1. 程式人生 > >虹膜識別內圓檢測 精定位 求最大比率

虹膜識別內圓檢測 精定位 求最大比率

本文和下文介紹如何對一個虹膜影象進行分割提取出虹膜,在虹膜分割中,最重要的是檢測兩個圓,一個內圓,一個是外圓。下面是兩個圓的示意圖。


本文先講解如何檢測內圓,在我的方法中,內圓的檢測可分為四步:

1. 用Canny邊緣檢測和Hough變換從經過高斯平滑處理後的圖片中檢測圓。在此步操作,我故意把Hough變換的閾值設得比較小,這樣我們就可以檢測出很多圓了。下圖就是用cvHoughCircle檢測出的圓。


可以看到,在此步中,我們檢測到了圓,但是有很多圓,我們現在要想辦法找到我們要的那個內圓。下面的步驟就是我找內圓的方法。

2. 把原圖二值化,這個可以通過cvThreshold很容易實現,閾值設在五十左右就可以了。閾值化後的影象如下:


這個二值化後得到的影象是為了後面計算每個圓中包含的瞳孔點比率做準備的。

3. 計算第一步中得到的每個圓的一個比率,計算是根據第二步中二值影象進行。比率的定義如下

PupilInclusion Rate = Number of black points / Area of circle 即:用每一個circle中包含的黑點的個數除以圓的面積 4. 在計算出每一個圓的比率後,找到比率最大的那個,並把那個作為最後的內圓,這樣就可以完美得檢測出內圓了。

 
 

opencv程式碼如下:

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;

int main()
{
	Mat srcImage=imread("C://1.bmp");
	Mat midImage,dstImage,edge;
	imshow("原始圖",srcImage);
	threshold(srcImage, srcImage, 30, 200.0, CV_THRESH_BINARY);//二值化

	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<Vec3f> circles;
	HoughCircles(midImage,circles,CV_HOUGH_GRADIENT,2,10,200,80,0,0);
	for(cn=0;cn<circles.size();cn++)
	{
		Point center(cvRound(circles[cn][0]),cvRound(circles[cn][1]));
		 radius=cvRound(circles[cn][2]);
	//	circle(srcImage,center,3,Scalar(0,255,0),-1,8,0);
	//	circle(srcImage,center,radius,Scalar(155,50,255),3,8,0);
		//////////////////////////////
		int width = srcImage.cols;
	    int height = srcImage.rows;	
		int value; //pixel value
	    int count = 0;
		for(int i=0;i<height;i++)
	    {
			for(int j=0;j<width;j++)
			{
				if (sqrt(pow(float(center.x-j),2)+pow(float(center.y-i),2))< radius)
				{
					//獲得某點的畫素值
					value = srcImage.at<Vec3b>(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(srcImage,center1,3,Scalar(0,255,0),-1,8,0);
		 circle(srcImage,center1,result[2],Scalar(155,50,255),3,8,0);
  }
	 if(cn==0)
	 {
		printf("No Circle Detected!!Please Check!!\n");
		system("pause");
	 }
	imshow("效果圖",srcImage);
	waitKey(0);
	return 0;
}

一定要注意這段程式碼是在迴圈裡面的:

 if (ratio >= maxratio)
		 {
			result[0] = circles[cn][0];
			result[1] = circles[cn][1];
			result[2] = radius;
			maxratio = ratio;
		 }

而且result[0]=cricles[cn][0];
最後的執行結果如下所示:
在這裡插入圖片描述
這樣就把所有可能的霍夫圓的重合的最大比率的圓畫出來了,輸出統計到黑色畫素點的總個數。