Owleye / codes /base /iris_lm_depth.py
owleyetracker's picture
Upload 45 files
b4c5d36 verified
import os
import cv2
import numpy as np
from codes.base.core import (
detections_to_rect,
landmarks_to_detections,
slice_from_roi,
tflite_inference,
transform_rect,
)
PATH2ROOT_ABS = os.path.dirname(__file__) + "/../../"
def from_landmarks_to_depth(
frame_rgb, eye_landmarks, image_size, is_right_eye=False, focal_length=None
):
"""
Predicting the iris position using eyes landmarks
Parameters:
frame_rgb: the frame (RGB)
eye_landmarks: the landmarks of the eyes
image_size: the image size
is_right_eye: whether or not it's the right eye
focal_length: the focal length of the camera
Returns:
success: whether or not the iris is detected
depth: distance to the camera
iris_size: the size of the iris
iris_landmarks: iris landmarks
eye_contours: eye contours
iris_landmarks_respect: iris landmarks respect to the eyes
"""
if focal_length is None:
focal_length = frame_rgb.shape[1]
detections = landmarks_to_detections(eye_landmarks)
rect = detections_to_rect(detections, image_size, rotation_vector_start_end=(0, 1))
roi = transform_rect(rect, image_size, scale_x=2.3, scale_y=2.3)
slice_y = slice_from_roi(roi, image_size, False)
slice_x = slice_from_roi(roi, image_size, True)
eye_image = frame_rgb[slice(*slice_y), slice(*slice_x), :]
position_in_frame = np.array((slice_x[0], slice_y[0], 0))
if eye_image.any():
success = True
eye_contours, iris_landmarks, eye_frame_low = detect_iris(
eye_image.copy(), is_right_eye=is_right_eye
)
iris_landmarks_respect = iris_landmarks.copy()
eye_contours[:, 0] = eye_contours[:, 0] * eye_image.shape[0]
eye_contours[:, 1] = eye_contours[:, 1] * eye_image.shape[1]
eye_contours = eye_contours + position_in_frame
eye_contours[:, 0] = eye_contours[:, 0] / frame_rgb.shape[1]
eye_contours[:, 1] = eye_contours[:, 1] / frame_rgb.shape[0]
iris_landmarks[:, 0] = iris_landmarks[:, 0] * eye_image.shape[0]
iris_landmarks[:, 1] = iris_landmarks[:, 1] * eye_image.shape[1]
iris_landmarks = iris_landmarks + position_in_frame
iris_landmarks[:, 0] = iris_landmarks[:, 0] / frame_rgb.shape[1]
iris_landmarks[:, 1] = iris_landmarks[:, 1] / frame_rgb.shape[0]
depth, iris_size = calculate_iris_depth(iris_landmarks, image_size, focal_length)
else:
success = False
depth = None
iris_size = None
iris_landmarks = None
eye_contours = None
iris_landmarks_respect = None
return success, depth, iris_size, iris_landmarks, eye_contours, iris_landmarks_respect
def detect_iris(eye_frame, is_right_eye=False):
side_low = 64
eye_frame_low = cv2.resize(
eye_frame, (side_low, side_low), interpolation=cv2.INTER_AREA
)
model_path = PATH2ROOT_ABS + "models/iris/iris_landmark.tflite"
if is_right_eye:
eye_frame_low = np.fliplr(eye_frame_low)
outputs = tflite_inference(eye_frame_low / 127.5 - 1.0, model_path)
eye_contours_low = np.reshape(outputs[0], (71, 3))
iris_landmarks_low = np.reshape(outputs[1], (5, 3))
eye_contours = eye_contours_low / side_low
iris_landmarks = iris_landmarks_low / side_low
if is_right_eye:
eye_contours[:, 0] = 1 - eye_contours[:, 0]
iris_landmarks[:, 0] = 1 - iris_landmarks[:, 0]
return eye_contours, iris_landmarks, eye_frame_low
def calculate_iris_depth(iris_landmarks, image_size, focal_length_pixel):
"""
iris_landmarks should be normalized to the complete image frame
depth in mm
"""
iris_size = calculate_iris_diameter(iris_landmarks, image_size)
depth = calculate_depth(
iris_landmarks[0, :], focal_length_pixel, iris_size, image_size
)
return depth, iris_size
def get_depth(x0, y0, x1, y1):
return np.sqrt((x0 - x1) ** 2 + (y0 - y1) ** 2)
def get_landmark_depth(ld0, ld1, image_size):
return get_depth(
ld0[0] * image_size[0],
ld0[1] * image_size[1],
ld1[0] * image_size[0],
ld1[1] * image_size[1],
)
def calculate_iris_diameter(iris_landmarks, image_size):
dist_vert = get_landmark_depth(
iris_landmarks[1, :], iris_landmarks[3, :], image_size
)
dist_hori = get_landmark_depth(
iris_landmarks[2, :], iris_landmarks[4, :], image_size
)
return (dist_hori + dist_vert) / 2.0
def calculate_depth(center_landmark, focal_length_pixel, iris_size, image_size):
# Average fixed iris size across human beings.
human_iris_size_in_mm = 11.8
origin = np.array(image_size) / 2.0
center_landmark_pixel = center_landmark[:2] * np.array(image_size)
y = get_depth(
origin[0], origin[1], center_landmark_pixel[0], center_landmark_pixel[1]
)
x = np.sqrt(focal_length_pixel ** 2 + y ** 2)
depth = human_iris_size_in_mm * x / iris_size
return depth