- Aruco: fixed multidetection

This commit is contained in:
2025-11-30 20:00:12 +01:00
parent 5c2270f1ef
commit f73bcfeae6
74 changed files with 52 additions and 62 deletions
+18 -24
View File
@@ -5,37 +5,35 @@ import numpy as np
RESULTS_FOLDER = "results" RESULTS_FOLDER = "results"
class BoardDetector(abc.ABC): class BoardDetector(abc.ABC):
name = None
ids = None
mtx = None
dist = None
r_vecs = None
t_vecs = None
obj_points_list = []
img_points_list = []
board_id = None
def __repr__(self): def __repr__(self):
return self.name return self.name
def __init__(self, name: str, board_id: str, n_syms: int): def __init__(self, name: str, board_id: str, n_syms: int):
self.mtx = None
self.dist = None
self.r_vecs = None
self.t_vecs = None
self.name = name self.name = name
self.obj_points_list = []
self.img_points_list = []
self.board_id = board_id self.board_id = board_id
# Create IDs
offset = int(board_id)*n_syms offset = int(board_id)*n_syms
self.ids = np.array([x + offset for x in range(n_syms)]) self.ids = np.array([x + offset for x in range(n_syms)])
print(f"{self.name}: markers: {self.ids}")
def match_ids(self, ids: np.array): def match_ids(self, corners_in, ids_in: np.array):
corners = ()
ids = []
offset = int(self.board_id) * len(self.ids) offset = int(self.board_id) * len(self.ids)
if ids is None: if ids_in is not None:
return False for n in range(len(ids_in)):
if ((ids_in[n] - offset) >= 0) and ((ids_in[n] - offset) < len(self.ids)):
temp = corners_in[n]
corners += (temp,)
ids.append(ids_in[n])
for n in range(len(ids)): return corners, np.array(ids)
if (ids[n] - offset) < 0:
return False
if (ids[n] - offset) > len(self.ids):
return False
return True
@abc.abstractmethod @abc.abstractmethod
def get_board_name(self) -> str: def get_board_name(self) -> str:
@@ -87,15 +85,11 @@ class BoardDetector(abc.ABC):
ret, mtx, dist, r_vecs, t_vecs = cv.calibrateCamera(self.obj_points_list, self.img_points_list, image.shape, self.mtx, self.dist, ret, mtx, dist, r_vecs, t_vecs = cv.calibrateCamera(self.obj_points_list, self.img_points_list, image.shape, self.mtx, self.dist,
rvecs=r_vecs, tvecs=t_vecs, flags=flags) rvecs=r_vecs, tvecs=t_vecs, flags=flags)
print(f"Camera calibration finished: ", end='')
if ret < 3: if ret < 3:
print(f"Success ({ret})!")
success = True success = True
self.mtx = mtx self.mtx = mtx
self.dist = dist self.dist = dist
self.r_vecs = r_vecs self.r_vecs = r_vecs
self.t_vecs = t_vecs self.t_vecs = t_vecs
else:
print(f"Failed ({ret})!")
return success return success
+26 -29
View File
@@ -35,17 +35,16 @@ class BoardDetectorAruco(BoardDetector):
success = False success = False
obj_points = None obj_points = None
img_points = None img_points = None
corners, ids, _ = self.detector.detectMarkers(image)
if not self.match_ids(ids):
return False, None, None
if corners is not None: corners, ids, _ = self.detector.detectMarkers(image)
if len(ids) >= len(self.board.getIds()): corners, ids = self.match_ids(corners, ids)
_obj_points, _img_points = self.board.matchImagePoints(corners, ids)
if len(_obj_points) > 0 and len(_img_points) > 0: if len(ids) >= len(self.board.getIds()):
success =True _obj_points, _img_points = self.board.matchImagePoints(corners, ids)
obj_points = _obj_points if len(_obj_points) > 0 and len(_img_points) > 0:
img_points = _img_points success = True
obj_points = _obj_points
img_points = _img_points
return success, obj_points, img_points return success, obj_points, img_points
@@ -55,30 +54,28 @@ class BoardDetectorAruco(BoardDetector):
t_vec = None t_vec = None
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
(corners, ids, rejected) = self.detector.detectMarkers(gray) corners, ids, rejected = self.detector.detectMarkers(gray)
corners, ids = self.match_ids(corners, ids)
# Draw a square around the markers if len(ids) > 0:
if draw_marker_box: # Draw a square around the markers
cv.aruco.drawDetectedMarkers(image, corners) if draw_marker_box:
cv.aruco.drawDetectedMarkers(image, corners)
# Draw marker id # Draw marker id
if draw_marker_id: if draw_marker_id:
cv.aruco.drawDetectedMarkers(image, corners, ids) cv.aruco.drawDetectedMarkers(image, corners, ids)
if not self.is_calibrated(): if not self.is_calibrated():
return pose, None, None return pose, None, None
if not self.match_ids(ids): # Draw marker axis
return pose, None, None if draw_marker_axis:
_r_vecs, _t_vecs, _ = cv.aruco.estimatePoseSingleMarkers(corners, markerLength=0.1, cameraMatrix=self.mtx, distCoeffs=self.dist)
if _r_vecs is not None:
for i in range(len(_r_vecs)):
cv.drawFrameAxes(image, self.mtx, self.dist, _r_vecs[i], _t_vecs[i], 0.05)
# Draw marker axis
if draw_marker_axis:
_r_vecs, _t_vecs, _ = cv.aruco.estimatePoseSingleMarkers(corners, markerLength=0.1, cameraMatrix=self.mtx, distCoeffs=self.dist)
if _r_vecs is not None:
for i in range(len(_r_vecs)):
cv.drawFrameAxes(image, self.mtx, self.dist, _r_vecs[i], _t_vecs[i], 0.05)
if len(corners) > 0:
# Estimate pose of each marker and return the values r_vec and t_vec---(different from those of camera coefficients) # Estimate pose of each marker and return the values r_vec and t_vec---(different from those of camera coefficients)
obj_points, img_points = self.board.matchImagePoints(corners, ids) obj_points, img_points = self.board.matchImagePoints(corners, ids)
pose, r_vec, t_vec = cv.solvePnP(obj_points, img_points, self.mtx, self.dist, rvec=r_vecs, tvec=t_vecs) pose, r_vec, t_vec = cv.solvePnP(obj_points, img_points, self.mtx, self.dist, rvec=r_vecs, tvec=t_vecs)
+8 -9
View File
@@ -61,11 +61,11 @@ class Detector(abc.ABC):
name = det.get_board_name() name = det.get_board_name()
cv.imwrite(f"{RESULTS_FOLDER}/{name}.png", image) cv.imwrite(f"{RESULTS_FOLDER}/{name}.png", image)
def calibrate_save(self): @staticmethod
for det in self.detector: def calibrate_save(det: BoardDetector):
filename = f"{RESULTS_FOLDER}/{det.get_board_name()}_cal.npz" filename = f"{RESULTS_FOLDER}/{det.get_board_name()}_cal.npz"
mtx, dist, r_vecs, t_vecs = det.calibration_get() mtx, dist, r_vecs, t_vecs = det.calibration_get()
np.savez(f"{filename}", mtx=mtx, dist=dist, rvecs=r_vecs, tvecs=t_vecs) np.savez(f"{filename}", mtx=mtx, dist=dist, rvecs=r_vecs, tvecs=t_vecs)
def calibrate_load(self): def calibrate_load(self):
for det in self.detector: for det in self.detector:
@@ -127,13 +127,12 @@ class Detector(abc.ABC):
success = det.collect_points(gray) success = det.collect_points(gray)
if success: if success:
print(f"{det}: Points matching success") print(f"{det}: Points matching success")
else:
print(f"{det}: Points matching failed, try again")
elif k == ord('c'): elif k == ord('c'):
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
for det in self.detector: for det in self.detector:
det.calibrate_camera(gray) if det.calibrate_camera(gray):
self.calibrate_save() print(f"{det}: Camera calibration success")
self.calibrate_save(det)
elif k == ord('x'): elif k == ord('x'):
for det in self.detector: for det in self.detector:
det.calibration_clear() det.calibration_clear()
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB