效果图
三幅图像分别为矫正前、校正后和裁减后的图片。
矫正后的图像有些奇怪,需要把无用的部分裁剪掉。
代码
步骤一:拍摄棋盘图片
运行该程序,按空格键拍摄棋盘信息(注意拍摄的棋盘要完整),拍摄20张左右即可,按q键退出。
import cv2
# 图片保存路径
IMG_SAVE_PATH = "img/"
if __name__ == '__main__':
num = 1
camera = cv2.VideoCapture(0)
while True:
state, src = camera.read()
cv2.imshow('src', src)
if cv2.waitKey(10) & 0xff == ord(' '):
cv2.imwrite(IMG_SAVE_PATH + str(num) + '.jpg', src)
print("Saved img_" + str(num) + "!")
num += 1
if cv2.waitKey(10) & 0xff == ord('q'):
break
cv2.destroyAllWindows()
步骤二:计算畸变矩阵
计算畸变矩阵,并保存畸变数据到parameter文件。
import cv2
import glob
import numpy as np
import pickle
import os
# 棋盘规格
BOARD_RAW = 19
BOARD_COL = 13
# 图片保存路径
IMG_SAVE_PATH = "img/"
IMG_RESULT_PATH = "result/"
if __name__ == '__main__':
obj_p = np.zeros((BOARD_RAW*BOARD_COL, 3), np.float32)
# np.mgrid[0:raw, 0:col]的shape为(2, 19, 13)转置后为(13, 19, 2),reshape后为(13*19, 2)
# obj_p[:, :2]===>obj_p[:, 0] and obj_p[:, 1]
obj_p[:, :2] = np.mgrid[0:BOARD_RAW, 0:BOARD_COL].T.reshape(-1, 2)
# print('obj_p:', obj_p)
obj_points = []
img_points = []
images = glob.glob(IMG_SAVE_PATH + '*.jpg')
for name in images:
print('name:', name)
img = cv2.imread(name)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 寻找角点
ret, corners = cv2.findChessboardCorners(gray, (BOARD_RAW, BOARD_COL), None)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
sub_corners = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
obj_points.append(obj_p)
img_points.append(sub_corners)
img = cv2.drawChessboardCorners(gray, (BOARD_RAW, BOARD_COL), sub_corners, ret)
cv2.imshow('img', img)
cv2.imwrite(IMG_RESULT_PATH + 'img'+name.split(os.sep)[-1], img)
cv2.waitKey(500)
# 标定结果:相机的内参数矩阵,畸变系数,旋转矩阵和平移向量
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, gray.shape[::-1], None, None)
print('ret:', ret)
print('mtx:', mtx)
print('dist:', dist)
print('rvecs:', rvecs)
print('tvecs:', tvecs)
# 保存参数
cal_parameter = {'ret': ret, 'mtx': mtx, 'dist': dist, 'rvecs': rvecs, 'tvecs': tvecs}
pickle.dump(cal_parameter, open("parameter", "wb"), 0)
print("Save successfully!")
步骤三:读取广角摄像头图像
打开广角摄像头,进行矫正,分别获得原图像、矫正图像和裁剪图像。
import cv2
import pickle
if __name__ == '__main__':
# 获取矫正参数
f = pickle.load(open('parameter', 'rb')) # 读取矫正参数
ret, mtx, dist, rvecs, tvecs = f['ret'], f['mtx'], f['dist'], f['rvecs'], f['tvecs']
# 获取图像尺寸
img = cv2.imread('img\\1.jpg')
h, w = img.shape[:2]
new_camera_mtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h))
x, y, w, h = roi # roi 提取的不准确,可能需要手动调整
vid = cv2.VideoCapture(0)
while True:
state, src = vid.read()
cv2.imshow('src', src)
dst = cv2.undistort(src, mtx, dist, None, new_camera_mtx)
cv2.imshow('img1', dst)
dst = dst[y:y + h, x:x + w]
cv2.imshow('img2', dst)
cv2.waitKey(1)
评论(0)
您还未登录,请登录后发表或查看评论