Как проверить, вложен ли один контур / встроен в opencv - PullRequest
9 голосов
/ 14 декабря 2011

У меня есть два контура, и я хочу проверить соотношение между ними (если один из них вложен).Обычно я бы использовал функцию findContours с режимом поиска CV_RETR_TREE.Однако я получил контуры из другого источника (используя метод MSER ).На самом деле у меня есть не только контуры, но и маска региона, если это помогает.Например, допустим, я хочу сегментировать букву «О», тогда у меня будут следующие маски или контуры:

1)

0 0 0 0 0 0
0 1 1 1 1 0
0 1 0 0 1 0
0 1 0 0 1 0
0 1 1 1 1 0
0 0 0 0 0 0 

2)

0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 1 0 0
0 0 1 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0 

Как я могу легко проверить, что второй находится внутри первого контура?Я думал о проверке связи между ограничивающими прямоугольниками, но это не охватывает все возможные случаи.

Ответы [ 2 ]

7 голосов
/ 14 декабря 2011

Используйте cv::pointPolygonTest(InputArray contour, Point2f pt, bool measureDist), чтобы узнать, находится ли точка из контура внутри другой.

Необходимо проверить границы (первая выбранная точка является общей для обоих полигонов и т. Д.)

if(pointPolygonTest(contour, pointFromOtherContour, false) > 0)
{
    // it is inside
}

Функция определяет, находится ли точка внутри контура, снаружи илилежит на ребре (или совпадает с вершиной).Возвращает положительное (внутри), отрицательное (снаружи) или нулевое (на ребре) значение соответственно.

Когда measureDist=false, возвращаемое значение равно +1, -1 и 0 соответственно.В противном случае возвращаемое значение представляет собой расстояние со знаком между точкой и ближайшим краем контура.

1 голос
/ 14 декабря 2011

Если вы знаете, что контуры замкнуты (в четырехзначном смысле), то вы, вероятно, можете использовать тест луча в бесконечность, который чаще используется для проверки того, находятся ли точки внутри замкнутых многоугольников.(Также при условии, что контуры не пересекаются, что, по-видимому, не может.)

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

«пересечение» внешнего контура на самом деле немного сложнее, например:

  . 1 1 1 1 1 1 1
  . 1 . . X X X 1
  . 1 . . X . X 1
<-.-1-1-.-X X X 1 : here a naiive implementation counts two crossings
  . . 1 1 1 1 1 1

Таким образом, чтобы проверить, пересекает ли луч контур в точке, вам действительно необходимо рассмотреть 3х3 соседние точки.Я думаю, что в итоге вы получите набор случаев, которые выглядят примерно так:

  . . .
<-1-1 1 // not crossing
  . . .

  1 . 1
<-1-1 1 // not crossing
  . . .

  . . 1
<-1-1 1 // crossing
  . . .

  1 . .
<-1-1 1 // crossing
  . . .

Я не уверен на 100%, что возможно построить согласованный тест для пересечений на основе 4-соединенного контурав окрестностях 3х3, но, вероятно, так оно и есть.

Все это, конечно, зависит от того, что внешний контур замкнут.

...