OpenCV: falsche Kontur um Blobs
-
25-09-2019 - |
Frage
Ich versuche Konturen in einem binären Bild um Blobs zu zeichnen, aber manchmal zieht OpenCV eine einzelne Kontur um zwei verschiedene Blobs. unten ist ein Beispiel. Wie kann ich dieses Problem lösen?
Hier sollte es zwei Zeichen-Boxen für den Klecks auf der rechten Seite ziehen und separat für die eine von der linken Seite. Ich bin damit einverstanden sie sind in der Nähe, aber genug Abstand zwischen ihnen. Ich bin nur Außenkonturen anstelle des Baumes oder der Liste ziehen. Ich verwende auch cvFindNextContour (contourscanner), da dies eine einfachere Implementierung für meinen Fall ist.
Danke
EDIT: Bild in der „Output“ Fenster angezeigt wird, aus einer anderen Funktion, die nur Bild Subtraktion der Fall ist. Bild gefunden in der „Konturen“ Fenster ist in der Funktion pplfind (). „Ausgang“ Bild wird auf img_con () übergeben.
IplImage* img_con(IplImage* image){
int ppl;
CvMemStorage* memstr = cvCreateMemStorage();
IplImage* edges = cvCreateImage(cvGetSize(image),8,1);
cvCanny(image,edges,130,255);
CvContourScanner cscan = cvStartFindContours(image,memstr,sizeof(CvContour),CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE,cvPoint(0,0));
ppl = pplfind(cscan,cvGetSize(image));
if (ppl !=0 )
printf("Estimated number of people: %d\n",ppl);
cvEndFindContours(&cscan);
cvClearMemStorage(memstr);
return edges;
}
int pplfind(CvContourScanner cscan, CvSize frSize){
ofstream file; char buff[50];
file.open("box.txt",ofstream::app);
int ppl =0;
CvSeq* c;
IplImage *out = cvCreateImage(frSize,8,3);
while (c = cvFindNextContour(cscan)){
CvRect box = cvBoundingRect(c,1);
if ((box.height > int(box.width*1.2))&&(box.height>20)){//&&(box.width<20)){//
ppl++;
cvRectangle(out,cvPoint(box.x,box.y),cvPoint(box.x+box.width,box.y+box.height),CV_RGB(255,0,50),1);
cvShowImage("contours",out);
//cvWaitKey();
}
//printf("Box Height: %d , Box Width: %d ,People: %d\n",box.height,box.width,ppl);
//cvWaitKey(0);
int coord = sprintf_s(buff,"%d,%d,%d\n",box.width,box.height,ppl);
file.write(buff,coord);
}
file.close();
cvReleaseImage(&out);
return ppl;
}
Lösung
Ich habe noch nie verwendet cvFindNextContour
, sondern läuft cvFindContours
mit CV_RETR_EXTERNAL
auf dem Bild scheint zu funktionieren:
verwende ich OpenCV + Python, so dass dieser Code nicht nützlich sein könnte für Sie, aber aus Gründen der Vollständigkeit hier geht es:
contours = cv.FindContours(img, cv.CreateMemStorage(0), mode=cv.CV_RETR_EXTERNAL)
while contours:
(x,y,w,h) = cv.BoundingRect(contours)
cv.Rectangle(colorImg, (x,y), (x+w,y+h), cv.Scalar(0,255,255,255))
contours = contours.h_next()
Edit: Sie gefragt, wie nur mit bestimmten Eigenschaften, diese Konturen zu zeichnen; es wäre so etwas wie dies:
contours = cv.FindContours(img, cv.CreateMemStorage(0), mode=cv.CV_RETR_EXTERNAL)
while contours:
(x,y,w,h) = cv.BoundingRect(contours)
if h > w*1.2 and h > 20:
cv.Rectangle(colorImg, (x,y), (x+w,y+h), cv.Scalar(0,255,255,255))
contours = contours.h_next()