added aruco generate and detect

This commit is contained in:
2025-11-24 14:24:19 +01:00
parent 4ea570e2ab
commit 86f70372ae
6 changed files with 171 additions and 5 deletions
+1
View File
@@ -1 +1,2 @@
results/
__pycache__/
+4
View File
@@ -1,2 +1,6 @@
# Checker board
https://docs.opencv.org/4.x/d6/d55/tutorial_table_of_content_calib3d.html
https://docs.opencv.org/4.x/d9/db7/tutorial_py_table_of_contents_calib3d.html
# Aruco
https://docs.opencv.org/4.x/d2/d64/tutorial_table_of_content_objdetect.html
+85
View File
@@ -0,0 +1,85 @@
import argparse
import cv2
import sys
import cv2.aruco
from aruco_types import ARUCO_DICT
def im_resize(image, new_width: int):
# Define new width while maintaining the aspect ratio
aspect_ratio = new_width / image.shape[0]
new_height = int(image.shape[1] * aspect_ratio) # Compute height based on aspect ratio
image = cv2.resize(image, (new_width, new_height))
return image
def factory(aruco_type: int) -> cv2.aruco.ArucoDetector:
aruco_dict = cv2.aruco.getPredefinedDictionary(aruco_type)
aruco_params = cv2.aruco.DetectorParameters()
aruco_detector = cv2.aruco.ArucoDetector(aruco_dict, aruco_params)
return aruco_detector
def process_video(aruco_detector: cv2.aruco.ArucoDetector):
# Open camera
video = cv2.VideoCapture(0)
if not video.isOpened():
print("Cannot open camera")
exit()
while True:
# Read a new frame
ok, img = video.read()
if not ok:
return
process(aruco_detector, img)
k = cv2.waitKey(1) & 0xFF
if k == ord('q'):
break
def process_still(aruco_detector, filename: str):
image = cv2.imread(filename)
image = im_resize(image, 600)
process(aruco_detector, image)
k = cv2.waitKey(-1) & 0xFF
def process(aruco_detector, img):
(corners, ids, rejected) = aruco_detector.detectMarkers(img)
img = cv2.aruco.drawDetectedMarkers(img, corners, ids)
cv2.imshow("Image", img)
def main():
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image",
help="path to input image containing ArUCo tag")
ap.add_argument("-t", "--type", type=str,
default="DICT_ARUCO_ORIGINAL",
help="type of ArUCo tag to detect")
args = vars(ap.parse_args())
# verify that the supplied ArUCo tag exists and is supported by
# OpenCV
if ARUCO_DICT.get(args["type"], None) is None:
print("[INFO] ArUCo tag of '{}' is not supported".format(
args["type"]))
sys.exit(0)
# load the ArUCo dictionary, grab the ArUCo parameters, and detect
# the markers
print("[INFO] detecting '{}' tags...".format(args["type"]))
aruco_detector = factory(ARUCO_DICT[args["type"]])
# load the input image from disk and resize it
print("[INFO] loading image...")
if args["image"] is not None:
process_still(aruco_detector, args["image"])
else:
process_video(aruco_detector)
if __name__ == '__main__':
main()
+51
View File
@@ -0,0 +1,51 @@
import numpy as np
import argparse
import cv2
import sys
from aruco_types import ARUCO_DICT
def generate(aruco_dict: cv2.aruco.Dictionary, tag_id: int, side_pixels: int = 300):
tag = np.zeros((side_pixels, side_pixels, 1), dtype="uint8")
cv2.aruco.generateImageMarker(aruco_dict, tag_id, side_pixels, tag, 1)
return tag
def main():
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-f", "--folder", required=True,
help="path to output image containing ArUCo tag")
ap.add_argument("-d", "--id", type=int, required=True,
help="ID of ArUCo tag to generate")
ap.add_argument("-t", "--type", type=str,
default="DICT_ARUCO_ORIGINAL",
help="type of ArUCo tag to generate")
ap.add_argument("-i", "--imagetype", type=str,
default="png",
help="image file type of ArUCo tag image")
args = vars(ap.parse_args())
# verify that the supplied ArUCo tag exists and is supported by
# OpenCV
if ARUCO_DICT.get(args["type"], None) is None:
print("[INFO] ArUCo tag of '{}' is not supported".format(
args["type"]))
sys.exit(0)
# load the ArUCo dictionary
aruco_dict = cv2.aruco.getPredefinedDictionary(ARUCO_DICT[args["type"]])
# allocate memory for the output ArUCo tag and then draw the ArUCo
# tag on the output image
print("[INFO] generating ArUCo tag type '{}' with ID '{}'".format(
args["type"], args["id"]))
tag = generate(aruco_dict, args["id"], 300)
# write the generated ArUCo tag to disk and then display it to our
# screen
filename = f"{args["folder"]}/{args["type"]}_ID_{args["id"]:04d}.{args["imagetype"]}"
cv2.imwrite(filename, tag)
cv2.imshow("ArUCo Tag", tag)
cv2.waitKey(0)
if __name__ == '__main__':
main()
+25
View File
@@ -0,0 +1,25 @@
import cv2
ARUCO_DICT = {
"DICT_4X4_50": cv2.aruco.DICT_4X4_50,
"DICT_4X4_100": cv2.aruco.DICT_4X4_100,
"DICT_4X4_250": cv2.aruco.DICT_4X4_250,
"DICT_4X4_1000": cv2.aruco.DICT_4X4_1000,
"DICT_5X5_50": cv2.aruco.DICT_5X5_50,
"DICT_5X5_100": cv2.aruco.DICT_5X5_100,
"DICT_5X5_250": cv2.aruco.DICT_5X5_250,
"DICT_5X5_1000": cv2.aruco.DICT_5X5_1000,
"DICT_6X6_50": cv2.aruco.DICT_6X6_50,
"DICT_6X6_100": cv2.aruco.DICT_6X6_100,
"DICT_6X6_250": cv2.aruco.DICT_6X6_250,
"DICT_6X6_1000": cv2.aruco.DICT_6X6_1000,
"DICT_7X7_50": cv2.aruco.DICT_7X7_50,
"DICT_7X7_100": cv2.aruco.DICT_7X7_100,
"DICT_7X7_250": cv2.aruco.DICT_7X7_250,
"DICT_7X7_1000": cv2.aruco.DICT_7X7_1000,
"DICT_ARUCO_ORIGINAL": cv2.aruco.DICT_ARUCO_ORIGINAL,
"DICT_APRILTAG_16h5": cv2.aruco.DICT_APRILTAG_16h5,
"DICT_APRILTAG_25h9": cv2.aruco.DICT_APRILTAG_25h9,
"DICT_APRILTAG_36h10": cv2.aruco.DICT_APRILTAG_36h10,
"DICT_APRILTAG_36h11": cv2.aruco.DICT_APRILTAG_36h11
}
+4 -4
View File
@@ -14,7 +14,7 @@ def draw_gizmo(img, corners, imgpts):
return img
def draw_cube(img, corners, imgpts):
def draw_cube(img, imgpts):
imgpts = np.int32(imgpts).reshape(-1, 2)
# draw ground floor in green
@@ -29,7 +29,7 @@ def draw_cube(img, corners, imgpts):
return img
def init_data():
def factory():
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)
objp = np.zeros((PAT_NX * PAT_NY, 3), np.float32)
objp[:, :2] = np.mgrid[0:PAT_NX, 0:PAT_NY].T.reshape(-1, 2)
@@ -46,7 +46,7 @@ def process_video():
mtx, dist, _, _ = [X[i] for i in ('mtx', 'dist', 'rvecs', 'tvecs')]
# Init
criteria, objp, axis = init_data()
criteria, objp, axis = factory()
# Open camera
video = cv.VideoCapture(0)
@@ -69,7 +69,7 @@ def process_still():
mtx, dist, _, _ = [X[i] for i in ('mtx', 'dist', 'rvecs', 'tvecs')]
# Init
criteria, objp, axis = init_data()
criteria, objp, axis = factory()
for fname in glob.glob('check*.jpg'):
img = cv.imread(fname)