Я пытаюсь отсканировать изображение с постоянным размером и найти в нем рисованные прямоугольники. Прямоугольники могут иметь любой размер, но только красный цвет.
Это не, где проблема начинается.
Я буду использовать уже написанную функцию, и буду использовать ее в качестве псевдокодов позже в моей логике кода.
Rectangle Locate(Rectangle scanArea);
//сканирует прямоугольник в заданной области сканирования.
если прямой прямоугольник не найден, возвращает null.
Моя логика была такой:
Найдите первый начальный красный прямоугольник, используя функцию Locate()
с полным размером изображения в качестве аргумента.
Теперь разделите остальные области и продолжайте сканирование рекурсивно.
Главное в этой логике алгоритма состоит в том, что вы никогда не проверяете уже отмеченную область, и вам не нужно использовать какое-либо условие, потому что всегда параметр scanArea
- это новая область, которую вы ранее не сканировали (и что благодаря техника разделения).
Процесс деления выполняется следующим образом: правая область текущего найденного прямоугольника, нижняя область и левая область.
Здесь изображение, которое иллюстрирует этот процесс. (Белые пунктирные прямоугольники и желтые стрелки не являются частью изображения, я добавил их только для иллюстрации.) Как вы видели, как только появился красный прямоугольник, я продолжаю сканирование справа от него, снизу и слева. Рекурсивный.
Итак, вот код для этого метода:
List<Rectangle> difList=new List<Rectangle>();
private void LocateDifferences(Rectangle scanArea)
{
Rectangle foundRect = Locate(scanArea);
if (foundRect == null)
return; // stop the recursion.
Rectangle rightArea = new Rectangle(foundRect.X + foundRect.Width, foundRect.Y, (scanArea.X + scanArea.Width) - (foundRect.X + foundRect.Width), (scanArea.Y + scanArea.Height) - (foundRect.Y + foundRect.Height)); // define right area.
Rectangle bottomArea = new Rectangle(foundRect.X, foundRect.Y + foundRect.Height, foundRect.Width, (scanArea.Y + scanArea.Height) - (foundRect.Y + foundRect.Height)); // define bottom area.
Rectangle leftArea = new Rectangle(scanArea.X, foundRect.Y, (foundRect.X - scanArea.X), (scanArea.Y + scanArea.Height) - (foundRect.Y + foundRect.Height)); // define left area.
difList.Add(rectFound);
LocateDifferences(rightArea);
LocateDifferences(bottomArea);
LocateDifferences(leftArea);
}
Пока все работает хорошо, он находит каждый красный прямоугольник. Но иногда прямоугольники сохраняются как несколько прямоугольников. По какой-то причине это очевидно для меня: с перекрывающимися прямоугольниками.
Теперь в этом случае программа найдет первую красную область, как и планировалось, но тогда, поскольку правильная область начинается только в середине полной второй области, она не сканирует с начала второго красного прямоугольника!
Аналогичным образом я могу разделить области так, чтобы нижняя область простиралась от начала scanArea
до конца, что было бы так:
Но теперь у нас возникнет проблема при сканировании перекрывающихся прямоугольников справа и слева от прямоугольника foundRect
, например, в этом случае:
Мне нужно получить каждый прямоугольник только в одном куске. Я хотел бы получить какую-либо помощь или предложение в сочетании с моей логикой кода - потому что он отлично работает, но мне нужен только один или два дополнительных условия в методе рекурсии. Я не уверен, что делать, и я бы очень признателен за любую помощь.
Если что-то недостаточно ясно, просто скажите, и я объясню это как можно лучше! Спасибо!
Конечно, это не настоящая проблема, с которой мне приходится сталкиваться, это просто небольшая демонстрация, которая может помочь мне решить реальную проблему, над которой я работаю (это интернет-проект в режиме реального времени).