[Python] Aruco Code Pose Estimation - SolvePnP issues

Discussão em 'Python' iniciado por Stack, Fevereiro 6, 2025.

  1. Stack

    Stack Membro Participativo

    I'm currently working on ArUco Code Pose Estimation using OpenCV's library. Due to using the latest OpenCV version (4.8.1.78), I've encountered limitations with most of the functions commonly used in tutorials and GitHub repositories. I'm attempting to perform pose estimation utilizing solvePnP. The translation and rotation vectors provided by this method should represent the pose of the ArUco code in relation to the camera. To verify this, I'm displaying these vectors on each frame.

    However, upon reviewing the video output, I'm noticing that the frame isn't correctly aligned with the ArUco code; instead, it's displayed somewhere in space at the bottom left corner of the frames.

    I've thoroughly reviewed my code but haven't been able to identify the issue. The markers are detected accurately, but the pose estimation doesn't seem to yield the expected results. Any insights or guidance on resolving this discrepancy would be greatly appreciated.

    from utils import ARUCO_DICT, aruco_display
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    import csv


    def detect_aruco(camera, video, type, output_video_path, marker_size):
    if camera:
    video_capture = cv2.VideoCapture(0)
    cv2.waitKey(2000)
    else:
    if video is None:
    print("[Error] Video file location is not provided")
    return

    video_capture = cv2.VideoCapture(video)

    if type not in ARUCO_DICT:
    print(f"ArUCo tag type '{type}' is not supported")
    return

    aruco_dict = cv2.aruco.getPredefinedDictionary(ARUCO_DICT[type])
    aruco_params = cv2.aruco.DetectorParameters()


    fourcc = cv2.VideoWriter.fourcc(*'mp4v')
    output_width = int(video_capture.get(cv2.CAP_PROP_FRAME_WIDTH))
    output_height = int(video_capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
    output_video = cv2.VideoWriter(output_video_path, fourcc, 20.0, (output_width, output_height))

    all_tvecs = []
    all_rvecs = []

    while True:
    ret, frame = video_capture.read()
    print(ret)

    if not ret:
    false_count += 1
    if false_count >= 2:
    break # If 'ret' is False twice consecutively, exit the loop
    continue # Skip to the next frame

    # Reset false_count if 'ret' is True
    false_count = 0

    h, w, _ = frame.shape
    width = 1000
    height = int(width * (h / w))
    frame = cv2.resize(frame, (width, height), interpolation=cv2.INTER_CUBIC)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    corners, ids, rejected = cv2.aruco.detectMarkers(gray, aruco_dict)
    detected_markers = aruco_display(corners, ids, rejected, frame)

    markerPoints = np.array([[0, 0, 0],
    [marker_size, 0, 0],
    [marker_size, marker_size, 0],
    [0, marker_size, 0]], dtype=np.float32)

    if np.all(ids is not None):
    for i in range(0, len(ids)):
    trash, rvec, tvec = cv2.solvePnP(markerPoints, corners, camera_matrix,
    distortion_coefficients, False, cv2.SOLVEPNP_IPPE_SQUARE)


    all_tvecs.append(tvec)
    all_rvecs.append(rvec)

    cv2.aruco.drawDetectedMarkers(frame, corners)
    cv2.drawFrameAxes(frame, camera_matrix, distortion_coefficients, np.array(rvec), np.array(tvec), 0.1)

    cv2.imshow("Image", detected_markers)

    key = cv2.waitKey(1) & 0xFF
    if key == ord("q"):
    break

    cv2.destroyAllWindows()
    video_capture.release()
    output_video.release()

    return all_tvecs


    Thank you for any suggestions!

    I did check the camera calibration process but couldt find any issues.

    Continue reading...

Compartilhe esta Página