在上篇文章我们已经检测到了内圆,本篇将根据上篇得到的内圆来检测外圆。步骤如下:
第一步:
用下面的这个算子对原图做卷积操作,这个算子可以叫作Vertical Filter
-1,0,1,
-1,0,1,
-1,0,1,
-1,0,1,
-1,0,1
卷积后的结果如下:
第二步:对第一步得到的结果进行二值化,这个我设的阈值是10。二值化后的结果如下
第三步:计算规矩规定角度范围弧线上的白点的数量,注意这个是针对不同的半径都要计算,半径的变化范围从1.2*内圆半径开始逐渐变大。下图是角度范围的约定。从下图可以看图角度的范围是左右两边各向下的60度区间,但在我实验中是左右两边各向下30度的区间。
第四步:找到在规定弧线上白点最大的半径,这个半径就是最后的外圆半径。最后的结果如下:
外圆检测的代码如下:
IplImage* tmp = cvCreateImage(cvGetSize(src),8,1);
//vertical filter operator
float k[15]={
-1,0,1,
-1,0,1,
-1,0,1,
-1,0,1,
-1,0,1 };
CvMat km;
km = cvMat(5,3,CV_32F,k);
cvFilter2D(src,tmp,&km,cvPoint(-1,-1));
cvNamedWindow("filter",1);
cvShowImage("filter",tmp);
cvThreshold(tmp,tmp,10,255,CV_THRESH_BINARY);
cvNamedWindow("filter1",1);
cvShowImage("filter1",tmp);
//detect the outer circle of iris
int FindOuterCircle(IplImage* img)
{
CvPoint center;
//X, Y and R are the inter circle position and radius
center.x = X;
center.y = Y;
int r = R;
int value; //pixel value
int max_count = 0;
int outer_r = 0;
int tmp_count = 0;
int test=0;
int ti,tj;
//3,6 img14
for(double tr = 2*r;tr< 4*r;tr++ )
{
tmp_count = 0;
for(double angle = 0;angle<=60;angle++)
{
ti = cvRound(center.y + tr*cos(angle));
tj = cvRound(center.x+tr*sin(angle));
if ((ti < HEIGHT) && (ti>0)&&(tj<WIDTH)&&(tj>0))
value = cvGetReal2D(img,ti,tj);
else break;
if( value == 255)
tmp_count++;
ti = cvRound(center.y+ tr*cos(angle));
tj = cvRound(center.x-tr*sin(angle));
if ((ti < HEIGHT) && (ti>0)&&(tj<WIDTH)&&(tj>0))
value = cvGetReal2D(img, ti,tj);
else break;
if( value == 255)
tmp_count++;
}
if (tmp_count>=max_count)
{
max_count = tmp_count;
outer_r = tr;
test++;
}
}
printf("outer radius = %d\n",outer_r);
return outer_r;
}
完整的测试图片及代码下载:
http://download.csdn.net/detail/computerme/8158905