2017-01-23 10 views
0

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

def areaAndPerimeter(point): 
    ...do some stuff... 
    return area, perimeter 

Я знаю, что могу использовать cv2.findContours(), чтобы найти периметр и область каждого подключенного компонента, но я не знаю, как соединить эту информацию с входной точкой. Какой периметр и площадь соответствуют подключенному компоненту point

+1

Я думаю, что вы делаете 'connectedComponentsWithStats()', и он накладывает все точки в каждом блобе с тем же цветом. Таким образом, вы найдете цвет (например, метку), соответствующий вашей точке, чтобы найти, к какому блобу он принадлежит. Возможно, я безнадежно ошибаюсь! Я полагаю, он называется 'bwlabel()' в Matlab. –

+0

Да, я начал работать над решением, в котором я использую просто старые '' connectedComponents() '', а затем извлекаю каждый компонент 1 на 1 и запускаю '' findContours() '' отдельно для каждого, но кажется, что такой отход когда я мог запускать '' findContours() '' один раз на всем изображении и пропускать связанные компоненты вместе. – mv3

ответ

0

Для этой функции я бы просто увеличил область, начиная с точки. Ниже приведен псевдокод:

- Define a point queue Q 
- Define a foreground point vector F 
- Define a boundary point vector B 
- Put starting point in Q 
- While Q is not empty 
     - p = Q.top 
     - if p is foreground 
      - F.push(p) 
      - Q.push(neighbors of p) 
     - else 
      - B.push(p) 
- Return size(F), size(B) 

В конце, F содержит передний план пикселей и B содержит граничные пиксели (черный прямо снаружи белых). Таким образом, size(F) дает площадь и size(B) дает периметр.

+0

Являются ли эти хорошие меры по периметру и площади? Я полагаю, что они могут быть взяты в качестве определений, но когда я пытаюсь это сделать, они не соответствуют результатам opencv-функций '' cv2.arcLength() '' и '' cv2.contourArea() ''. Размер контура совпадает с вашим определением периметра, но функция '' cv2.arclength() '' не равна этому и дает результаты ближе к тому, что я ожидал бы. – mv3

+0

Поскольку существуют разные меры для расстояния (т. Е. Расстояние Евклида до Манхэттена), площадь и длина дуги также зависят от вашего приближения, поскольку область изображения является дискретной. Вышеприведенный код дает «сколько пикселей на переднем плане?» и «сколько пикселей на границе?». Если вы хотите использовать аппроксимацию OpenCV, используйте все точки в 'B' и запустите' cv2.contourArea (B) 'и' cv2.arcLength (B) '. – ilke444

+0

Я вижу, я собираюсь попробовать это время против того, что я делаю сейчас, используя '' cv2.connectedComponents() '', чтобы найти подключенные компоненты, извлекая компонент моей точки, а затем используя '' cv2.findContours() '', а затем '' cv2.contourArea() '' и '' cv2.arcLenth() ''. – mv3