OpenCV: contorno errato intorno blob
-
25-09-2019 - |
Domanda
Sto cercando di disegnare i contorni attorno blob in un'immagine binaria, tuttavia, a volte, OpenCV disegna un unico contorno attorno a due macchie distinte. sotto è un esempio. Come posso risolvere questo problema?
Qui si dovrebbe trarre due caselle di delimitazione per il blob sulla destra e separatamente per quella della sinistra. Sono d'accordo che sono vicini, ma una distanza sufficiente tra di loro. Sono solo disegnare i contorni esterni invece che l'albero o lista. Sto anche utilizzando cvFindNextContour (contourscanner) in quanto questa è un'implementazione più facile per il mio caso.
Grazie
EDIT: Immagine visualizzata nella finestra "uscita" è da una funzione diversa, che fa proprio la sottrazione di immagini. Immagine visualizzata nella finestra "contorni" è nella funzione pplfind (). immagine "in uscita" viene passato a img_con ().
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;
}
Soluzione
Non ho mai usato cvFindNextContour
, ma in esecuzione cvFindContours
con CV_RETR_EXTERNAL
sulla tua immagine sembra funzionare bene:
Io uso OpenCV + Python, quindi questo codice potrebbe non essere utile per voi, ma per amor di completezza qui va:
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()
Modifica: lei ha chiesto come disegnare solo i contorni con determinate proprietà; sarebbe qualcosa di simile:
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()