objetos deteccion contornos con c++ c visual-c++ opencv image-processing

c++ - deteccion - Contornos opencv: cómo eliminar pequeños contornos en una imagen binaria



deteccion de contornos opencv python (6)

¿Estás seguro de que el filtrado por área de contorno pequeño no funcionó? Siempre me funcionó. ¿Podemos ver tu código?

Además, como se mencionó en sue-ling, es una buena idea usar erosionar y dilatar para preservar aproximadamente el área. Para eliminar las pequeñas partículas ruidosas, primero use erosionar y, para rellenar los agujeros, primero use dilatar.

Y, aparte, es posible que desee comprobar las nuevas versiones de C ++ de las funciones cv * si no las conocía ya ( documentación para findContours ). Son mucho más fáciles de usar, en mi opinión.

Actualmente estoy trabajando en un proyecto de procesamiento de imágenes. Estoy usando Opencv2.3.1 con VC ++. He escrito el código de tal manera que la imagen de entrada se filtra solo al color azul y se convierte en una imagen binaria. La imagen binaria tiene algunos objetos pequeños que no quiero. Quería eliminar esos pequeños objetos, así que utilicé el método cvFindContours() de cvFindContours() para detectar contornos en una imagen binaria. pero el problema es que no puedo eliminar los objetos pequeños en la salida de la imagen. cvContourArea() función cvContourArea() , pero no funcionó correctamente ..., la función erosionar tampoco funcionó correctamente.

Entonces, por favor, que alguien me ayude con este problema ...

La imagen binaria que obtuve :

La imagen de resultado / resultado que quiero obtener:


A juzgar por las imágenes de antes y después, debe determinar el área de todas las áreas blancas o blobs, luego aplicar un valor de área de umbral. Esto eliminaría todas las áreas menores que el valor y dejaría solo la gran región blanca que se ve en la segunda imagen. Después de usar la función cvFindContours, intente usar 0 momentos de orden. Esto devolvería el área de los blobs en la imagen. Este enlace podría ser útil para implementar lo que acabo de describir. http://www.aishack.in/2010/07/tracking-colored-objects-in-opencv/


Aquí está mi solución para eliminar pequeños contornos. La idea básica es verificar el largo / área para cada contorno, luego eliminar el más pequeño del contenedor vectorial.

normalmente obtendrás contornos como este

Mat canny_output; //example from OpenCV Tutorial vector<vector<Point> > contours; vector<Vec4i> hierarchy; Canny(src_img, canny_output, thresh, thresh*2, 3);//with or without, explained later. findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0,0));

Con el preprocesamiento de Canny (), obtendrá segmentos de contorno, sin embargo, cada segmento se almacena con píxeles de límite como un anillo cerrado. En este caso, puede verificar la longitud y eliminar la pequeña como

for (vector<vector<Point> >::iterator it = contours.begin(); it!=contours.end(); ) { if (it->size()<contour_length_threshold) it=contours.erase(it); else ++it; }

Sin el preprocesamiento de Canny (), obtendrá contornos de objetos. Similitud, también puede usar el área para definir un umbral para eliminar objetos pequeños, como se muestra en el tutorial de OpenCV

vector<Point> contour = contours[i]; double area0 = contourArea(contour);

este contourArea () es el número de píxeles distintos de cero


Creo que puedes usar operadores morfológicos como erosionar y dilatar (lee más aquí )

Debe realizar la erosión con un tamaño de núcleo cerca del radio del círculo de la derecha (el que desea eliminar). seguido de dilatación usando el mismo kernel para llenar los huecos creados por el paso de erosión.

La erosión FYI seguida de la dilatación usando el mismo núcleo se llama apertura.

el código será algo como esto

int erosion_size = 30; // adjust with you application Mat erode_element = getStructuringElement( MORPH_ELLIPSE, Size( 2*erosion_size + 1, 2*erosion_size+1 ), Point( erosion_size, erosion_size ) ); erode( binary_img, binary_img, erode_element ); dilate( binary_img, binary_img, erode_element );


De acuerdo, creo que su problema podría resolverse con la demo del cuadro delimitador introducida recientemente por OpenCV.

Como probablemente haya notado, el objeto que le interesa debe estar dentro del dibujo rectangular más grande de la imagen. Afortunadamente, este código no es muy complejo y estoy seguro de que puedes resolverlo investigando y experimentando con él.


No es una forma rápida, pero puede ser útil en algunos casos. Hay una nueva función en OpencCV 3.0 - connectedComponentsWithStats. Con él podemos obtener el área de componentes conectados y eliminar innecesarios. Así que podemos eliminar fácilmente el círculo con agujeros, con el mismo cuadro delimitador que el círculo sólido.