利用opencv对摄像头做3D空间矫正
Submitted by hubdog on Tue, 2021-02-16 15:05
上边的mtx就是摄像机矩阵对应Intrincs,rvecs是旋转向量,tvecs是平移向量,dist是求解的误差系数
Transform矩阵可以使用罗德里格斯函数+平移向量组成
np.hstack((cv2.Rodrigues(rvecs[i])[0],tvecs[i]))
标准的calibratecamera函数是对下面的方程求解
[u,v,1]=Intrincs*Transform*[x,y,z,1]
u,v,1对应的2D像素坐标,x,y,z,1对应空间坐标,求解的Intrincs是相机的内部参数,可以理解为相机各种焦距的3x3矩阵,Transform是一个旋转+平移的组合矩阵(3x4)
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
上边的mtx就是摄像机矩阵对应Intrincs,rvecs是旋转向量,tvecs是平移向量,dist是求解的误差系数
Transform矩阵可以使用罗德里格斯函数+平移向量组成
np.hstack((cv2.Rodrigues(rvecs[i])[0],tvecs[i]))
对于任意的3D空间坐标,可以用opencv的ProjectPoints来求解2D投影坐标
imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
如果dist设为None,那么就跟用Intrincs*Transform算出来的结果是一模一样的。
Lcam=mtx.dot(np.hstack((cv2.Rodrigues(rvecs[i])[0],tvecs[i]))) for j in range(len(objpoints[i])): chessPoint=np.hstack((objpoints[i][j], 1)) np.reshape(chessPoint, (4,-1)) imgpoints2=Lcam.dot(chessPoint) imgpoints2/=imgpoints2[2]
标准的矫正函数一般是用findchessboardcorners 获取棋盘角点坐标,但是这个函数有个缺点,就是不能有遮挡。
想要在有遮挡的情况下获取角点位置,最好的库是libcbdetect,基于facebook的算法实现的。