[Python] Cyclorotation from eye iris images

Discussão em 'Python' iniciado por Stack, Julho 21, 2025.

  1. Stack

    Stack Membro Participativo

    How can i find the cyclorotation from eye? I have two images: reference_image, test_image.

    I already get the iris using a mask to crop iris region from image. How can i compare two regions mask from reference and test image to find the iris rotation/eye rotation? I made this code below, but its not returning the correct angle. Always 0.5 degress.

    def extract_ellipse_region(image, ellipse, output_size=(200, 200)):
    """Extrai a região da elipse da imagem."""
    mask = np.zeros_like(image if len(image.shape) == 2 else image[:, :, 0])
    cv2.ellipse(mask, ellipse, 255, -1)

    # Aplica máscara
    result = cv2.bitwise_and(image, image, mask=mask)

    # Recorta a região da elipse
    x, y, w, h = cv2.boundingRect(cv2.ellipse2Poly((int(ellipse[0][0]), int(ellipse[0][1])),
    (int(ellipse[1][0] / 2), int(ellipse[1][1] / 2)),
    int(ellipse[2]), 0, 360, 1))
    crop = result[y:y+h, x:x+w]

    # Redimensiona
    crop_resized = cv2.resize(crop, output_size)
    return crop_resized




    def get_rotation_angle_from_region(img_ref, img_surgery, mask_ref, mask_surgery, debug=False):
    contours_ref, _ = cv2.findContours(mask_ref, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours_surg, _ = cv2.findContours(mask_surgery, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    if len(contours_ref) == 0 or len(contours_surg) == 0:
    print("Nenhum contorno detectado.")
    return None

    contour_ref = max(contours_ref, key=cv2.contourArea)
    contour_surg = max(contours_surg, key=cv2.contourArea)

    ellipse_ref = cv2.fitEllipse(contour_ref)
    ellipse_surg = cv2.fitEllipse(contour_surg)

    crop_ref = extract_ellipse_region(img_ref, ellipse_ref)
    crop_surg = extract_ellipse_region(img_surgery, ellipse_surg)

    # Converte para tons de cinza
    gray_ref = cv2.cvtColor(crop_ref, cv2.COLOR_BGR2GRAY) if len(crop_ref.shape) == 3 else crop_ref
    gray_surg = cv2.cvtColor(crop_surg, cv2.COLOR_BGR2GRAY) if len(crop_surg.shape) == 3 else crop_surg

    # Aplica adaptiveThreshold invertido
    thresh_ref = cv2.adaptiveThreshold(gray_ref, 255,
    cv2.ADAPTIVE_THRESH_MEAN_C,
    cv2.THRESH_BINARY_INV,
    blockSize=55,
    C=2)

    thresh_surg = cv2.adaptiveThreshold(gray_surg, 255,
    cv2.ADAPTIVE_THRESH_MEAN_C,
    cv2.THRESH_BINARY_INV,
    blockSize=55,
    C=2)

    best_angle = 0
    best_score = -np.inf
    best_rotated = None

    cv2.imshow("ref", thresh_ref)
    cv2.imshow("refsurg", thresh_surg)

    for angle in np.linspace(-30, 30, 121): # de -30° a 30° com passo de 0.5°
    (center_x, center_y) = (crop_surg.shape[1] // 2, crop_surg.shape[0] // 2)
    M = cv2.getRotationMatrix2D((center_x, center_y), angle, 1.0)
    rotated = cv2.warpAffine(thresh_surg, M, (crop_surg.shape[1], crop_surg.shape[0]))

    result = cv2.matchTemplate(rotated, thresh_ref, cv2.TM_CCOEFF_NORMED)
    score = result[0][0]

    if score > best_score:
    best_score = score
    best_angle = angle
    best_rotated = rotated

    if debug:
    print(f"Melhor ângulo estimado: {best_angle:.2f}° | Score: {best_score:.3f}")
    cv2.imshow("Ref adaptThresh", thresh_ref)
    cv2.imshow("Surg best match", best_rotated)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    return best_angle

    Continue reading...

Compartilhe esta Página