目前在机器人高层规划中,机器人越来越依赖于摄像头的反馈信息,比如自动打磨,焊接,喷涂的智能规划,或者一些分拣,码垛的规划. 在项目开始前, 第一步要做的一定是给机器人和摄像头进行标定. 那么如何结合机器人标定摄像头就是本片要讨论的问题. 本片接下来就是记录我自己做的标定全过程.
手眼标定非常依赖机器人给出的参数,如果参数不准确,一定会影响到标定结果. 而且还很难察觉. 否则,会浪费大量时间在检查摄像头标定步骤中, 却忽略机器人参数本身.
标定板也很重要, 简单的棋盘格标定板可以从opencv官网上链接下载并打印. 如果追求精度,那就要在淘宝上购买更精确的标定板. 为了追求精确度,就不要省钱了.
上图为opencv的棋盘标定板, 角点计算是算这个棋盘的内部角点(也就是正方块的角), 就是说边缘部分的角是不算的. 那么从左往右数,这个棋盘的长中,角点有九个, 宽中角点有6个. 就是说这个棋盘是6*9的
如图安装好机器人和相机, 该相机安装在机器人的末端,所以就是眼在手上的机器人标定.
手眼标定的原理我就不在这里探讨了,我贴一段别人的博客,可以去看那里.
https://blog.csdn.net/yaked/article/details/77161160
第一步就是先把足够的参数收集起来 然后再统一计算. 那么需要哪些参数呢
https://docs.opencv.org/4.4.0/dc/dbb/tutorial_py_calibration.html
A = n_long * side
B = n_short * side
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
objp = np.zeros((n_short*n_long,3), np.float32)
objp[:,:2] = np.mgrid[0:A:side,0:B:side].T.reshape(-1,2)
# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.
axis = np.float32([[3,0,0], [0,3,0], [0,0,-3]]).reshape(-1,3) * side
rvecs = []
tvecs = []
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
3.2 计算棋盘标定板的角点
ret, corners = cv2.findChessboardCorners(gray, (n_long,n_short),None)
3.3 进一步在获得的角点参数下亚像素信息
corners2 = cv2.cornerSubPix(gray,corners,(15,15),(-1,-1),criteria)
3.4 重复上述3.1到3.3的迭代获取多组亚像素信息
3.5 计算相机的内外参
ret, mtx, disto, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],intrinsic,disto)
3.6 计算误差
for i in range(len(images)):
imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, disto)
error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
mean_error += error
print("mean error: ", mean_error/len(objpoints))
至此为利用opencv计算内外参的手眼标定全部过程. 当然具体要根据自己的项目情况来优化代码.