web-dev-qa-db-fra.com

Trouver des contours dans OpenCV?

Lorsque vous récupérez les contours d'une image, vous devez obtenir 2 contours par tache: un intérieur et un extérieur. Considérez le cercle ci-dessous - puisque le cercle est une ligne avec une largeur de pixel supérieure à un, vous devriez pouvoir trouver deux contours dans l'image: un à partir de la partie interne du cercle et un à partir de la partie externe.

En utilisant OpenCV, je veux récupérer les contours INNER. Cependant, lorsque j'utilise findContours (), il semble que je ne reçois que les contours extérieurs. Comment pourrais-je récupérer les contours intérieurs d'un blob à l'aide d'OpenCV?

J'utilise l'API C++ et non le C, donc je ne suggère que des fonctions qui utilisent l'API C++. (c'est-à-dire findContours () plutôt que cvFindContours ())

Merci.

enter image description here

14
fdh

J'ai couru ce code sur votre image et il a retourné un contour intérieur et extérieur.

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

Voici les contours trouvés:

findContour result image

25
SSteve

Je pense que ce que Farhad demande, c'est de rogner le contour de l'image originale.

Pour ce faire, vous devez trouver le contour comme expliqué ci-dessus, puis utiliser un masque pour obtenir l'intérieur de l'original, puis rogner le résultat en une image de la même taille que le contour.

3
Kacem Boufelliga

La fonction findcontours stocke tous les contours dans différents vecteurs. Dans le code, tous les contours sont dessinés; il vous suffit de dessiner le contour correspondant à celui intérieur, idx est la variable qui détermine le contour dessiné.

0
Dangelo Guanipa