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=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