2011-12-09 15 views
14

Cuando recupera contornos de una imagen, debe obtener 2 contornos por blob, uno interno y uno externo. Considere el siguiente círculo: dado que el círculo es una línea con un ancho de píxel mayor que uno, debería poder encontrar dos contornos en la imagen, uno de la parte interna del círculo y el otro de la parte exterior.¿Cómo encontrar contornos en OpenCV?

Al utilizar OpenCV, quiero recuperar los contornos INNER. Sin embargo, cuando uso findContours(), parece que solo obtengo los contornos externos. ¿Cómo recuperaría los contornos internos de una burbuja usando OpenCV?

Estoy utilizando la API C++, no C, por lo tanto, solo sugiero funciones que usan la API C++. (es decir, findContours() en lugar de cvFindContours())

Gracias.

enter image description here

+0

¿Puede mostrarnos algún código? – SSteve

+0

Bueno, realmente no tengo ningún código único. Solo tengo una Mat que recupero de la cámara. Ejecuto el detector de borde astuto y luego encuentro contornos usando findContours(). Todos los contornos encontrados se almacenan en un vector >. Eso es básicamente todo lo que tengo, así que no tiene mucho sentido que publique código real; es simplemente el proceso tradicional de encontrar contornos. – fdh

+0

He trabajado un poco con los contornos, aunque mi interés solo fueron los contornos externos. Intenté colorear un contorno con 'drawContours()'. Lo cual requiere una especie de jerarquía. La muestra en 'drawContours()' que utilicé, no coloreó los contornos internos. Lo que trato de hacer aquí, es que probablemente necesites usar la matriz de jerarquía de 'findContours()' para ordenarlos. (La razón por la que no publico una respuesta es que mi conocimiento de esta jerarquía es limitado, y no quisiera confundirlo sobre el asunto. He hecho un poco de prueba sobre esto y podría explicar mi comprensión hasta el momento, si lo solicita.) – Sonaten

Respuesta

19

me encontré con este código en su imagen y volvió un contorno interior y exterior.

#include <iostream> 
#include "opencv2/core/core.hpp" 
#include "opencv2/imgproc/imgproc.hpp" 
#include "opencv2/highgui/highgui.hpp" 

int main(int argc, const char * argv[]) { 

    cv::Mat image= cv::imread("../../so8449378.jpg"); 
    if (!image.data) { 
     std::cout << "Image file not found\n"; 
     return 1; 
    } 

    //Prepare the image for findContours 
    cv::cvtColor(image, image, CV_BGR2GRAY); 
    cv::threshold(image, image, 128, 255, CV_THRESH_BINARY); 

    //Find the contours. Use the contourOutput Mat so the original image doesn't get overwritten 
    std::vector<std::vector<cv::Point> > contours; 
    cv::Mat contourOutput = image.clone(); 
    cv::findContours(contourOutput, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE); 

    //Draw the contours 
    cv::Mat contourImage(image.size(), CV_8UC3, cv::Scalar(0,0,0)); 
    cv::Scalar colors[3]; 
    colors[0] = cv::Scalar(255, 0, 0); 
    colors[1] = cv::Scalar(0, 255, 0); 
    colors[2] = cv::Scalar(0, 0, 255); 
    for (size_t idx = 0; idx < contours.size(); idx++) { 
     cv::drawContours(contourImage, contours, idx, colors[idx % 3]); 
    } 

    cv::imshow("Input Image", image); 
    cvMoveWindow("Input Image", 0, 0); 
    cv::imshow("Contours", contourImage); 
    cvMoveWindow("Contours", 200, 0); 
    cv::waitKey(0); 

    return 0; 
} 

Éstos son los contornos que se ha encontrado:

findContour result image

+0

Gracias. ¿Sabría cómo acceder específicamente a los contornos internos solamente? Como en los límites del hoyo? – fdh

+2

Si configura el modo 'CV_RETR_TREE' en lugar de' CV_RETR_LIST' obtendrá un árbol jerárquico de contornos para que el contorno interno quede debajo del contorno exterior. No hace una distinción entre los contornos internos y externos por lo que si hubiera un círculo dentro del círculo, ambos contornos estarían debajo del contorno interno del círculo exterior. El [OpenCV findContour tutorial] (http://opencv.itseez.com/doc/tutorials/imgproc/shapedescriptors/find_contours/find_contours.html#find-contours) utiliza 'CV_RETR_TREE'. – SSteve

3

Creo que lo que está pidiendo es Farhad para recortar el contorno de la imagen original.

Para hacer eso, necesitará encontrar el contorno como se explicó anteriormente, luego use una máscara para obtener el interior del original, y luego recorte el resultado en una imagen del mismo tamaño que el contorno.

0

La función findcontours almacena todos los contornos en diferentes vectores, en el código dado se dibujan todos los contornos, solo tiene que dibujar el contorno correspondiente al interno, idx es la variable que indica qué contorno se dibuja.

Cuestiones relacionadas