web-dev-qa-db-fra.com

OpenCV - recherche le cadre de sélection du plus gros blob dans une image binaire

Quel est le moyen le plus efficace de trouver le cadre englobant le plus gros blob d'une image binaire à l'aide d'OpenCV? Malheureusement, OpenCV n’a pas de fonctionnalité spécifique pour la détection de blob. Devrais-je simplement utiliser findContours() et rechercher le plus grand dans la liste? 

11
1''

Si vous souhaitez utiliser les bibliothèques OpenCV, consultez OpenCV SimpleBlobDetector. Voici un autre dépassement de pile montrant un petit tutoriel: Comment utiliser OpenCV SimpleBlobDetector

Cela ne vous donne cependant que des points clés. Vous pouvez utiliser ceci comme recherche initiale pour trouver le blob que vous souhaitez, puis éventuellement utiliser l'algorithme findContours autour des blobs les plus probables.

De plus, plus vous en savez sur votre blob, vous pouvez fournir des paramètres pour filtrer les blobs dont vous ne voulez pas. Vous voudrez peut-être tester les paramètres de zone de SimpleBlobDetector. Peut-être pourriez-vous calculer la zone en fonction de la taille de la zone de l'image, puis autoriser de manière itérative un blob plus petit si l'algorithme ne détecte aucun blobs.

Voici le lien vers la documentation OpenCV principale: http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html#simpleblobdetector

3
jluzwick

Ici. Il. Is. (Pour votre information: essayez de ne pas être paresseux et de comprendre ce qui se passe dans ma fonction ci-dessous.

cv::Mat findBiggestBlob(cv::Mat & matImage){
    int largest_area=0;
    int largest_contour_index=0;

    vector< vector<Point> > contours; // Vector for storing contour
    vector<Vec4i> hierarchy;

    findContours( matImage, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the image

    for( int i = 0; i< contours.size(); i++ ) {// iterate through each contour. 
        double a=contourArea( contours[i],false);  //  Find the area of contour
        if(a>largest_area){
            largest_area=a;
            largest_contour_index=i;                //Store the index of largest contour
            //bounding_rect=boundingRect(contours[i]); // Find the bounding rectangle for biggest contour
        }
    }

    drawContours( matImage, contours, largest_contour_index, Scalar(255), CV_FILLED, 8, hierarchy ); // Draw the largest contour using previously stored index.
    return matImage;
}
6
TimZaman

Pour trouver la boîte englobante du plus gros blob, j'ai utilisé findContours, suivi du code suivant:

double maxArea = 0;
for (MatOfPoint contour : contours) {
    double area = Imgproc.contourArea(contour);
    if (area > maxArea) {
        maxArea = area;
        largestContour = contour;
    }
}
Rect boundingRect = Imgproc.boundingRect(largestContour);
2
1''

Le moyen le plus efficace est probablement d’utiliser CvBlobsLib. Vous pouvez le télécharger à l’adresse http://sourceforge.net/projects/cvblobslib/?source=dlp

0
Bull

TimZaman, votre code a un bug mais je ne peux pas commenter et je commence une nouvelle réponse correcte.

Mat measure::findBiggestBlob(cv::Mat &src){
int largest_area=0;
int largest_contour_index=0;
Mat temp(src.rows,src.cols,CV_8UC1);
Mat dst(src.rows,src.cols,CV_8UC1,Scalar::all(0));
src.copyTo(temp);

vector<vector<Point>> contours; // storing contour
vector<Vec4i> hierarchy;

findContours( temp, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );

for( int i = 0; i< contours.size(); i++ ) // iterate
{
    double a=contourArea( contours[i],false);  //Find the largest area of contour
    if(a>largest_area)
    {
        largest_area=a;
        largest_contour_index=i;
    }

}

drawContours( dst, contours,largest_contour_index, Scalar(255), CV_FILLED, 8, hierarchy ); 
// Draw the largest contour
return dst;
}
0
Christoph Schart