OpenCV Iris Detection C ++

Purpose: I am trying to get the size of the iris (width / radius) using video as input.

I tried HoughCircles, but it seems that it is not accurate, because the circle of the iris does not seem so accurate. What information do I already have the center of the pupil point of the eye and its radius.

Grayscale

I was asked to find the edge of the iris in order to try to measure the magnitude of the gradient, starting from the center of the pupil going out. Then use the histogram, using the accumulation of the maximum gradient to find the width of the aperture. I'm not quite sure how to implement this, starting from a certain point.

I used the Sobel operator on the eye's ROI to try to get the gradient with the output shown below.

Sobel eye

Sobel Image Code:

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); } 

I am not quite sure how to proceed. Any suggestions or comments are appreciated. Also, please let me know if I missed any information, or if I am vague about something. Thank you very much in advance!

EDIT: I had to better explain the context of my application, so I apologize for that. I measure the pupil expansion of the eye over the frames from the video input. I already know the location of the center point of the pupil and the radius of the pupil. I am trying to find the size of the iris, so that changes in the distance from the eye to the camera can be used to compensate for the misinterpreted values โ€‹โ€‹of the pupil size, because if the eye gets closer to the camera, the pupil, of course, will appear more without dilatation. I could also try other ways to explain this, such as the angles of the eyes, but I thought that since I already have a few student functions that I will start with the diaphragm.

Again, sorry to leave this item before. Thanks!

+4
source share
2 answers

Clarification of the sentence you are talking about in your question:

โ€œI was asked to find the edge of the iris to try to measure the magnitude of the gradient, starting from the center of the pupil going out. Then, to use the histogram, using the accumulation of the maximum of the gradient, to find the width of the iris. I'm not quite sure how to implement this, starting from a certain point. "

What you can do specifically is to start from your student center and execute an algorithm for growing the area where your stopping condition, rather than, say, a too different gray level value, is the threshold value of your gradient. Some pseudo codes:

 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) 
+2
source

I think you should use the fact that there is a black circle inside the iris.

Here is what I got after a simple black segmentation in your image:

Segmented image

And it seems that the real iris is 3 or 4 times larger than this black circle. So here is the result:

Result image

Looking for source code? It is he:

 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(); } } 
+2
source

Source: https://habr.com/ru/post/1439213/


All Articles