4

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

I have tried HoughCircles but it seems that it is not precise as the iris circle seems to not be so accurate. What information I have already is the center point for the eye pupil and its radius.

Grayscale Eye

It has been suggested to me to find the iris edge to try and measure the gradient magnitude starting from the pupil center going outward. Then to use a histogram using the accumulation of the gradient maximum to find the iris width. I am not exactly sure in which way to implement this, starting from a specific point.

I used the Sobel operator on the eye ROI to try and 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 exactly sure how to proceed next. Any suggestions or comments are appreciated. Also please let me know if I missed any information or if I was vague on something. Much thanks in advance!

EDIT: I should have explained the context of my application better so I apologize for that. I am measuring pupil dilation of the eye over frames from 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 variations of the distance from the eye to the camera can be used to compensate for misinterpreted values of the pupil size, since if the eye becomes closer to the camera the pupil will of course appear larger without dilation. I might also try other ways to account for this such as the eye corners but I figured that since I already have several pupil features that I would start with the iris.

Again, sorry for leaving this detail out before. Thanks!

jmo
  • 153
  • 2
  • 12
  • 1
    I already know about the Hough Circle Transform. I have tried it already and it does not perform well enough for me to use. Thank you for the suggestion though. – jmo Oct 12 '12 at 08:18
  • I am failing to understand why this was closed as a duplicate of another questions about HoughCircles. If someone could please let me know why this is the case so that I do not create duplicate questions in the future if in fact that is what I did. However, I specifically say that I do not want to use HoughCircles. – jmo Oct 15 '12 at 14:14
  • You say, "I have already is the center point for the eye pupil and its radius." Can you provide some details of how you already arrive at that information, what method you found to be most successful? – ChaimKut Mar 07 '13 at 09:16
  • The eye centers were obtained by using the method proposed in the paper "Accurate Eye Center Location through Invariant Isocentric Patterns". For the pupil radius, I am using an IR camera and do a binary threshold. – jmo Mar 07 '13 at 10:15
  • If you instead want to proceduraly generate an eye iris, you could use this: http://blog.octomy.org/2017/08/the-eyes-are-mirror-of-soul.html – Mr. Developerdude Jan 20 '21 at 00:29

2 Answers2

2

I think that you should use that fact that there's black circle inside iris.

Here's what I've got after simple black color segmentation on your image:

Segmented image

And it seems that a real iris is in 3 or 4 times bigger than this black circle. So, here's result:

Result image

Looking for a source code? This is it:

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();
    }
}
ArtemStorozhuk
  • 8,715
  • 4
  • 35
  • 53
  • Astor, thank you for the suggestion. I probably should have explained the context more of my application though. I actually already implement your suggestion, more or less, to get the radius of the pupil. But I need something that is more accurate and not so much an approximation. Thank you in any case for the detailed answer. – jmo Oct 12 '12 at 08:20
  • Thanks for the link. I just read it. I know I'm new to posting here but if there is something specific that I should be doing (or not doing) with this maybe you can let me know. – jmo Oct 14 '12 at 13:25
2

Clarifying the suggestion you talk about in your question:

"It has been suggested to me to find the iris edge to try and measure the gradient magnitude starting from the pupil center going outward. Then to use a histogram using the accumulation of the gradient maximum to find the iris width. I am not exactly sure in which way to implement this, starting from a specific point."

What you can concretely do is to start from your pupil center, and perform a region growing algorithm where your stopping condition, instead of beeing, say, a too different grey level value, is a threshold on the magnitude of your gradient. Some pseudo code:

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)
remi
  • 3,914
  • 1
  • 19
  • 37
  • Thanks remi for the suggestion. I am away at the moment but will attempt this in a few days and let you know the results. It seems promising. Thanks! – jmo Oct 12 '12 at 08:58
  • Thanks for the help. This seems to be working for me in the way that I need. I'm not sure why people think this is a duplicate question to HoughCircles when both the question and the accepted answer do not use it. Much thanks! – jmo Oct 15 '12 at 14:18
  • I agree, I'm not sure how to get the attention to users with high rep to get the question reopened – remi Oct 16 '12 at 07:34