Here’s the code… If you compare this to the link I first posted you’ll notice that I “functionalized” the two most important parts of the tutorial code so that I could call them repeatedly, and I also prevented it from passing the flags as set (including cv2.CALIB_FIX_ASPECT_RATIO
)… I was just trying different things (it didn’t help)… Lemme know what else I can provide and thanks again for any & all insight.
from numpy import savez
import numpy as np
import cv2
from os import environ, mkdir, walk
from os.path import isdir
from glob import glob
def read_chessboards(images, aruco_dict, board):
"""
Charuco base pose estimation.
"""
print("POSE ESTIMATION STARTS:")
allCorners = []
allIds = []
decimator = 0
# SUB PIXEL CORNER DETECTION CRITERION
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.00001)
for im in images:
print("=> Processing image {0}".format(im))
frame = cv2.imread(im)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
corners, ids, rejectedImgPoints = cv2.aruco.detectMarkers(gray, aruco_dict)
if len(corners)>0:
# SUB PIXEL DETECTION
for corner in corners:
cv2.cornerSubPix(gray, corner,
winSize = (3,3),
zeroZone = (-1,-1),
criteria = criteria)
res2 = cv2.aruco.interpolateCornersCharuco(corners,ids,gray,board)
if res2[1] is not None and res2[2] is not None and len(res2[1])>3 and decimator%1==0:
allCorners.append(res2[1])
allIds.append(res2[2])
decimator+=1
imsize = gray.shape
return allCorners,allIds,imsize
def calibrate_camera(allCorners, allIds, imsize, board):
"""
Calibrates the camera using the dected corners.
"""
print("CAMERA CALIBRATION")
cameraMatrixInit = np.array([[ 1000., 0., imsize[0]/2.],
[ 0., 1000., imsize[1]/2.],
[ 0., 0., 1.]])
distCoeffsInit = np.zeros((5,1))
flags = (cv2.CALIB_USE_INTRINSIC_GUESS + cv2.CALIB_RATIONAL_MODEL + cv2.CALIB_FIX_ASPECT_RATIO)
#flags = (cv2.CALIB_RATIONAL_MODEL)
(ret, camera_matrix, distortion_coefficients0,
rotation_vectors, translation_vectors,
stdDeviationsIntrinsics, stdDeviationsExtrinsics,
perViewErrors) = cv2.aruco.calibrateCameraCharucoExtended(
charucoCorners=allCorners,
charucoIds=allIds,
board=board,
imageSize=imsize,
cameraMatrix=cameraMatrixInit,
distCoeffs=distCoeffsInit,
# flags=flags,
criteria=(cv2.TERM_CRITERIA_EPS & cv2.TERM_CRITERIA_COUNT, 10000, 1e-9))
return ret, camera_matrix, distortion_coefficients0, rotation_vectors, translation_vectors
myname = environ['COMPUTERNAME']
workdir = './working/'
datadir = './imdata/'
if not isdir(workdir):
mkdir(workdir)
if not isdir(datadir):
mkdir(datadir)
mydirs = ('IMG-5x7_20,16_DICT6x6', 'IMG-5x7_25,19_DICT6x6',
'IMG-5x7_32,25_DICT6x6','IMG-8x11_20,16_DICT4x4')
dict4 = cv2.aruco.Dictionary_get(cv2.aruco.DICT_4X4_50)
dict6 = cv2.aruco.Dictionary_get(cv2.aruco.DICT_6X6_50)
mydict = (dict6, dict6, dict6, dict4)
myboard = (cv2.aruco.CharucoBoard_create(5, 7, 20, 16, dict6),
cv2.aruco.CharucoBoard_create(5, 7, 25, 19, dict6),
cv2.aruco.CharucoBoard_create(5, 7, 32, 25, dict6),
cv2.aruco.CharucoBoard_create(8, 11, 20, 16, dict4))
for i, (curdir, curdict, curboard) in enumerate(zip(mydirs, mydict, myboard)):
images = []
dirnam = f'imdata/CalibrationImageSets/{curdir}'
for root, _, _ in walk(dirnam, followlinks=False):
for imgnam in glob(f'{root}/*.jpg') + glob(f'{root}/*.png'):
images.append(imgnam)
allCorn, allIds, imsize = read_chessboards(images, curdict, curboard)
ret, mtx, dist, rvecs, tvecs = calibrate_camera(allCorn, allIds,
imsize, curboard)
savez(workdir + f'{myname}-CamCal{i}.npz', ret=ret, mtx=mtx, dist=dist,
rvecs=rvecs, tvecs=tvecs)