标定相机
矫正失真的公式
其中r是未矫正的点(x,y)对应的棋盘上的点距离棋盘中心的距离。
使用棋盘矫正法,推荐至少拍摄不同角度和距离的20张棋盘照片。
OpenCV
标定步骤:
1.objpoints,对应实体的3D坐标,项目中使用的棋盘尺寸是8x6
2.imgpoints,对应照片的2D坐标
3.cv2.calibrateCamera()
4.cv2.undistort()
objpoints
由于不管照片是什么角度,棋盘始终是一个棋盘,objp适用于整个标定过程。
objp = np.zeros((6*8,3), np.float32)
objp[:,:2] = np.mgrid[0:8, 0:6].T.reshape(-1,2)
objpoints = [] # 3d points in real world space
imgpoints, 角点检测
只检测内角点,即2白块与2黑块相交的点
官方文档的摘抄:
findChessboardCorners(image, patternSize[, corners[, flags]]) → retval, corners
drawChessboardCorners(image, patternSize, corners, patternWasFound) → None
标定时用到超过20张图片,存入一个list
# 标定时用到超过20张图片,存入一个list
images = glob.glob('calibration_wide/GO*.jpg')
# 对每张标定图片寻找角点
for idx, fname in enumerate(images):
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Find the chessboard corners
ret, corners = cv2.findChessboardCorners(gray, (8,6), None)
# If found, add object points, image points
if ret == True:
objpoints.append(objp)
imgpoints.append(corners)
# Draw and display the corners
cv2.drawChessboardCorners(img, (8,6), corners, ret)
#write_name = 'corners_found'+str(idx)+'.jpg'
#cv2.imwrite(write_name, img)
cv2.imshow('img', img)
cv2.waitKey(500)
cv2.destroyAllWindows()
完成贫病交迫heimgp后,开始标定
标定
1.cv2.calibrateCamera
输入中的gray.shape[::-1]是图像尺寸(H x W),这个尺寸从灰度图中获得比较方便。
返回mtx摄像机矩阵,dist畸变参数,,rvecs旋转和tvecs平移向量
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
2.dst = cv2.undistort
这一步需要上一步中得到的mtx,dist作为输入参数;返回矫正后的图片。
dst = cv2.undistort(img, mtx, dist, None, mtx)
import pickle
# Test undistortion on an image
img = cv2.imread('calibration_wide/test_image.jpg')
img_size = (img.shape[1], img.shape[0])
# Do camera calibration given object points and image points
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, img_size,None,None)
dst = cv2.undistort(img, mtx, dist, None, mtx)
cv2.imwrite('calibration_wide/test_undist.jpg',dst)
# Save the camera calibration result for later use (we won't worry about rvecs / tvecs)
dist_pickle = {}
dist_pickle["mtx"] = mtx
dist_pickle["dist"] = dist
pickle.dump( dist_pickle, open( "calibration_wide/wide_dist_pickle.p", "wb" ) )
#dst = cv2.cvtColor(dst, cv2.COLOR_BGR2RGB)
# Visualize undistortion
f, (ax1, ax2) = plt.subplots(1, 2, figsize=(20,10))
ax1.imshow(img)
ax1.set_title('Original Image', fontsize=30)
ax2.imshow(dst)
ax2.set_title('Undistorted Image', fontsize=30)