Я пытаюсь выполнить обнаружение темного (почти черного) объекта в видеоисточнике на основе его характеристик формы (например, площадь, длина контура и т. Д.), Но у меня есть проблема с обнаружением контуров в двоичной маске.
Иногда, даже если объект не меняет форму, а контур получается из простой маски, содержащей только один компактный большой двоичный объект, контуры не закрываются (я могу сказать это, потому что я отображаю его с опцией CV_FILLED, а для многих кадров контур заполнено), и из-за этого вычисляемая область фактически не заслуживает доверия (значение уменьшается до нескольких пикселей).
Я также заметил, что когда контур объекта не замкнут, длина примерно в 2 раза больше, чем предполагалось (что имеет смысл).
Почему контуры простых пятен иногда открываются, а иногда закрываются, и как я могу заставить их всегда быть замкнутыми? Я уже пробовал выпуклый корпус, а также копировал первую точку контура до конца, но это не сработало.
Шаги моего подхода следующие:
- Используйте детектор краев Canny, чтобы получить только края
Это классическая ошибка. После и во время шага 2 я предполагаю, что у вас есть двоичное изображение, т.е. черное изображение с кучей заполненный белые пятна, которые обозначают области, которые вы хотите найти. Это именно то, что cv::findContours
работает на.
Когда вы делаете обнаружение краев, вы фактически превращаете эти хорошо заполненные области в кучу очень тонких длинных и возможно, но не обязательно замкнутые линии, ограничивающие ваши прежние области, что все портит. таким образом cv::findContours
вернет именно это, куча очень тонких контуров. Эти контуры являются на самом деле тоже замкнутый, потому что они представляют собой замкнутый многоугольник с последней точкой, соединяющейся обратно с первой, просто этот многоугольник обвивает эти тонкие линии, полученные в результате обнаружения краев, что объясняет, почему их площадь очень мала, а периметр примерно вдвое больше, чем вы ожидаете. Он в основном обрабатывает те линии, которые возникают в результате обнаружения краев не как фактические контуры, а не очень тонкие районы Вы хотите найти границы контуров, что, скорее всего, не то, что вы намерены.
Если эти границы закрыты а также вы получаете только внешние контуры (например, с помощью CV_RETR_EXTERNAL
), вы может быть получить примерно те же правильные контуры области, которые вы ожидаете, но это просто не гарантировано и легко испортить.
Таким образом, простое решение состоит в том, чтобы просто отбросьте шаг Canny Edge Detection и работайте над правильным двоичным изображением напрямую, как cv::findContours
является обычно Предназначен для.