How to remove reflections when wearing glasses in order to detect the eye directions correctly

Can anyone help, I am working on an eye detection project, to detect the directions of the pupil, say left or right, it works well but whenever I use glasses it glitches, it starts to detect the pupil directions wrongly…

Here is my code below:
#for the iris(eye) detection
def iris_size(gray):
#return the percentage of space that the iris takes up on the
#surface of the eye
eye_space = gray[5:-5, 5:-5]
height, width = eye_space.shape[:2]
nb_pixels = height * width
nb_blacks = nb_pixels - cv2.countNonZero(eye_space)
return nb_blacks / nb_pixels

def image_processing(eye_frame, threshold):
#perform operations on the eye frame to isolate the iris
kernel = np.ones((3, 3), np.uint8)
new_frame = cv2.bilateralFilter(gray, 10, 15, 15)
new_frame = cv2.erode(new_frame, kernel, iterations=3)
new_frame = cv2.threshold(new_frame, threshold, 255, cv2.THRESH_BINARY)[1]
return new_frame

def find_best_threshold_value(gray):
#calibrate the pupil detection algorithm by finding the best
#binarization threshold value for the person
avg_iris_size = 0.48
trials = {}
#keep adjusting till we find the best threshold that fits the current environment
for threshold in range(5, 100, 5):
    iris_frame = image_processing(gray, threshold)
    trials[threshold] = iris_size(iris_frame)
best_threshold = min(trials.items(), key=(lambda p: abs(p[1] - avg_iris_size)))[0]
return best_threshold
#get eye movements
def get_gaze_ratio(eye_points, facial_landmarks):
eye_region = np.array([(facial_landmarks.part(eye_points[0]).x, facial_landmarks.part(eye_points[0]).y),
                       (facial_landmarks.part(eye_points[1]).x, facial_landmarks.part(eye_points[1]).y),
                       (facial_landmarks.part(eye_points[2]).x, facial_landmarks.part(eye_points[2]).y),
                       (facial_landmarks.part(eye_points[3]).x, facial_landmarks.part(eye_points[3]).y),
                       (facial_landmarks.part(eye_points[4]).x, facial_landmarks.part(eye_points[4]).y),
                       (facial_landmarks.part(eye_points[5]).x, facial_landmarks.part(eye_points[5]).y)], np.int32)

#Create a mask(a black screen/frame) to get only the eye
height, width = gray.shape[:2]
black_frame = np.zeros((height, width), np.uint8)
    
mask = np.full((height, width), 255, np.uint8)
#cv2.polylines(mask, [eye_region], True, 255, 2)
cv2.fillPoly(mask, [eye_region], (0, 0, 0))
    
#working with both eyes taking left eye into consideration
eye = cv2.bitwise_not(black_frame, gray.copy(), mask = mask)

#slicing the eye into portions and cropping it
min_x = np.min(eye_region[:, 0])
max_x = np.max(eye_region[:, 0])
min_y = np.min(eye_region[:, 1])
max_y = np.max(eye_region[:, 1])

gray_frame_eye = eye[min_y: max_y, min_x: max_x]
#add blur to reduce noise including fluctuations when a user is wearing glasses
blur_eye = cv2.GaussianBlur(gray_frame_eye, (7, 7), 0)
_, threshold_eye = cv2.threshold(blur_eye, thres_best, 255, cv2.THRESH_BINARY)

#height and width of both the left and right eye
height, width = threshold_eye.shape[:2]
#eye threshold
left_side_threshold = threshold_eye[0: height, 0: int(width / 2)]
#get only the white part of the eye(255)
left_side_white = cv2.countNonZero(left_side_threshold)
    
right_side_threshold = threshold_eye[0: height, int(width / 2): width]
right_side_white = cv2.countNonZero(right_side_threshold)
gaze_ratio = left_side_white / right_side_white
return gaze_ratio

What if you try to remove the reflection source? (like the light source in front of the glasses)
For example avoid using the integrated webcam of a laptop, prefer using an external webcam, with no frontal light. Of course this depends on the application, it can’t be used in a car for example.

Fantastic! but I have to use the integrated webcam for this application, Is there any way to reduce the reflection on the glass… because this application will be used in conferences where you have different sources of light

Use a polarizing filter over the webcam, if possible.
The light from the screen is polarized, so a polarizing filter oriented at 90° will filter all the reflections.

1 Like