rellenar personas movimiento formas encontrar detector detectar deteccion contornos contorno con opencv image-processing

movimiento - opencv deteccion de personas



OpenCV convierte bordes Canny a contornos (3)

Tengo una aplicación OpenCV alimentada por una secuencia de webcam de un interior de oficina (muchos detalles) donde tengo que encontrar un marcador artificial. El marcador es un cuadrado negro sobre fondo blanco. Uso Canny para encontrar bordes y cvFindContours para contornear, luego approxPolyDP y co. para filtrar y encontrar candidatos, luego use un histograma local para filtrar más, bla bla bla ...

Esto funciona más o menos, pero no exactamente como quiero. FindContours siempre devuelve un bucle cerrado, incluso si Canny crea una línea no cerrada. Obten un contorno caminando en ambos lados de la línea formando un bucle. Para bordes cerrados en la imagen de Canny (mi marcador), obtengo 2 contornos, uno en el interior y otro en el exterior. Tengo problemas con esta operación:

  • Obtengo 2 contornos para cada marcador (no tan serio)

  • el filtro más trivial no es utilizable (rechaza contornos no cerrados)

Entonces mi pregunta: ¿es posible obtener contornos no cerrados para los bordes Canny no cerrados? ¿O cuál es la forma estándar de resolver los 2 problemas anteriores?

Canny es una herramienta muy buena, pero necesito una forma de convertir la imagen 2D b / w, en algo fácilmente procesable. Algo así como componentes conectados que enumeran todos los píxeles en orden de avance del componente. Así que puedo filtrar los bucles y alimentarlo en approxPolyDP.

Actualización: omití algunos detalles importantes: el marcador puede tener cualquier orientación (no está orientado hacia la cámara, no hay ángulos rectos), de hecho, lo que estoy haciendo es una estimación de orientación 3D, basada en la proyección 2D del marcador.


Encontré una solución limpia y fácil para los 2 problemas en la pregunta. El truco es habilitar la generación de jerarquía de 2 niveles (en findCountours) y buscar contornos que tengan un padre. Esto devolverá el contorno interno de los bordes Canny cerrados y nada más. Los bordes no cerrados se descartan automáticamente, y cada marcador tendrá un contorno único.

vector<vector<Point> > contours; vector<Vec4i> hierarchy; findContours(CannyImage, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, Point(0,0) ); for (unsigned int i=0; i<contours.size(); i++) if (hierarchy[i][3] >= 0) //has parent, inner (hole) contour of a closed edge (looks good) drawContours(contourImage, contours, i, Scalar(255, 0, 0), 1, 8);

También funciona a la inversa, es decir: busque contornos que tengan un elemento secundario (jerarquía [i] [2]> = 0), pero en mi caso la comprobación principal proporciona mejores resultados.


Así es como lo haría 1. Canny para detección de bordes 2. Use houghtransform para detectar los bordes. 3. Detecta los dos bordes que forman un ángulo de 90.


Tuve el mismo problema con los contornos duplicados e incluso dilatar y erosionar no pudo resolverlo:

Mat src=imread("E://test.bmp"),gry,bin,nor,dil,erd; GaussianBlur( src, nor, Size(5,5),0 ); cvtColor(nor,gry,CV_BGR2GRAY); Canny(gry,bin,100,150,5,true); dilate(bin,dil,Mat()); erode(dil,erd,Mat()); Mat tmp=bin.clone(); vector<vector<Point>> conts; vector<Vec4i> hier; findContours(tmp,conts,hier,CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE);

Esta imagen (test.bmp) contiene 3 contornos pero findContours devolvió 6! Utilicé el umbral y el problema resuelto:

Mat src=imread("E://test.bmp"),gry,bin,nor,dil,erd; GaussianBlur( src, nor, Size(5,5),0 ); cvtColor(nor,gry,CV_BGR2GRAY); threshold(gry,bin,0,255,THRESH_BINARY+THRESH_OTSU); vector<vector<Point>> conts; vector<Vec4i> hier; findContours(bin,conts,hier,CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE);

Ahora devuelve 4 contornos, el primero es el límite de la imagen (contorno con índice 0) y se puede omitir fácilmente.