1

--------------read edit below--------------- I am trying to detect the edge of the pupils and iris within various images. I am altering parameters and such but I can only manage to ever get one iris/pupil outline correct, or get unnecessary outlines in the background, or none at all. Is the some specific parameters that I should try to try and get the correct outlines. Or is there a way that I can crop the image just to the eyes, so the system can focus on that part?

This is my UPDATED method:

private void findPupilIris() throws IOException {
    //converts and saves image in grayscale

    Mat newimg = Imgcodecs.imread("/Users/.../pic.jpg");
    Mat des = new Mat(newimg.rows(), newimg.cols(), newimg.type());
    Mat norm = new Mat();

    Imgproc.cvtColor(newimg, des, Imgproc.COLOR_BGR2HSV);
    List<Mat> hsv = new ArrayList<Mat>();
    Core.split(des, hsv);
    Mat v = hsv.get(2); //gets the grey scale version

    Imgcodecs.imwrite("/Users/Lisa-Maria/Documents/CapturedImages/B&Wpic.jpg", v); //only writes mats

    CLAHE clahe = Imgproc.createCLAHE(2.0, new Size(8,8) ); //2.0, new Size(8,8) 
    clahe.apply(v,v);
//    Imgproc.GaussianBlur(v, v, new Size(9,9), 3); //adds left pupil boundary and random circle on 'a'
 //   Imgproc.GaussianBlur(v, v, new Size(9,9), 13); //adds right outer iris boundary and random circle on 'a'
    Imgproc.GaussianBlur(v, v, new Size(9,9), 7);  //adds left outer iris boundary and random circle on left by hair
  //  Imgproc.GaussianBlur(v, v, new Size(7,7), 15);
    Core.addWeighted(v, 1.5, v, -0.5, 0, v);


    Imgcodecs.imwrite("/Users/.../after.jpg", v); //only writes mats
    if (v != null) {
        Mat circles = new Mat();

        Imgproc.HoughCircles( v, circles, Imgproc.CV_HOUGH_GRADIENT, 2, v.rows(), 100, 20, 20, 200 );

        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();

        System.out.println("circles.cols() " + circles.cols());
        if(circles.cols() > 0) {
            System.out.println("1");
            for (int x = 0; x < circles.cols(); x++) {
                System.out.println("2");
                double vCircle[] = circles.get(0, x);


                if(vCircle == null) {
                    break;
                }

                Point pt = new Point(Math.round(vCircle[0]), Math.round(vCircle[1]));
                int radius = (int) Math.round(vCircle[2]);

                //draw the found circle




                Imgproc.circle(v, pt, radius, new Scalar(255,0,0),2); //newimg
                //Imgproc.circle(des, pt, radius/3, new Scalar(225,0,0),2); //pupil
                Imgcodecs.imwrite("/Users/.../Houghpic.jpg", v); //newimg

                //draw the mask: white circle on black background
//                  Mat mask = new Mat( new Size( des.cols(), des.rows() ), CvType.CV_8UC1 );
//                  Imgproc.circle(mask, pt, radius, new Scalar(255,0,0),2); 

//                  des.copyTo(des,mask);
//                  Imgcodecs.imwrite("/Users/..../mask.jpg", des); //newimg


                Imgproc.logPolar(des, norm, pt, radius, Imgproc.WARP_FILL_OUTLIERS);
                Imgcodecs.imwrite("/Users/..../Normalised.jpg",norm);
            }
        }
    }
}

Result: hough pic

