这里给出我觉得原理解释较清楚的地址,供大家参考:
https://blog.csdn.net/u010128736/article/details/52860364
这一篇为张正友标定原版论文的翻译版:
https://blog.csdn.net/heroacool/article/details/50286677?tdsourcetag=s_pctim_aiomsg
下面所写的原理均参考转载自这两篇文章,有问题请指正。
过程中可能出现的问题
(1)ValueError: could not broadcast input array from shape (54,2) into shape (49,2)
在运行过程中,我们所要采用计算的是棋盘格的内角点,而不包括外角点,若是出现这种错误可以检查看看自己函数中所代入的角点是否有误。
(2)error: ..\..\..\modules\core\src\array.cpp:2482: error: (-206) Unrecognized or unsupported array type in function cvGetMat
这个错误也只是个小错误,需要检查自己的图片路径是否有误。若是有出现cv2error,-215这样错误的,可能是opencv版本与代码不适用,可以尝试换个opencv版本。
运行结果
(1)我所使用的手机型号为OPPO r11,相机分辨率为3456×4608,焦距为4.27mm,拍摄使用的棋盘格单个方格尺寸为2.5cm×2.5cm,每行每列均有10个方格。
(2)intrinsics_parm为内参,一个相机只有一个内参,distortionk为畸变系数K,extrinsics_parm为外参数,接下来的数据则为每一张图片的参数,因为拍摄角度的不同所以每一张的外参也不相同,有17张图片就有17个外参。
(3)在这里,要注意的是所使用的图片要先转为灰度图再运行,因为原图所占空间较大怕影响处理速度,所以我使用的图像是经过比例压缩的,若是不经过比例压缩会导致图像变形,方格就没那么精确,结果也会有较大的偏差。
若是使用要做相应的修改,比如10×10的棋盘,则内角点为9×9。
#!usr/bin/env/ python
# _*_ coding:utf-8 _*_
import cv2 as cv
import numpy as np
import os
from step.homography import get_homography
from step.intrinsics import get_intrinsics_param
from step.extrinsics import get_extrinsics_param
from step.distortion import get_distortion
from step.refine_all import refinall_all_param
def calibrate():
#求单应矩阵
H = get_homography(pic_points, real_points_x_y)
#求内参
intrinsics_param = get_intrinsics_param(H)
#求对应每幅图外参
extrinsics_param = get_extrinsics_param(H, intrinsics_param)
#畸变矫正
k = get_distortion(intrinsics_param, extrinsics_param, pic_points, real_points_x_y)
#微调所有参数
[new_intrinsics_param, new_k, new_extrinsics_param] = refinall_all_param(intrinsics_param,
k, extrinsics_param, real_points, pic_points)
print("intrinsics_parm:\t", new_intrinsics_param)
print("distortionk:\t", new_k)
print("extrinsics_parm:\t", new_extrinsics_param)
if __name__ == "__main__":
file_dir = r'..\image6'
# 标定所用图像
pic_name = os.listdir(file_dir)
# 由于棋盘为二维平面,设定世界坐标系在棋盘上,一个单位代表一个棋盘宽度,产生世界坐标系三维坐标
cross_corners = [7, 7] #棋盘方块交界点排列
real_coor = np.zeros((cross_corners[0] * cross_corners[1], 3), np.float32)
real_coor[:, :2] = np.mgrid[0:7, 0:7].T.reshape(-1, 2)
real_points = []
real_points_x_y = []
pic_points = []
for pic in pic_name:
pic_path = os.path.join(file_dir, pic)
pic_data = cv.imread(pic_path)
# 寻找到棋盘角点
succ, pic_coor = cv.findChessboardCorners(pic_data, (cross_corners[0], cross_corners[1]), None)
if succ:
# 添加每幅图的对应3D-2D坐标
pic_coor = pic_coor.reshape(-1, 2)
pic_points.append(pic_coor)
real_points.append(real_coor)
real_points_x_y.append(real_coor[:, :2])
calibrate()
以上为主函数,代码原作者还写了一些子函数调用,具体参考 https://github.com/SPengLiang/Camera-Calibration-of-Zhang-s-method