opencv 查找矩形
//矩形查找 BOOL CImageFun::FindSquares(IplImage *srcImage, double fMaxR, double fMinR, ARRCIR_XY_R &ptarr, int npar1, int npar2) { CvSeq *contour; int header_size, i, count; CvPoint *PointArray; CvPoint2D32f *PointArray32f; CvPoint myCenter; CvBox2D *myBox = (CvBox2D *) malloc(sizeof(CvBox2D)); //用于画圆和椭圆,这里将是 方形边缘周长拟合的圆 header_size = sizeof(CvContour); IplImage* gray = Canny(srcImage,npar1,npar2); IplImage *dst_=cvCloneImage( srcImage ); CvMemStorage* storage = cvCreateMemStorage(0); int number_of_c=cvFindContours (gray , storage, &contour, header_size, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); // 检查所有的轮廓 while(contour!=NULL) //当轮廓contour不为空时 { if(CV_IS_SEQ_CURVE(contour)) { count = contour ->total;//序列元素的总数,即轮廓上点的总数 PointArray = (CvPoint *)malloc(count * sizeof(CvPoint)); cvCvtSeqToArray(contour, PointArray, CV_WHOLE_SEQ); PointArray32f = (CvPoint2D32f *) malloc((count + 1) * sizeof(CvPoint2D32f)); ARRPOINT arr; POINT pt; for (i=0; i<count-1; i++) { pt.x = PointArray32f[i].x = (double)(PointArray[i].x); pt.y = PointArray32f[i].y = (double)(PointArray[i].y); arr.push_back(pt); } PointArray32f[i].x = (double)(PointArray[0].x); PointArray32f[i].y = (double)(PointArray[0].y); if (count>=7) { cvFitEllipse(PointArray32f, count,myBox); myCenter.x = (int) myBox->center.x; myCenter.y = (int) myBox->center.y; double length = myBox->size.height / 2; double width = myBox->size.width / 2; BOOL bOk =(myCenter.x > 0) && (myCenter.y >0); bOk &= myCenter.x - length >=0; bOk &= myCenter.x + length <= srcImage->width; bOk &= myCenter.y - length >=0; bOk &= myCenter.y + length <= srcImage->height; bOk &= length >= fMinR && length <= fMaxR; //////////////////////// //过滤,半径过大的,过小的,丢弃 if (!bOk) { goto EXIT_END; } cvCircle( dst_, cvPoint(cvRound(myCenter.x),cvRound(myCenter.y)), 3, CV_RGB(0,255,0), -1, 8, 0 ); cvCircle( dst_, cvPoint(cvRound(myCenter.x),cvRound(myCenter.y)), cvRound(myBox->size.height / 2), CV_RGB(255,0,0), 1, 8, 0 ); //DBWindowWrite(_T("圆心坐标x= %d 圆心坐标y=%d 半径=%.3f"),myCenter.x,myCenter.y,length); /////////////简单的将找到的位置信息加到集合中//////////// CIR_XY_R ptcyr = {myCenter.x, myCenter.y,length}; ptarr.push_back(ptcyr); /*//创建一个矩形,然后 POINT ptcr; ptcr.x = myCenter.x; ptcr.y = myCenter.y; ARRPOINT::iterator iter; for (iter = arr.begin(); iter != arr.end(); iter++) { float fdis = GetPointDistance(ptcr,*iter); DBWindowWrite(_T("坐标x=%d 坐标y= %d"),(*iter).x,(*iter).y); } bOk &= abs(length - width) <= nMarkPixOffset; if(bOk) //检测所有的点是否在圆上,容许的10的数据误差,误差+-2个像素 { POINT ptcr; ptcr.x = myCenter.x; ptcr.y = myCenter.y; int nOut =0; ARRPOINT::iterator iter; for (iter = arr.begin(); iter != arr.end(); iter++) { float fdis = GetPointDistance(ptcr,*iter); if(abs(fdis - length) <= nMarkPixOffset) nOut++; } CIR_XY_R ptcyr = {myCenter.x, myCenter.y,length}; float fbl = (float)nOut / arr.size(); if(fbl >= fMarkTolerance) ptarr.push_back(ptcyr); //找到了就直接跳出来 }*/ } EXIT_END: free(PointArray32f ); free(PointArray ); if(ptarr.size()) break; } contour = contour->h_next; } //cvShowImage( "template", dst_ ); //cvWaitKey( 0 ); free (myBox); cvReleaseImage(&gray); cvReleaseImage(&dst_); cvReleaseMemStorage(&storage); //过滤集合数据 if (FALSE){ double dx=0,dy=0,dr=0; for (int i=0;i<ptarr.size();i++) { dx+=ptarr[i].fx; dy+=ptarr[i].fy; dr+=ptarr[i].fr; } ptarr.clear(); CIR_XY_R ptcyr = {dx/ptarr.size(), dy/ptarr.size(), dr/ptarr.size()}; ptarr.push_back(ptcyr); } return ptarr.size(); }