本着自娱自乐的精神,标定板做好后,就开始拿它做下标定试试。以前都是用c++做的,作为Python初学者,试试用Python把这个流程回顾一遍。
首先,开始采集图像。我这里有三种能采集图像的
东西:usb摄像头,笔记本自带摄像头,手机摄像头。
因为我这标定板有点重量(真材实料,嘿嘿),我觉得得用双手才能hold住,所以就用笔记本自带摄像头来采集,采集过程得自动化才能解放双手,因此加了时间触发,代码如下:
"""
@author: wanqingfeng
"""
import cv2
import time
cam = cv2.VideoCapture(0)
i = 0
while True:
(isCaptured,frame) = cam.read() #采集摄像头
cv2.imshow("one",frame)
cv2.imwrite("calib/frame%d.jpg"%i,frame)
i = i + 1
time.sleep(1)#每隔一秒采一帧
if cv2.waitKey(1) & 0xFF == ord("q"): #按‘q’结束采集
break
cam.release()
cv2.destroyAllWindows()
这里时间设为等待1秒,每隔1秒自动采集一张,全部存入指定文件夹里。
采集完成以后,来文件夹再看看,把一些运动模糊的,角度重复的图片删掉。
然后开始标定:
标定程序:
"""
@author: wanqingfeng
"""
#标定
import cv2
import numpy as np
import glob
criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
#标定板尺寸
w = 8#根据实际角点个数,9x7格子,角点就是8x6
h = 6#正确的数目很重要,否则会报错
objp = np.zeros((w*h,3), np.float32)
objp[:,:2] = np.mgrid[0:w, 0:h].T.reshape(-1,2)
obj_points = []
img_points = []
images = glob.glob('calib/*.jpg')#该文件夹下存着刚才采集并筛选过的图片
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
size = gray.shape[::-1]
ret, corners = cv2.findChessboardCorners(gray,(w,h),None)
if ret == True:
cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
obj_points.append(objp)
img_points.append(corners)
cv2.drawChessboardCorners(img,(w,h),corners,ret)
cv2.imshow('findCorners',img)
cv2.waitKey(0)#每按一次空格开始标定下一张
cv2.destroyAllWindows()
#标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points,gray.shape[::-1],None,None)
print("ret: \n",ret)
print("mtx: \n",mtx) #内参矩阵
就这样得到了内参矩阵,然后有这个内参矩阵,接下来可以进行更多别的实验了,未完待续……
(这个过程非常简单,大牛们不小心看到此文一笑而过就好……)