44import math
55import time
66from pathlib import Path
7+ from typing import Any , cast
78
89import cv2
910import numpy as np
@@ -29,51 +30,55 @@ def _starting_index(out_dir: Path, prefix: str, ext: str) -> int:
2930def _dict_by_name (name : str ):
3031 if not hasattr (cv2 , "aruco" ):
3132 raise RuntimeError ("cv2.aruco is required for charuco" )
32- code = getattr (cv2 .aruco , str (name ).strip ().upper (), None )
33+ aruco = cast (Any , cv2 .aruco )
34+ code = getattr (aruco , str (name ).strip ().upper (), None )
3335 if code is None :
3436 raise ValueError (f"unsupported aruco dictionary: { name } " )
35- return cv2 . aruco .getPredefinedDictionary (int (code ))
37+ return aruco .getPredefinedDictionary (int (code ))
3638
3739
3840def _make_charuco_board (cols : int , rows : int , marker_ratio : float , dict_name : str ):
41+ aruco = cast (Any , cv2 .aruco )
3942 dictionary = _dict_by_name (dict_name )
4043 sx = int (cols ) + 1
4144 sy = int (rows ) + 1
4245 mr = float (marker_ratio )
4346 if mr <= 0.0 or mr >= 1.0 :
4447 raise ValueError ("marker-ratio must be in (0, 1)" )
45- if hasattr (cv2 . aruco , "CharucoBoard" ):
46- board = cv2 . aruco .CharucoBoard ((sx , sy ), 1.0 , mr , dictionary )
48+ if hasattr (aruco , "CharucoBoard" ):
49+ board = aruco .CharucoBoard ((sx , sy ), 1.0 , mr , dictionary )
4750 else :
48- board = cv2 . aruco .CharucoBoard_create (sx , sy , 1.0 , mr , dictionary )
51+ board = aruco .CharucoBoard_create (sx , sy , 1.0 , mr , dictionary )
4952 return board , dictionary
5053
5154
5255def _make_aruco_detector (dictionary ):
56+ aruco = cast (Any , cv2 .aruco )
5357 params = None
54- if hasattr (cv2 . aruco , "DetectorParameters" ):
55- params = cv2 . aruco .DetectorParameters ()
56- elif hasattr (cv2 . aruco , "DetectorParameters_create" ):
57- params = cv2 . aruco .DetectorParameters_create ()
58- if hasattr (cv2 . aruco , "ArucoDetector" ) and params is not None :
59- return cv2 . aruco .ArucoDetector (dictionary , params ), params
58+ if hasattr (aruco , "DetectorParameters" ):
59+ params = aruco .DetectorParameters ()
60+ elif hasattr (aruco , "DetectorParameters_create" ):
61+ params = aruco .DetectorParameters_create ()
62+ if hasattr (aruco , "ArucoDetector" ) and params is not None :
63+ return aruco .ArucoDetector (dictionary , params ), params
6064 return None , params
6165
6266
6367def _detect_markers (gray : np .ndarray , dictionary , detector , detector_params ):
68+ aruco = cast (Any , cv2 .aruco )
6469 if detector is not None :
6570 return detector .detectMarkers (gray )
6671 if detector_params is None :
67- return cv2 . aruco .detectMarkers (gray , dictionary )
68- return cv2 . aruco .detectMarkers (gray , dictionary , parameters = detector_params )
72+ return aruco .detectMarkers (gray , dictionary )
73+ return aruco .detectMarkers (gray , dictionary , parameters = detector_params )
6974
7075
7176def _detect_checkerboard (gray : np .ndarray , pattern_size : tuple [int , int ]) -> tuple [bool , np .ndarray | None ]:
7277 found , corners = cv2 .findChessboardCornersSB (gray , pattern_size , None )
7378 if found and corners is not None :
7479 return True , corners
7580 flags = cv2 .CALIB_CB_ADAPTIVE_THRESH + cv2 .CALIB_CB_NORMALIZE_IMAGE + cv2 .CALIB_CB_FAST_CHECK
76- found2 , corners2 = cv2 .findChessboardCorners (gray , pattern_size , flags )
81+ found2 , corners2 = cv2 .findChessboardCorners (gray , pattern_size , None , flags )
7782 if not found2 or corners2 is None :
7883 return False , None
7984 criteria = (cv2 .TERM_CRITERIA_EPS + cv2 .TERM_CRITERIA_MAX_ITER , 40 , 0.001 )
@@ -89,17 +94,18 @@ def _detect_charuco(
8994 detector_params ,
9095 min_corners : int ,
9196) -> tuple [bool , np .ndarray | None , np .ndarray | None , tuple ]:
97+ aruco = cast (Any , cv2 .aruco )
9298 corners , ids , rejected = _detect_markers (gray , dictionary , detector , detector_params )
9399 if ids is None or len (ids ) <= 0 :
94100 return False , None , None , (corners , ids , rejected )
95- if hasattr (cv2 . aruco , "refineDetectedMarkers" ):
101+ if hasattr (aruco , "refineDetectedMarkers" ):
96102 try :
97- refined = cv2 . aruco .refineDetectedMarkers (gray , board , corners , ids , rejected )
103+ refined = aruco .refineDetectedMarkers (gray , board , corners , ids , rejected )
98104 if isinstance (refined , tuple ) and len (refined ) >= 3 :
99105 corners , ids , rejected = refined [0 ], refined [1 ], refined [2 ]
100106 except Exception :
101107 pass
102- retval , charuco_corners , charuco_ids = cv2 . aruco .interpolateCornersCharuco (corners , ids , gray , board )
108+ retval , charuco_corners , charuco_ids = aruco .interpolateCornersCharuco (corners , ids , gray , board )
103109 if retval is None or float (retval ) < float (min_corners ) or charuco_corners is None or charuco_ids is None :
104110 return False , None , None , (corners , ids , rejected )
105111 return True , charuco_corners , charuco_ids , (corners , ids , rejected )
@@ -229,9 +235,9 @@ def main() -> None:
229235 )
230236 marker_corners , marker_ids , _ = marker_pack
231237 if marker_ids is not None and len (marker_ids ) > 0 :
232- cv2 .aruco .drawDetectedMarkers (vis , marker_corners , marker_ids )
238+ cast ( Any , cv2 .aruco ) .drawDetectedMarkers (vis , marker_corners , marker_ids )
233239 if found and cc is not None and ci is not None :
234- cv2 .aruco .drawDetectedCornersCharuco (vis , cc , ci , (0 , 255 , 0 ))
240+ cast ( Any , cv2 .aruco ) .drawDetectedCornersCharuco (vis , cc , ci , (0 , 255 , 0 ))
235241 points = cc
236242 else :
237243 found , corners = _detect_checkerboard (gray , pattern )
0 commit comments