2011-12-09 28 views
14

Quando recuperi i contorni da un'immagine, dovresti ottenere 2 contorni per blob: uno interno e uno esterno. Considera il cerchio sottostante: poiché il cerchio è una linea con una larghezza di pixel maggiore di uno, dovresti riuscire a trovare due contorni nell'immagine: uno dalla parte interna del cerchio e uno dalla parte esterna.Trovare contorni in OpenCV?

Utilizzando OpenCV, voglio recuperare i contorni interni. Tuttavia, quando uso findContours(), mi sembra di ottenere solo i contorni esterni. Come posso recuperare i contorni interni di un blob usando OpenCV?

Sto usando l'API C++, C non quindi solo suggerire le funzioni che utilizzano l'API C++. (cioè findContours() piuttosto che cvFindContours())

Grazie.

enter image description here

+0

Puoi mostrarci un codice? – SSteve

+0

Beh, in realtà non ho alcun codice univoco. Ho solo un tappetino che ho recuperato dalla fotocamera. Eseguo su di esso il rilevatore di bordo cangiante, quindi trovo i contorni usando findContours(). Tutti i contorni trovati sono memorizzati in un vettore >. Questo è praticamente tutto ciò che ho, quindi non ho molto senso pubblicare il codice reale - è solo il processo tradizionale di trovare contorni. – fdh

+0

Ho lavorato un po 'con i contorni, anche se il mio interesse erano solo i contorni esterni. Ho provato a colorare un contorno, con 'drawContours()'. Che rispecchia una sorta di gerarchia. L'esempio su 'drawContours()' che ho usato, non ha colorato i contorni interni. Quello che sto cercando di ottenere qui, è che probabilmente devi usare l'array hierachy da "findContours()" per ordinarli. (La ragione per cui non ho una risposta è che la mia conoscenza di questa gerarchia è limitata, non vorrei confondervi, ho fatto un po 'di prove su questi e ho potuto spiegare la mia comprensione fino ad ora, se richiesta.) – Sonaten

risposta

19

ho eseguito questo codice sulla vostra immagine e restituito un contorno interno ed esterno.

#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; 
} 

Qui ci sono i contorni che ha trovato:

findContour result image

+0

Grazie. Ti capita di sapere come accedere specificamente solo ai contorni interni? Come nei confini del buco? – fdh

+2

Se si imposta la modalità su 'CV_RETR_TREE' invece di' CV_RETR_LIST' si ottiene un albero gerarchico di contorni in modo che il contorno interno si trovi sotto il contorno esterno. Non fa una distinzione tra contorni interni e contorni esterni, quindi se ci fosse un cerchio all'interno del cerchio, entrambi i contorni sarebbero al di sotto del contorno interno del cerchio esterno. Il [tutorial OpenCV findContour] (http://opencv.itseez.com/doc/tutorials/imgproc/shapedescriptors/find_contours/find_contours.html#find-contours) utilizza 'CV_RETR_TREE'. – SSteve

3

Credo che quello che Farhad chiede è quello di ritagliare il contorno dall'immagine originale.

Per fare questo è necessario trovare il contorno, come spiegato sopra, quindi utilizzare una maschera per ottenere l'interno dall'originale, e poi ritagliare il risultato in un'immagine con le stesse dimensioni del contorno.

0

La funzione findcontours memorizza tutti i contorni in diversi vettori, nel codice dato tutti i contorni sono disegnati, basta disegnare il contorno corrispondente a quello interno, idx è la variabile che indica quale contorno viene disegnato.

Problemi correlati