在opencv中提供了一组函数用于实现相机的标定,标定返回的值包括:相机内参矩阵(fx fy xc yc)、相机外参矩阵(R t)以及畸变矩阵。python
标定的步骤以下:git
1. 准备棋盘格,棋盘格图片能够自行打印,如下使用10*7方格的棋盘格,交点则为9*6,棋盘格的大小1mm,即 gridsize=1github
2. 拍照,拍照的原则是多角度,根据理论至少要两种角度的拍照,实际中一般会拍20张左右;app
3. 使用opencv提供的角点检测函数findChessboardCorners找到棋盘格中的角点,并将每幅图片的角点值存放到list中,同时将棋盘格的角点的三维坐标存放到另外一个list。函数
4. 使用calibrateCamera函数获取内存矩阵、畸变矩阵、旋转矩阵以及转移矩阵。code
5.使用undistort函数将畸变的图像进行校订并查看校订后的图片效果。图片
代码以下(opencv_3.4.3):内存
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Wed Oct 16 08:45:25 2019 @author: hmeng """ import numpy as np import cv2 #图片角点个数 objp_dict = { 1: (9, 5), 2: (9, 6), 3: (9, 6), 4: (9, 6), 5: (9, 6), 6: (9, 6), 7: (9, 6), 8: (9, 6), 9: (9, 6), 10: (9, 6), 11: (9, 6), 12: (9, 6), 13: (9, 6), 14: (9, 6), 15: (9, 6), 16: (9, 6), 18: (9, 6), 17: (9, 6), 19: (9, 6), 20: (9, 6), } objp_list = [] corners_list = [] for k in objp_dict: nx, ny = objp_dict[k] # Prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0) gridsize=1(mm) objp = np.zeros((nx*ny,3), np.float32) #生成角点的三维坐标 objp[:,:2] = np.mgrid[0:nx, 0:ny].T.reshape(-1,2) # Make a list of calibration images fname = 'camera_cal/calibration%s.jpg' % str(k) img = cv2.imread(fname) # Convert to grayscale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Find the chessboard corners ret, corners = cv2.findChessboardCorners(gray, (nx, ny), None) # If found, save & draw corners if ret == True: # Save object points and corresponding corners objp_list.append(objp) corners_list.append(corners) # Draw and display the corners #cv2.drawChessboardCorners(img, (nx, ny), corners, ret) #plt.imshow(img) #plt.show() #print('Found corners for %s' % fname) else: print('Warning: ret = %s for %s' % (ret, fname)) img = cv2.imread('camera_cal/calibration1.jpg') img_size = (img.shape[1], img.shape[0]) ''' mtx : 内参矩阵 dist: 畸变矩阵 rvecs : 旋转矩阵 tvecs : 转移矩阵 ''' ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objp_list, corners_list, img_size,None,None) #将原始图片转换成未发生畸变的图片 dst = cv2.undistort(img, mtx, dist, None, mtx) com_img = np.hstack((img, dst)) cv2.namedWindow('image', cv2.WINDOW_NORMAL) cv2.imshow('image', com_img) cv2.waitKey(0) cv2.destroyAllWindows()
代码以及使用到的图片见github:utf-8
https://github.com/JosiahMg/calibrateCamerait