1 | initial version |
You can use template matching for solve this problem before matching you have to use below
void bhDrawBox2D(IplImage* srcImage,CvBox2D box2d,CvScalar color,int thickness)
{
CvPoint2D32f pts[4];
cvBoxPoints(box2d,pts);
for (int i=0; i < 3;i++)
{
cvLine(srcImage, cvPointFrom32f(pts[i]),cvPointFrom32f(pts[i+1]),color,thickness);
}
cvLine(srcImage, cvPointFrom32f(pts[3]),cvPointFrom32f(pts[0]),color,thickness);
}
CvBox2D bhGetImageBox2d(IplImage* srcImage)
{
CvBox2D result;
IplImage* tempImg = cvCloneImage(srcImage);
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* seq = 0;
cvFindContours(tempImg,storage,&seq,sizeof(CvContour),CV_RETR_EXTERNAL);
result = cvMinAreaRect2(seq,storage);
cvReleaseMemStorage(&storage);
cvReleaseImage(&tempImg);
return result;
}
int main(int argc, char** argv )
{
IplImage* srcImg = cvLoadImage("c:\\org.jpg",0);
IplImage* tempImg = cvLoadImage("c:\\temp.jpg",0);
cvThreshold(tempImg,tempImg,128,255,CV_THRESH_OTSU);
IplImage* orgsrcImg = cvCloneImage(srcImg);
cvNot(srcImg,srcImg);
cvNot(tempImg,tempImg);
CvBox2D tempBox = bhGetImageBox2d(tempImg);
cvCanny(srcImg,srcImg,10,50);
cvSmooth(srcImg,srcImg,CV_GAUSSIAN,9);
cvCanny(tempImg,tempImg,10,50);
cvSmooth(tempImg,tempImg,CV_GAUSSIAN,9);
IplImage* resultImg;
IplImage* resultImg2;
resultImg = cvCreateImage(cvSize(srcImg->width-tempImg->width+1,srcImg->height-tempImg->height+1),32,1);
resultImg2= cvCreateImage(cvSize(srcImg->width-tempImg->width+1,srcImg->height-tempImg->height+1),8,1);
cvMatchTemplate(srcImg,tempImg,resultImg,2);
double minV,maxV;
cvNormalize(resultImg,resultImg2,0,255,CV_MINMAX);
cvMinMaxLoc(resultImg2,&minV,&maxV);
cvThreshold(resultImg2,resultImg2,maxV - 60,255,CV_THRESH_BINARY);
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* seq = 0;
cvFindContours(resultImg2,storage,&seq,sizeof(CvContour),CV_RETR_EXTERNAL);
for (CvSeq* c= seq;c != 0 ;c = c->h_next)
{
CvRect r = cvBoundingRect(c);
cvSetImageROI(resultImg,r);
CvPoint minPnt,maxPnt;
cvMinMaxLoc(resultImg,&minV,&maxV,&minPnt,&maxPnt);
tempBox.center = cvPoint2D32f(maxPnt.x + r.x + tempImg->width/2,maxPnt.y+r.y + tempImg->height/2);
bhDrawBox2D(orgsrcImg,tempBox,cvScalarAll(128),2);
cvResetImageROI(resultImg);
}
cvReleaseMemStorage(&storage);
cvShowImage("view",orgsrcImg);
cvWaitKey(0);
}
2 | No.2 Revision |
You can use template matching for solve this problem before matching you have to use below do preprocessing by canny & smooth.
void bhDrawBox2D(IplImage* srcImage,CvBox2D box2d,CvScalar color,int thickness)
{
CvPoint2D32f pts[4];
cvBoxPoints(box2d,pts);
for (int i=0; i < 3;i++)
{
cvLine(srcImage, cvPointFrom32f(pts[i]),cvPointFrom32f(pts[i+1]),color,thickness);
}
cvLine(srcImage, cvPointFrom32f(pts[3]),cvPointFrom32f(pts[0]),color,thickness);
}
CvBox2D bhGetImageBox2d(IplImage* srcImage)
{
CvBox2D result;
IplImage* tempImg = cvCloneImage(srcImage);
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* seq = 0;
cvFindContours(tempImg,storage,&seq,sizeof(CvContour),CV_RETR_EXTERNAL);
result = cvMinAreaRect2(seq,storage);
cvReleaseMemStorage(&storage);
cvReleaseImage(&tempImg);
return result;
}
int main(int argc, char** argv )
{
IplImage* srcImg = cvLoadImage("c:\\org.jpg",0);
IplImage* tempImg = cvLoadImage("c:\\temp.jpg",0);
cvThreshold(tempImg,tempImg,128,255,CV_THRESH_OTSU);
IplImage* orgsrcImg = cvCloneImage(srcImg);
cvNot(srcImg,srcImg);
cvNot(tempImg,tempImg);
CvBox2D tempBox = bhGetImageBox2d(tempImg);
cvCanny(srcImg,srcImg,10,50);
cvSmooth(srcImg,srcImg,CV_GAUSSIAN,9);
cvCanny(tempImg,tempImg,10,50);
cvSmooth(tempImg,tempImg,CV_GAUSSIAN,9);
IplImage* resultImg;
IplImage* resultImg2;
resultImg = cvCreateImage(cvSize(srcImg->width-tempImg->width+1,srcImg->height-tempImg->height+1),32,1);
resultImg2= cvCreateImage(cvSize(srcImg->width-tempImg->width+1,srcImg->height-tempImg->height+1),8,1);
cvMatchTemplate(srcImg,tempImg,resultImg,2);
double minV,maxV;
cvNormalize(resultImg,resultImg2,0,255,CV_MINMAX);
cvMinMaxLoc(resultImg2,&minV,&maxV);
cvThreshold(resultImg2,resultImg2,maxV - 60,255,CV_THRESH_BINARY);
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* seq = 0;
cvFindContours(resultImg2,storage,&seq,sizeof(CvContour),CV_RETR_EXTERNAL);
for (CvSeq* c= seq;c != 0 ;c = c->h_next)
{
CvRect r = cvBoundingRect(c);
cvSetImageROI(resultImg,r);
CvPoint minPnt,maxPnt;
cvMinMaxLoc(resultImg,&minV,&maxV,&minPnt,&maxPnt);
tempBox.center = cvPoint2D32f(maxPnt.x + r.x + tempImg->width/2,maxPnt.y+r.y + tempImg->height/2);
bhDrawBox2D(orgsrcImg,tempBox,cvScalarAll(128),2);
cvResetImageROI(resultImg);
}
cvReleaseMemStorage(&storage);
cvShowImage("view",orgsrcImg);
cvWaitKey(0);
}