2013-06-14 14 views
23

haben Sie einen Blick auf den folgenden CodeUnterschied zwischen „Kantenerkennung“ und „Bildkonturen“

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

using namespace std; 
using namespace cv; 

Mat src, grey; 
int thresh = 10; 

const char* windowName = "Contours"; 

void detectContours(int,void*); 

int main() 
{ 
    src = imread("C:/Users/Public/Pictures/Sample Pictures/Penguins.jpg"); 

    //Convert to grey scale 
    cvtColor(src,grey,CV_BGR2GRAY); 

    //Remove the noise 
    cv::GaussianBlur(grey,grey,Size(3,3),0); 

    //Create the window 
    namedWindow(windowName); 

    //Display the original image 
    namedWindow("Original"); 
    imshow("Original",src); 

    //Create the trackbar 
    cv::createTrackbar("Thresholding",windowName,&thresh,255,detectContours); 

    detectContours(0,0); 
    waitKey(0); 
    return 0; 

} 

void detectContours(int,void*) 
{ 
    Mat canny_output,drawing; 

    vector<vector<Point>> contours; 
    vector<Vec4i>heirachy; 

    //Detect edges using canny 
    cv::Canny(grey,canny_output,thresh,2*thresh); 

    namedWindow("Canny"); 
    imshow("Canny",canny_output); 

    //Find contours 
    cv::findContours(canny_output,contours,heirachy,CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE,Point(0,0)); 

    //Setup the output into black 
    drawing = Mat::zeros(canny_output.size(),CV_8UC3); 



    //Draw contours 
    for(int i=0;i<contours.size();i++) 
    { 
     cv::drawContours(drawing,contours,i,Scalar(255,255,255),1,8,heirachy,0,Point()); 
    } 

    imshow(windowName,drawing); 

} 

Theoretisch Contours Mittel Kurven zu erfassen. Edge detection bedeutet Erkennung von Kanten. In meinem obigen Code habe ich Kantenerkennung mit Canny und Kurvenerkennung durch findContours() durchgeführt. Im Folgenden sind die resultierenden Bilder

Canny Bild

enter image description here

Contours Bild

enter image description here

OK, also jetzt, wie man sehen kann, gibt es keinen Unterschied! Also, was ist der tatsächliche Unterschied zwischen diesen 2? In OpenCV-Tutorials wird nur der Code angegeben. Ich habe eine Erklärung dazu gefunden, was Contours ist, aber dieses Problem wird nicht angesprochen.

Bitte helfen!

+0

Ich schlage vor, Sie verwenden cv :: Weichzeichnen() vor cv :: Canny(). Dies kann den Großteil der Unordnung beseitigen, während die Hauptkanten beibehalten werden. – Bull

Antwort

38

Kanten werden als Punkte berechnet, die Extrema des Bildgradienten in Richtung des Gradienten sind. Wenn es hilft, können Sie sie als die Min- und Max-Punkte in einer 1D-Funktion vorstellen. Der Punkt ist, Rand Pixel sind eine lokale Vorstellung: Sie zeigen nur einen signifikanten Unterschied zwischen benachbarten Pixeln.

Konturen werden oft von Kanten erhalten, aber sie sind auf sein Objektkonturen richtet. Sie müssen also geschlossene Kurven sein. Sie können sich vorstellen, sie als Grenzen (einige Bildverarbeitungsalgorithmen & Librarires nennen sie so). Wenn sie von Kanten erhalten werden, müssen Sie die Kanten verbinden, um eine geschlossene Kontur zu erhalten.

+0

Vielen Dank für die Antwort. Ich schätze es wirklich :) –

+0

Gern geschehen :) – sansuiso

3

Konturen können tatsächlich ein bisschen mehr als "nur" Kanten erkennen. Der Algorithmus findet zwar Kanten von Bildern, stellt sie aber auch in eine Hierarchie. Dies bedeutet, dass Sie äußere Ränder von Objekten anfordern können, die in Ihren Bildern erkannt wurden. So etwas wäre (direkt) nicht möglich, wenn Sie nur nach Kanten suchen.

Wie in der Dokumentation zu lesen ist, werden die Konturen hauptsächlich für die Objekterkennung verwendet, wobei der "canny edge detector" eine "globalere" Operation ist. Ich wäre nicht überrascht, wenn der Konturalgorithmus irgendeine Art von Kantenerkennung verwendet.

+0

seit findContours() arbeitet auf binären Bildern, würde ich sehr überrascht sein, wenn es einen Canny Kantendetektor verwendet. – Bull

+0

Vielen Dank für die Antwort, ich gab Ihnen bereits eine +1 –

6

Der Hauptunterschied zwischen dem Finden von Kanten und countours besteht darin, dass bei der Suche nach Kanten die Ausgabe ein neues Bild ist. In diesem neuen Bild (Kantenbild) haben Sie hervorgehobene Kanten. Es gibt viele Algorithmen zum Erkennen von Kanten look at wiki see also.

Zum Beispiel gibt der Sobel-Operator glatte "neblige" Ergebnisse. In Ihrem speziellen Fall besteht der Haken darin, dass Sie Canny Kantendetektor verwenden. Dieser macht einige Schritte weiter als andere Detektoren. Es führt tatsächlich weitere Kantenverfeinerungsschritte aus. Die Ausgabe des Canny-Detektors ist somit ein binäres Bild mit 1 px breiten Linien anstelle von Kanten.

Auf der anderen Seite Contours Algorithmus verarbeitet arbiträre Binärbild. Also, wenn Sie weiß gefülltes Quadrat auf schwarzen Hintergrund setzen. Nach dem Ausführen von Contours Algorithmus, würden Sie weiße leere Quadrat, nur die Grenzen bekommen.

Ein weiterer zusätzlicher Bonus der Konturerkennung ist, es gibt tatsächlich eine Reihe von Punkten zurück! Das ist großartig, denn Sie können diese Punkte für eine bestimmte Verarbeitung weiter verwenden.

In Ihrem speziellen Fall ist es nur ein Zufall, dass beide Bilder übereinstimmen. Es herrscht keine Regel, und in Ihrem Fall ist es wegen der einzigartigen Eigenschaft des Canny-Algorithmus.

+2

Sobel ist nicht wirklich ein Kantendetektor, es gibt nur den Gradienten. Canny findet jedoch den maximalen Gradienten, d. H. Die Spitzen in dem Gradienten. Die OpenCV-Implementierung von Canny() verwendet tatsächlich Sobel() in seinem Frontend. – Bull

+0

Vielen Dank für die Antwort, ich gab Ihnen bereits eine +1 –

2

Der Begriff der Konturen wird als Werkzeug zur Bearbeitung von Kantendaten verwendet. Nicht alle Kanten sind gleich. In vielen Fällen, z.B. Objekte mit einer unimodalen Farbverteilung (d. h. eine Farbe), Kanten sind die tatsächlichen Konturen (Umriss, Form).

  1. Erkennen Sie nicht nur Kurven, sondern alles, was an der Kantenkarte angeschlossen ist. (Connected Component Analysis) [1]
  2. Nützlich für Objekte mit einer unimodalen Farbverteilung (eine Vordergrundmaske kann leicht mit einem einfachen Schwellenwert gefunden werden). Ihr Beispielbild ist nicht geeignet.

[1] Topologische Strukturanalyse von Digitalisierte Binary Bilder von Border Nach Satoshi Suzuki, 1985

+0

Vielen Dank für die Antwort, ich habe Ihnen bereits +1 gegeben –