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[i], 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.