在上篇文章我们已经检测到了内圆,本篇将根据上篇得到的内圆来检测外圆。步骤如下:

第一步:

用下面的这个算子对原图做卷积操作,这个算子可以叫作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


Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