What kind of image processing techniques which i can deploy to remove eye lashes and eyebrows from a human eye image?

Question:

I have been trying to process a human eye image to get the dimensions of iris for the past month. I used this image as my input and somewhat I was able to achieve what I was trying to do but still not efficient when it comes to detecting contours and getting my region of interest(Iris).

Input

The potential reason behind it is, since the human eye images contains eyebrows and eye lashes which are generally dark and when I apply thresholding on it, they get included during canny processing and when I try to draw contours on them, they are interfering my region of interest i.e., iris and they return a whole mess of a region —>

contours

which I’m quite unsure how to obtain the ROI from it. So I tried not to use contours instead I went for Hough circles but they results are not acceptable since irises are not perfect circles rather ellipses.

Contouring seems like the best option since I can easily draw a bounding box over a contour and get its dimensions but my image processing knowledge is limited and I need to find a way to remove all the noise and artifacts to get the ROI i.e., Human Iris

So my questions is: What kind of image processing techniques which I can deploy to remove eye lashes and eyebrows from a human eye image?

Alternative question: How can I extract my region of interest (Human Iris) from my already processed image? Processed Image:

processed image

Reason: When I try to obtain the contours from the image, the unwanted eyebrows/eyelashes are interfering with my region of interest(iris) so the ROI is often merged with the eyebrows/eyelashes which I find difficult to process/remove in order to calculate the iris dimensions.

Here is the code:


#Libraries
import cv2
import numpy as np

#show image
def display_image(name,current_image):
    cv2.imshow(name,current_image)
    cv2.waitKey(0)

def image_processing(current_image):
    
    
    #Grayscaling
    grayscaled_image = cv2.cvtColor(current_image, cv2.COLOR_BGR2GRAY)
    #display_image("Gray",grayscaled_image)

    #Inverting
    inverted_image = cv2.bitwise_not(grayscaled_image)
    #display_image("Invert",inverted_image)

    #Removing Reflection
    kernel = np.ones((5, 5), np.uint8)
    blackhat_image = cv2.morphologyEx(inverted_image,cv2.MORPH_BLACKHAT,kernel)
    #display_image("Backhat",blackhat_image)

    removed_refection = cv2.addWeighted(src1=inverted_image,alpha=0.5,src2=blackhat_image,beta=0.5,gamma=0)
    #display_image("Removed reflection",removed_refection)

    image_without_reflection =  cv2.medianBlur(removed_refection, 5)
    #display_image("No reflection",image_without_reflection)

    #Thresholding
    _,thresholded_image= cv2.threshold(image_without_reflection,100,255,cv2.THRESH_BINARY)
    #display_image("Thresholded",thresholded_image)

    #Canny
    region_of_interest = cv2.bitwise_not(thresholded_image)
    canny_image = cv2.Canny(region_of_interest, 200, 100)

    return canny_image

def iris_detection(image):
    
    
    circles = cv2.HoughCircles(processed_image, cv2.HOUGH_GRADIENT, 1, 20, param1 = 200, param2 = 20, minRadius = 0)
    
    if circles is not None:
        
        #fifth step mark circles co-ordinates
        inner_circle = np.uint16(np.around(circles[0][0])).tolist()
        cv2.circle(current_image, (inner_circle[0], inner_circle[1]), inner_circle[2], (0, 255, 0), 1)
        display_image("Final",current_image)
        x, y,_ = current_image.shape
        
    radius = inner_circle[2]*0.2645833333
    diameter = radius * 2

    print("The Radius of the iris is:",radius,"mm")
    print("The Diameter of the iris is:",diameter,"mm")
    
def contour_detection(image):
    
    #Countours are less effective
    contours,hierarchy = cv2.findContours(image,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    return cv2.drawContours(new_image, contours, -1, (0,255,0), 3)
    
    
#input
current_image = cv2.imread("eye.jpg", 1)
display_image("Original",current_image)

#Copy of the original image
new_image = current_image.copy()

#Image pre-processing
processed_image = image_processing(current_image)
display_image("Processed Image",processed_image)

#Iris Detection using Hough circles
iris_detection(processed_image)
contoured_image = contour_detection(processed_image)
display_image("Contours",contoured_image)


cv2.destroyAllWindows() 
Asked By: Sivadithiyan

||

Answers:

In the meantime, i came up with my own solution which gave me the best results.. There might be some advanced image processing functions but the simplest way to go about this was masking the region of interest over a blank image

My solution was to apply a mask slightly larger than the radius found using the HoughCircles function and replacing the background to a color of choice. Here I masked the background to white so I can work with the darker iris region later. Essentially removing things like eyelashes and eyebrows which are interfering during post processing.

white_image = np.full((img.shape[0], img.shape[1]), 255, dtype=np.uint8)
cv2.circle(white_image, (inner_circle[0], inner_circle[1]), inner_circle[2]+30, (0, 0, 0), -1)
roi = cv2.bitwise_or(median,white_image)
#median is the processed binary image
Answered By: Sivadithiyan