tgif
  • 15
  • 6
  • Why did you post [another question](http://stackoverflow.com/questions/43309075/opencv-java-can-only-detect-edge-of-iris-but-not-pupil-using-hough-circles)? – Rick M. Apr 10 '17 at 15:12
  • because i changed it, im going to delete the other one, i am now able to detect the pupils/iris edges only sometimes – tgif Apr 11 '17 at 09:46
  • So did the new filters work for you? Which one? – Rick M. Apr 11 '17 at 12:43
  • i've made an edit that explains whats happening thanks :) – tgif Apr 11 '17 at 13:05
  • ahh thank you, i made a couple of edits to my code, would you say the code is correct now? and it definitely seemed to improve the hough result, i think i need to make to pupil outline slightly bigger though – tgif Apr 11 '17 at 13:20
  • hmm when i use different images it doesn't seem to work as well at capturing the iris's – tgif Apr 11 '17 at 13:33
  • You should try using `bilateralfilter` instead of Gaussian. May be adaptive histogram equalization. It would be helpful if you upload the best case and the worst case from your data set to better understand the problem. – Rick M. Apr 11 '17 at 16:00
  • okay, so I added in the bilateralfilter and have put up the best image I have managed to achieve. The worst is getting absolutely no circles or just getting them in the wrong places in the background. I tried adding in the histogram thing but seemed to get better results without it.thanks – tgif Apr 14 '17 at 11:34
  • Can you put up the worst case image too? I'll try to figure out and get back to you – Rick M. Apr 14 '17 at 11:40
  • hi, @RickM. you didn't happen to figure anything out did you? – tgif Apr 18 '17 at 10:12
  • Hey! I have been busy at work. Probably at the end of the day today :) – Rick M. Apr 19 '17 at 08:52
  • Ok, so figured something out but its better we discuss this in chat before I post an answer. Let me know when you have time. I'll try to be online then – Rick M. Apr 19 '17 at 15:37
  • okay cool, im free now if its not too late? or anytime tomorrow – tgif Apr 19 '17 at 20:16
  • I am online now for the next 8 hours – Rick M. Apr 20 '17 at 08:10
  • okay im free now – tgif Apr 20 '17 at 11:00
  • Ok I will invite you to a chat room – Rick M. Apr 20 '17 at 12:33
  • okay thank you for ur help – tgif Apr 20 '17 at 12:52
  • [chat room](http://chat.stackoverflow.com/rooms/142179/opencv) – Rick M. Apr 20 '17 at 13:03
  • hey sorry, i dont think i have a high enough reputation to talk in the chat room – tgif Apr 20 '17 at 13:15
  • Ahhhh ok. What should we do then? Can you read the messages in the chat room? The ones I post? – Rick M. Apr 20 '17 at 13:16
  • yeah i can read them – tgif Apr 20 '17 at 13:18
  • thank you, that was helpful! I'll just upload the image – tgif Apr 20 '17 at 13:35
  • i will try update my version later or tomorrow, thanks – tgif Apr 20 '17 at 13:42
  • Sounds good, I will post an answer asap – Rick M. Apr 20 '17 at 13:46
  • just updated my answer :) – tgif Apr 21 '17 at 11:35
  • Looks good, may be you should save the results of the unsharpmask into another image. Because to me the output image looks really blurred, which isn't actually helping. Also, try with different kernel sizes and sigma for the `Gaussian Blur` before the `addWeighted`. – Rick M. Apr 21 '17 at 11:49
  • thanks, I have tried with different sizes/sigma and found that sizes between 7-11 all kinda work similar, lower values don't work so well. – tgif Apr 21 '17 at 12:27

1 Answers1

-1

Following discussion in comments, I am posting a general answer with some results I got on the worst case image uploaded by the OP.

Note : The code I am posting is in Python, since it is the fastest for me to write

Step 1. As you ask for a way to crop the image, so as to focus on the eyes only, you might want to look at Face Detection. Since, the image essentially requires to find eyes only, I did the following:

eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
eyes = eye_cascade.detectMultiScale(v) // v is the value channel of the HSV image
// The results "eyes" gives you the dimensions of the rectangle where the eyes are detected as [x, y, w, h]
// Just for drawing 
cv2.rectangle(v, (x1, y1), (x1+w1, y1+h1), (0, 255, 0), 2)
cv2.rectangle(v, (x2, y2), (x2+w2, y2+h2), (0, 255, 0), 2)

The result of Haar Cascade Classifier

Now, once you have the bounding rectangles, you can crop the rectangles from the image like:

crop_eye1 = v[y1:y1+h1, x1:x1+w1]
crop_eye2 = v[y2:y2+h2, x2:x2+w2]

After you obtain the rectangles, I would suggest looking into different color spaces instead of RGB/BGR, HSV/Lab/Luv in particular.

Because the R, G, and B components of an object’s color in a digital image are all correlated with the amount of light hitting the object, and therefore with each other, image descriptions in terms of those components make object discrimination difficult. Descriptions in terms of hue/lightness/chroma or hue/lightness/saturation are often more relevant

Then, once, you have the eyes, its time to equalize the contrast of the image, however, I suggest using CLAHE and play with the parameters for clipLimit and tileGridSize. Here is a code which I implemented a while back in Java:

private static Mat clahe(Mat image, int ClipLimit, Size size){
  CLAHE clahe = Imgproc.createCLAHE();
  clahe.setClipLimit(ClipLimit);
  clahe.setTilesGridSize(size);
  Mat dest_image = new Mat();
  clahe.apply(image, dest_image);
  return dest_image;
}     

Once you are satisfied, you should sharpen the image so that HoughCircle is robust. You should look at unsharpMask. Here is the code in Java for UnsharpMask I implemented in Java:

private static Mat unsharpMask(Mat input_image, Size size, double sigma){

// Make sure the {input_image} is gray.
  Mat sharpend_image = new Mat(input_image.rows(), input_image.cols(), input_image.type());
  Mat Blurred_image = new Mat(input_image.rows(), input_image.cols(), input_image.type());
  Imgproc.GaussianBlur(input_image, Blurred_image, size, sigma);
  Core.addWeighted(input_image, 2.0D, Blurred_image, -1.0D, 0.0D, sharpened_image);
  return sharpened_image;
}

Alternatively, you could use bilateral filter, which is edge preserving smoothing, or read through this for defining a custom kernel for sharpening image. Hope it helps and best of luck!

Rick M.
  • 3,045
  • 1
  • 21
  • 39