2011-12-18 19 views
9

Tengo 2 contornos A y B y quiero comprobar si se cruzan. Tanto A como B son vectores de tipo cv :: Point y son de tamaños diferentesOpenCV detectar contornos intersección

Para comprobar intersección, yo estaba tratando de hacer un bitwise_and. Esto arroja una excepción porque las entradas son de diferente tamaño. Cómo puedo solucionar esto ?

Editar:

La imagen adjunta debe dar una mejor idea sobre el tema. El coche es seguido por un contorno azul y el obstáculo por un contorno rosado. Necesito verificar la intersección. enter image description here

Respuesta

11

Un simple pero quizás no sea el (??) forma más eficiente sería utilizar drawContours para crear dos imágenes: una con el contorno del coche y una con el contorno del obstáculo.

Luego, and juntos, y cualquier punto que siga siendo positivo serán los puntos de intersección.

Algunos pseudocódigo (yo uso la interfaz de Python por lo que no sería obtener el derecho de sintaxis de C++, pero debe ser lo suficientemente simple para que usted pueda convertir):

import numpy as np # just for matrix manipulation, C/C++ use cv::Mat 
# find contours. 
contours,h = findContours(img, mode=RETR_LIST, method=CHAIN_APPROX_SIMPLE) 
# Suppose this has the contours of just the car and the obstacle. 

# create an image filled with zeros, single-channel, same size as img. 
blank = np.zeros(img.shape[0:2]) 

# copy each of the contours (assuming there's just two) to its own image. 
# Just fill with a '1'. 
img1 = drawContours(blank.copy(), contours, 0, 1) 
img2 = drawContours(blank.copy(), contours, 1, 1) 

# now AND the two together 
intersection = np.logical_and(img1, img2) 

# OR we could just add img1 to img2 and pick all points that sum to 2 (1+1=2): 
intersection2 = (img1+img2)==2 

Si miro intersection que recibirá imagen que es 1 donde los contornos se cruzan y 0 en cualquier otro lado.

Si lo prefiere puede rellenar el contorno de toda (no sólo el contorno, pero rellenar el interior también) con drawContours(blank.copy(), contours, 0, 1, thickness=-1) y luego la imagen intersection contendrá el área de intersección entre las curvas de nivel.

+0

¡Gracias! Parece que funciona bastante bien. – Madman

0

Si primero ordena sus vectores, usando prácticamente cualquier criterio de clasificación consistente que pueda encontrar, entonces puede usar std::set_intersection directamente en los vectores. Esto puede ser más rápido que la respuesta aceptada en caso de que los contornos sean cortos en comparación con el tamaño de la imagen.

0

He encontrado la biblioteca Clipper bastante útil para este tipo de propósitos. (Es fácil transformar vectores de cv::Point en objetos Clipper Path).

Cuestiones relacionadas