使用ChARUco 板子进行相机标定

一、 ChARUco 板子

以前标定过程中,都是用棋盘板子(张正友),棋盘图案的每个角都被两个黑色方块围绕着,可以更精确地细化,但是棋盘板子有个问题,就是不能被遮挡,必须是完全可见的。ArUco板子具有快速检测和多功能性,然而,ArUco标记的一个问题是,即使经过亚像素细化,它们的角点位置的准确性也不是很高。所以综上, ChARUco 板子结合两者,如图:
这里写图片描述

二、 标定过程代码

# -*- coding: utf-8 -*-
###相机标定
import cv2
import numpy as np
import os
dirpath=os.getcwd()
print("当前路径是%s"%dirpath)
#创建一个标准板子
num = 9#9*9的板子
dictionary = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_4X4_50)
board = cv2.aruco.CharucoBoard_create(num, num, .025, .0125, dictionary)#0.025单位是米
img = board.draw((200 * num, 200 * num))
cv2.imwrite(dirpath+"\\"+"{}.png".format(num), img)
#打印板子,如贴在墙上,用相机不同角度拍摄若干张照片
#标定
demo_path=r'' #文件夹
if len(os.listdir(demo_path))>40:
    assert("相机拍摄照片少于40张")
allCorners = []
allIds = []
os.chdir(demo_path) #改变路径,变换到文件夹中
for i in range(len(os.listdir(demo_path))): #这里也可以用webcamera 测试,把标准板子在webcamera 前移动
    im=cv2.imread("%g.jpg"%i,0)
    corners, ids, rejected = cv2.aruco.detectMarkers(im, dictionary)
    if corners == None or len(corners) == 0:
        continue
    ret, charucoCorners, charucoIds = cv2.aruco.interpolateCornersCharuco(corners, ids, im, board)#其中的参数依赖于detectMarkers检测的初始值
    if corners is not  None  and charucoIds is not None:
        allCorners.append(charucoCorners)
        allIds.append(charucoIds)
    cv2.aruco.drawDetectedMarkers(im,corners,ids)
    cv2.imshow("marsk",im)
    key = cv2.waitKey(1)
    if key == ord('q'):
        break
w,h=im.shape[1],im.shape[0]
ret, K, dist_coef, rvecs, tvecs = cv2.aruco.calibrateCameraCharuco(allCorners, allIds, board,(w,h),None,None,flag=cv2.CALIB_USE_INTRINSIC_GUESS)
#save results
cali_results=np.savez(demo_path+"\\"+"camera.npz",k= K,d=dist_coef)#cali_results['k']和cali_results['d']可以可视化结果

这个代码没有测试,因为没有去拿相机拍板子(40张吧),回头有时间测试一下。
参考:
http://www.morethantechnical.com/2017/11/17/projector-camera-calibration-the-easy-way/

猜你喜欢

转载自blog.csdn.net/qq_15642411/article/details/80666441