web-dev-qa-db-fra.com

Différence entre "Détection des bords" et "Contours d'image"

Je travaille sur le code suivant:

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

}

Théoriquement, Contours signifie la détection de courbes. Edge detection Signifie détecter les arêtes. Dans mon code ci-dessus, j'ai fait la détection de bord en utilisant Canny et la détection de courbe par findContours(). Voici les images résultantes

Canny Image

enter image description here

Image des contours

enter image description here

Alors maintenant, comme vous pouvez le voir, il n'y a pas de différence! Alors, quelle est la différence réelle entre ces 2? Dans les tutoriels OpenCV, seul le code est donné. J'ai trouvé une explication sur ce qu'est "Contours" mais il ne règle pas ce problème.

27
PeakGen

Bords sont calculés comme des points qui sont des extrema du dégradé d'image dans la direction du dégradé. si cela peut aider, vous pouvez les considérer comme les points min et max dans une fonction 1D. Le fait est que les pixels Edge sont une notion locale: ils soulignent simplement une différence significative entre les pixels voisins.

Contours sont souvent obtenus à partir d'arêtes, mais ils visent à être contours d'objets. Ainsi, ils doivent être des courbes fermées. Vous pouvez les considérer comme limites (certains algorithmes et librarires de traitement d'image les appellent ainsi). Lorsqu'elles sont obtenues à partir de bords, vous devez connecter les bords afin d'obtenir un contour fermé.

47
sansuiso

La principale différence entre la recherche de bords et de contours est que si vous exécutez la recherche de bords, la sortie est une nouvelle image. Dans cette nouvelle image (image de bord), vous aurez mis en surbrillance les bords. Il existe de nombreux algorithmes pour détecter les bords voir wiki voir aussi .

Par exemple, l'opérateur Sobel donne des résultats "brumeux" fluides. Dans votre cas particulier, le hic est que vous utilisez le détecteur Canny Edge. Celui-ci fait quelques pas de plus que les autres détecteurs. Il exécute en fait d'autres étapes de raffinement Edge. La sortie du détecteur Canny est donc une image binaire, avec des lignes larges de 1 px à la place des bords.

D'un autre côté, l'algorithme Contours traite une image binaire arbitraire. Donc, si vous mettez un carré rempli de blanc sur fond noir. Après avoir exécuté l'algorithme Contours, vous obtiendrez un carré vide blanc, juste les bordures.

Un autre avantage supplémentaire de la détection des contours est qu'il renvoie en fait un ensemble de points! C'est très bien, car vous pouvez utiliser ces points plus loin pour certains traitements.

Dans votre cas particulier, ce n'est qu'une coïncidence que les deux images correspondent. Ce n'est pas une règle, et dans votre cas, c'est à cause de la propriété unique de l'algorithme Canny.

8
jnovacho

Les contours peuvent en fait faire un peu plus que "juste" détecter les bords. L'algorithme trouve en effet des bords d'images, mais les place également dans une hiérarchie. Cela signifie que vous pouvez demander des bordures extérieures d'objets détectés dans vos images. Une telle chose ne serait pas (directement) possible si vous ne vérifiez que les bords.

Comme on peut le lire dans la documentation, les contours sont principalement utilisés pour la reconnaissance d'objets, où le détecteur de bord cany est une opération plus "globale". Je ne serais pas surpris si l'algorithme de contour utilise une sorte de détection de bord astucieuse.

4
Nallath

La notion de contours est utilisée comme un outil pour travailler sur les données Edge. Tous les bords ne sont pas identiques. Mais dans de nombreux cas, par exemple objets avec une distribution de couleurs unimodale (c'est-à-dire une couleur), les bords sont les contours réels (contour, forme).

  1. Détectez non seulement les courbes, mais tout ce qui est connecté sur la carte Edge. (analyse des composants connectés) [1]
  2. Utile pour les objets avec une distribution de couleurs unimodale (un masque de premier plan est facilement trouvé avec un simple seuil). Votre exemple d'image n'est pas adapté.

[1] Analyse structurale topologique des images binaires numérisées par suivi de bord par Satoshi Suzuki, 1985.

2
LovaBill