2015-08-20 4 views
0

У меня есть очень простые изображения, из которых я хотел бы извлечь самый длинный контур.OpenCV findContour метод возвращает «удвоенный» контур

Пример изображения будет как этот:

example image for contour finding

Я использую точную same sample code со страницы учебника OpenCV в. С одной я установил разностный порог к ряду исправлений, а именно 100.

Основная линия это:

cv::findContours(cannyOutput, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0)); 

После того, как я вызвать выше функцию я итерацию по найденным контурам и проверить, какие один из них самый длинный, затем я сохраняю самый длинный. Дольше всего я имею в виду, у кого больше всего очков.

В некоторых случаях, как и в приведенном выше примере, самый длинный контур удваивается. Для того, чтобы сделать его более понятным, что я имею в виду под «удвоенный» вот визуализируется изображение найденного контура:

enter image description here

Так что я пытался понять это сам, почему это происходит, пытаясь понять OpenCV docs of findContour, но я до сих пор не могу понять настоящую причину.

То, что мне удалось достичь, если я перейду на CV_RETR_EXTERNAL из CV_RETR_TREE, я не получу удвоенный контур.

Так что мои вопросы будут:

  • Что является причиной удвоенного контура и почему CV_RETR_EXTERNAL решить эту проблему?
  • Получение контура, который имеет наибольшее количество точек, не обязательно означает, что он длиннее, правильно? Из-за флага CV_CHAIN_APPROX_SIMPLE. Может ли CV_CHAIN_APPROX_NONE решить эту проблему?

ответ

2

Вопрос: В чем причина двойного контура и почему CV_RETR_EXTERNAL решает проблему?

A: OpenCV findCountours стандартный режим: CV_RETR_LIST, который выводит для линии, как в вашем случае, внутренний и внешний контур. CV_RETR_EXTERNAL, как описано в документах, выводит только «экстремальные внешние контуры». Обратите внимание, что внешний контур не означает самого длинного. Я бы рекомендовал вам пройти через все контуры, заданные режимом CV_RETR_LIST, и выполнить расчет.

Вопрос: Получение контура, который имеет наибольшее количество точек, не обязательно означает, что он длиннее, правильно? Из-за флага CV_CHAIN_APPROX_SIMPLE. Может ли CV_CHAIN_APPROX_NONE решить эту проблему?

A: Первый вопрос верен, если ваш метод findCountours отличается от CV_CHAIN_APPROX_NONE. Также верно, что CV_CHAIN_APPROX_NONE решит эту проблему, поскольку она «будет хранить абсолютно все точки контура», но вы также можете суммировать все расстояния между точками, если вы предпочитаете использовать какой-либо другой метод.

+0

Привет, Берриэль, благодарю вас за ответ.Просто, чтобы сделать некоторые вещи ясными, у меня есть еще один вопрос. Если на самом деле то, что я хотел бы сделать, это найти самые длинные внешние контуры, тогда я должен установить флаг CV_RETR_EXTERNAL, и оттуда я сам могу вычислить длину контуров результатов, или я мог бы использовать CV_CHAIN_APPROX_NONE и сравнить количество точек, чтобы получить самый длинный контур из результатов. Я вас правильно понял? – Silex

+1

На самом деле, поскольку 'CV_RETR_EXTERNAL' возвращает только« экстремальные внешние контуры », как описано в документах, вы должны быть уверены, что в вашей проблеме любые внутренние контуры должны быть короче. Самый безопасный/более общий способ - получить все контуры (например, используя «CV_RETR_LIST» в качестве режима) и все точки контуров (используя метод «CV_CHAIN_APPROX_NONE» в качестве метода), затем вы просматриваете список возвращаемых контуров и подсчитываете их точки (или вычисляете общее расстояние между точками). ОК? – Berriel

Смежные вопросы