OpenCV虹膜检测C ++

目标:我正在尝试使用video作为input获取虹膜的大小(宽度/半径)。

我已经尝试过HoughCircles,但是看起来不太精确,因为虹膜圈看起来不太准确。 我已经有了什么信息是眼睛瞳孔及其半径的中心点。

灰度眼睛

有人build议我find虹膜边缘,试着从瞳孔中心向外测量梯度的大小。 然后使用直方图使用最大梯度的累加来查找虹膜宽度。 从具体的angular度出发,我不太清楚从哪个方面来实现这一点。

我用眼睛ROI上的Sobel算子来尝试获得下面显示的输出的渐变。

索贝尔眼

Sobel图像编码:

void irisFind(Mat gradMat, Point2i pupCenter, int pupRad){ imshow("original", gradMat); Mat gradX; Mat gradY; Mat absGradX; Mat absGradY; GaussianBlur(gradMat, gradMat, Size(3, 3), 0, 0, BORDER_DEFAULT); equalizeHist(gradMat, gradMat); //Generate Gradient along x Sobel(gradMat, gradX, CV_16S, 1, 0, 3, 1, 0, BORDER_DEFAULT); convertScaleAbs(gradX, absGradX); //Generate Gradient along y Sobel(gradMat, gradY, CV_16S, 0, 1, 3, 1, 0, BORDER_DEFAULT); convertScaleAbs(gradY, absGradY); addWeighted(absGradX, .5, absGradY, .5, 0, gradMat); imshow("Sobel", gradMat); } 

我不确定如何继续下一步。 任何build议或意见表示赞赏。 也请让我知道,如果我错过了任何信息,或者如果我对某事模糊。 非常感谢提前!

编辑:我应该更好地解释我的应用程序的上下文,所以我很抱歉。 我正在测量从videoinput帧的瞳孔扩张。 我已经知道了瞳孔中心点的位置和瞳孔的半径。 我试图find虹膜的大小,以便可以使用从眼睛到相机的距离的变化来补偿瞳孔大小的误解值,因为如果眼睛靠近相机,瞳孔当然会出现较大而没有扩张。 我也可以尝试其他的方法来解释这个问题,比如说眼angular,但是我觉得既然我已经有了几个瞳孔特征,那么我就从虹膜开始。

再次,遗憾的是之前没有提到这个细节。 谢谢!

澄清你在你的问题中提出的建议:

“有人建议我找到虹膜边缘来测量从瞳孔中心向外的梯度大小,然后用直方图利用梯度最大值的积累来找出虹膜的宽度,但我并不确定从哪个方面来实现这一点,从一个特定的点开始。“

你可以具体做的是从你的瞳孔中心开始,并执行一个区域增长算法,你的停止条件,而不是beeing,说一个太不同的灰度值,是一个梯度幅度的门槛。 一些伪代码:

 initalize list of points with center of your pupil initialize a mask image to zero while list of point is not empty point pt = pop() set maskImage at pt to 255 for pt2 in pt neighbourhood if (gradientMagnitude at pt2 < THRESHOLD and maskImage at pt2 == 0) list of points.add (pt2) 

我认为你应该使用虹膜内有黑圈的事实。

这就是你的图像简单的黑色分割后,

分割的图像

而真正的虹膜似乎比这个黑圈大三四倍。 所以,结果如下:

结果图像

寻找一个源代码? 就是这个:

 int main() { Mat src = imread("input.jpg", CV_LOAD_IMAGE_GRAYSCALE), tmp; imshow("Source", src); double minVal = 0; minMaxLoc(src, &minVal, NULL, NULL, NULL); threshold(src, tmp, minVal + 10, 255, THRESH_BINARY_INV); //(Optional) remove noise (small areas of white pixels) /* Mat element = getStructuringElement(MORPH_ELLIPSE, Size(3, 3), Point(1, 1)); erode(tmp, tmp, element); dilate(tmp, tmp, element); */ vector<Vec4i> hierarchy; vector<vector<Point2i> > contours; findContours(tmp, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); //find contour with max area int maxArea = 0; Rect maxContourRect; for (int i=0; i<contours.size(); i++) { int area = contourArea(contours[i]); Rect rect = boundingRect(contours[i]); double squareKoef = ((double) rect.width)/rect.height; //check if contour is like square (shape) #define SQUARE_KOEF 1.5 if (area>maxArea && squareKoef < SQUARE_KOEF && squareKoef > 1.0/SQUARE_KOEF) { maxArea = area; maxContourRect = rect; } } if (maxArea == 0) { std::cout << "Iris not found!" << std::endl; } else { Rect drawRect = Rect(maxContourRect.x-maxContourRect.width, maxContourRect.y-maxContourRect.height, maxContourRect.width*3, maxContourRect.height*3); rectangle(src, drawRect, Scalar(0), 1); imshow("Dest", src); waitKey(); } }