Was ist der effizienteste Weg, die Bounding Box des größten Blobs in einem Binärbild mit OpenCV zu finden? Leider hat OpenCV keine spezifische Funktionalität für die Blob-Erkennung. Soll ich einfach findContours()
verwenden und nach dem größten in der Liste suchen?OpenCV - Bounding Box des größten Blobs im Binärbild finden
Antwort
herunterladen Wenn Sie OpenCV-Bibliotheken verwenden möchten, überprüfen Sie OpenCVs SimpleBlobDetector. Hier ist ein weiterer Stack-Überlauf, der ein kleines Tutorial zeigt: How to use OpenCV SimpleBlobDetector
Dies gibt Ihnen jedoch nur die wichtigsten Punkte. Sie können dies als eine anfängliche Suche verwenden, um den gewünschten Blob zu finden, und dann möglicherweise den findContours-Algorithmus für die wahrscheinlichsten Blobs verwenden.
Je mehr Informationen Sie über Ihren Blob wissen, desto mehr Parameter können Sie angeben, um die Blobs herauszufiltern, die Sie nicht möchten. Vielleicht möchten Sie die Bereichsparameter des SimpleBlobDetectors testen. Könnte möglicherweise den Bereich basierend auf der Größe des Bildbereichs berechnen und dann iterativ einen kleineren Blob zulassen, wenn der Algorithmus keine Blobs erkennt.
Hier ist der Link zu den wichtigsten OpenCV-Dokumentation ist: http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html#simpleblobdetector
Danke für den Link, das sieht nach einer guten Alternative zu 'findContours' aus. Leider ist es nicht in OpenCV4Android, also bleibe ich bei meinem ursprünglichen Plan. –
Möglicherweise ist der effizienteste Weg, CvBlobsLib zu verwenden. Sie können es unter http://sourceforge.net/projects/cvblobslib/?source=dlp
Ich würde lieber keine Drittanbieter-Bibliothek verwenden, sorry. –
Um den Begrenzungsrahmen des größten Blob zu finden, habe ich findContours
, durch den folgenden Code folgt:
double maxArea = 0;
for (MatOfPoint contour : contours) {
double area = Imgproc.contourArea(contour);
if (area > maxArea) {
maxArea = area;
largestContour = contour;
}
}
Rect boundingRect = Imgproc.boundingRect(largestContour);
Was ist, wenn in dieser Kontur ein Loch ist und wir den Blob mit der größten Fläche haben wollen? – Koray
hier. Es. Ist. (FYI:. Versuchen Sie nicht faul und herauszufinden, zu sein, was unten in meiner Funktion geschieht
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;
}
Ist das nicht ein Duplikat meiner eigenen Antwort? –
Nein, meine Antwort ist in C++, der Kernsprache von OpenCV. Wie gesagt, es ist für die Faulen. – TimZaman
@TimZaman Kannst du mir mit dem Java-Gegenstück von drawContours() helfen? –
TimZaman, hat der Code einen Fehler, aber ich kann nicht sagen, so dass ich eine neue und richtige Antwort beginnen hier. meine Lösung basiert auf 1" 's und TimZaman Ideen:
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;
}
Es hängt davon ab, was Sie mit dem Blob danach tun wollen, aber Ihr Ansatz ist gültig :) –
Wenn Sie sagen, welche Sprache Sie, die Sie verwenden kann spezifische Antworten erhalten – Geoff
Ich lese gerade ein wenig darüber, wenn Sie bereits ein binäres Bild haben, klingt es wie die Suzuki Methode verwendend ('findContours') passt wirklich gut. Sie könnten auch schrittweise das erste weiße Pixel finden und dann 'floodFill' verwenden, um den Rest dieser Region zu finden, und so weiter. Aber ich bin mir nicht sicher, dass das schneller wäre. – Geoff