added aruco generate and detect
This commit is contained in:
@@ -1 +1,2 @@
|
|||||||
results/
|
results/
|
||||||
|
__pycache__/
|
||||||
@@ -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/d6/d55/tutorial_table_of_content_calib3d.html
|
||||||
https://docs.opencv.org/4.x/d9/db7/tutorial_py_table_of_contents_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
|
||||||
@@ -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()
|
||||||
@@ -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()
|
||||||
@@ -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
@@ -14,7 +14,7 @@ def draw_gizmo(img, corners, imgpts):
|
|||||||
return img
|
return img
|
||||||
|
|
||||||
|
|
||||||
def draw_cube(img, corners, imgpts):
|
def draw_cube(img, imgpts):
|
||||||
imgpts = np.int32(imgpts).reshape(-1, 2)
|
imgpts = np.int32(imgpts).reshape(-1, 2)
|
||||||
|
|
||||||
# draw ground floor in green
|
# draw ground floor in green
|
||||||
@@ -29,7 +29,7 @@ def draw_cube(img, corners, imgpts):
|
|||||||
|
|
||||||
return img
|
return img
|
||||||
|
|
||||||
def init_data():
|
def factory():
|
||||||
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)
|
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)
|
||||||
objp = np.zeros((PAT_NX * PAT_NY, 3), np.float32)
|
objp = np.zeros((PAT_NX * PAT_NY, 3), np.float32)
|
||||||
objp[:, :2] = np.mgrid[0:PAT_NX, 0:PAT_NY].T.reshape(-1, 2)
|
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')]
|
mtx, dist, _, _ = [X[i] for i in ('mtx', 'dist', 'rvecs', 'tvecs')]
|
||||||
|
|
||||||
# Init
|
# Init
|
||||||
criteria, objp, axis = init_data()
|
criteria, objp, axis = factory()
|
||||||
|
|
||||||
# Open camera
|
# Open camera
|
||||||
video = cv.VideoCapture(0)
|
video = cv.VideoCapture(0)
|
||||||
@@ -69,7 +69,7 @@ def process_still():
|
|||||||
mtx, dist, _, _ = [X[i] for i in ('mtx', 'dist', 'rvecs', 'tvecs')]
|
mtx, dist, _, _ = [X[i] for i in ('mtx', 'dist', 'rvecs', 'tvecs')]
|
||||||
|
|
||||||
# Init
|
# Init
|
||||||
criteria, objp, axis = init_data()
|
criteria, objp, axis = factory()
|
||||||
|
|
||||||
for fname in glob.glob('check*.jpg'):
|
for fname in glob.glob('check*.jpg'):
|
||||||
img = cv.imread(fname)
|
img = cv.imread(fname)
|
||||||
|
|||||||
Reference in New Issue
Block a user