Как проверить, является ли один контур вложенным/встроенным в opencv

У меня есть два контура, и я хочу проверить связь между ними (если один из них вложен). Обычно я использую 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 

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


person pzo    schedule 14.12.2011    source источник


Ответы (2)


Чтобы узнать, является ли точка из контур находится внутри другого.

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

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

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

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

person Sam    schedule 14.12.2011

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

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

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

  . 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

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

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

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

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

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

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

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

person James    schedule 14.12.2011