虹膜识别外圆检测
在上篇文章我们已经检测到了内圆,本篇将根据上篇得到的内圆来检测外圆。步骤如下:
第一步:
用下面的这个算子对原图做卷积操作,这个算子可以叫作Vertical Filter
-1,0,1,
-1,0,1,
-1,0,1,
-1,0,1,
-1,0,1
卷积后的结果如下:
第二步:对第一步得到的结果进行二值化,这个我设的阈值是10。二值化后的结果如下
第三步:计算规矩规定角度范围弧线上的白点的数量,注意这个是针对不同的半径都要计算,半径的变化范围从1.8*内圆半径开始逐渐变大,一直到三倍的半径。下图是角度范围的约定。从下图可以看图角度的范围是左右两边各向下的60度区间,但在我实验中是左右两边各向下30度的区间。
第四步:找到在规定弧线上白点最大的半径,这个半径就是最后的外圆半径。最后的结果如下:
外圆检测加上内圆检测的全部opencv代码如下:
#include
#include
using namespace cv;
using namespace std;int main()
{Mat srcImage=imread("C://150.bmp");Mat midImage,dstImage,edge;Mat srcImage1=srcImage.clone();imshow("原始图",srcImage);//外圆 Mat kern = (Mat_(5,3) << -1, 0 ,1,-1, 0 ,1,-1, 0 ,1,-1, 0 ,1,-1, 0 ,1);Mat dst;filter2D(srcImage,dst,srcImage.depth(),kern);namedWindow("卷积",WINDOW_AUTOSIZE);imshow("卷积",dst);threshold(dst,dst,10,255,CV_THRESH_BINARY);namedWindow("二值化",WINDOW_AUTOSIZE);imshow("二值化",dst);threshold(srcImage, srcImage, 30, 200.0, CV_THRESH_BINARY);//二值化imshow("二值化1",srcImage);int cn=0;//cn是圆的个数int radius=0;float ratio = 0;float maxratio = 0;float result[3];cvtColor(srcImage,midImage,COLOR_BGR2GRAY);blur(midImage,edge,Size(3,3));Canny(edge,edge,3,9,3);GaussianBlur(midImage,midImage,Size(9,9),2,2);vector circles;HoughCircles(midImage,circles,CV_HOUGH_GRADIENT,2,10,200,80,0,0);for(cn=0;cn(i,j)[2]; //cvGetReal2D(img,i,j);if(value == 0)count++;}}ratio = float(count)/(3.14*radius*radius);if (ratio >= maxratio){result[0] = circles[cn][0];result[1] = circles[cn][1];result[2] = radius;maxratio = ratio;}}printf("黑色点像素的个数:%d\n",count);printf("瞳孔重合比率:%f\n",ratio);Point center1(cvRound(result[0]),cvRound(result[1]));circle(srcImage1,center1,3,Scalar(0,255,0),-1,8,0);circle(srcImage1,center1,result[2],Scalar(155,50,255),3,8,0);}//外圆int r=result[2];int value;int tmp_count = 0; int test=0;int outer_r = 0;int max_count = 0;int ti,tj;for(double tr = 1.8*r;tr< 3*r;tr++ ) // 半径的长度 1.8倍的半径到3倍的半径{tmp_count = 0;for(double angle = 0;angle<=60;angle++){ti = cvRound(result[1] + tr*cos(angle));tj = cvRound(result[0]+tr*sin(angle));if ((ti < dst.rows) && (ti>0)&&(dst.cols)&&(tj>0))value =dst.at(ti,tj)[2];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); //画外圆,已经知道内圆的圆心,外圆也是这个圆心,外圆半径的大小为outer_rPoint center1(cvRound(result[0]),cvRound(result[1]));circle(srcImage1,center1,3,Scalar(0,255,0),-1,8,0);circle(srcImage1,center1,outer_r,Scalar(155,50,255),3,8,0);if(cn==0){printf("No Circle Detected!!Please Check!!\n");system("pause");}imshow("效果图",srcImage1);waitKey(0);return 0;
}
最终的效果展示如下:
这样就能实现 虹膜内外圆的精定位了!
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
