非常详细的相机标定原理、步骤(一)(世界坐标系与相机坐标系原理与转化)_An efforter的博客-CSDN博客_最详细、最完整的相机标定讲解
非常详细的相机标定原理、步骤(二)(图像坐标系与像素坐标系原理与转化,三维转二维原理与公式等等)_An efforter的博客-CSDN博客
非常详细的相机标定原理(三)(张正友相机标定法初见和单应性矩阵)_An efforter的博客-CSDN博客
非常详细的相机标定原理(四)(张正友相机标定法数学推导求解)_An efforter的博客-CSDN博客
代码分布清晰,一看就懂:
import argparse
from argparse import RawTextHelpFormatter
import numpy as np
import cv2
#寻找焦点
def cam_calib_find_corners(img, rlt_dir, img_idx, col, row):
#灰度化图片,减少参数的运算
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#寻找角点
ret, corners = cv2.findChessboardCorners(gray,(col,row), None)
#为了得到稍微精确一点的角点坐标,进一步对角点进行亚像素寻找
corners2 = cv2.cornerSubPix(gray, corners, (5, 5), (-1, -1), (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 10, 0.001))
print(corners)
if ret == True:
#保存角点图像
sav_path = rlt_dir + "\\" + str(img_idx) + "_corner.jpg"
#绘制角点
cv2.drawChessboardCorners(img, (col,row), corners2, ret)
cv2.imwrite(sav_path, img)
return (ret, corners2)
#相机标定
def cam_calib_calibrate(img_dir, rlt_dir, col, row, img_num):
w = 0
h = 0
all_corners = []
patterns = []
#标定相机,先搞这么一个假想的板子,标定就是把图像中的板子往假想的板子上靠,靠的过程就是计算参数的过程
x,y = np.meshgrid(range(col),range(row))
prod = row * col
pattern_points=np.hstack((x.reshape(prod,1),y.reshape(prod,1),np.zeros((prod,1)))).astype(np.float32)
for i in range(1,img_num+1):
img_path = img_dir + "\\" + str(i) + ".jpg"
print (img_path)
#读取图像
img = cv2.imread(img_path)
(h, w) = img.shape[:2]
#提取角点
ret, corners = cam_calib_find_corners(img, rlt_dir, i, col, row)
#合并所有角点
all_corners.append(corners)
patterns.append(pattern_points)
#rms代表返回成功,cameraMatrix代表相机内参,disCoeffs代表畸变,rvecs代表旋转向量,tvecs平移向量,最后两个是相机外参
rms, cameraMatrix, distCoeffs, rvecs, tvecs = cv2.calibrateCamera(patterns, all_corners, (w, h), None, None)
print('相机内参',cameraMatrix)
print('相机外参旋转向量',rvecs)
print('相机外参平移向量',tvecs)
return (cameraMatrix, distCoeffs)
def cam_calib_correct_img(crct_img_dir, cameraMatrix, distCoeffs):
for i in range(1,3):
crct_img_path = crct_img_dir + "\\" + str(i) + ".jpg"
print(crct_img_path)
img = cv2.imread(crct_img_path)
(h1, w1) = img.shape[:2]
#对参数做处理,使得最后的输出的矫正图像去表不必要的边缘。
newcameramtx,roi = cv2.getOptimalNewCameraMatrix(cameraMatrix,distCoeffs,(w1,h1),1,(w1,h1))
#矫正
dst = cv2.undistort(img, cameraMatrix, distCoeffs, None, newcameramtx)
# 保存矫正图像
x,y,w,h = roi
dst = dst[y:y+h, x:x+w]
rlt_path = crct_img_dir + "\\rlt\\" + str(i) + "_crct.jpg"
cv2.imwrite(rlt_path, dst)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="读取标定的图片并保存结果",formatter_class=RawTextHelpFormatter)
parser.add_argument("--img_dir",help="标定图片路径",type=str,metavar='', default='H:\\camera_code\\calib_img')
parser.add_argument("--rlt_dir",help="保存路径",type=str,metavar='',default="H:\\camera_code\\rlt_dir")
parser.add_argument("--crct_img_dir",help="待矫正图像路径",type=str,metavar='',default="H:\\camera_code\\crct_img")
parser.add_argument("--row_num",help="每一行有多少个角点,边缘处的不算",type=int,metavar='',default="7")
parser.add_argument("--col_num",help="每一列有多少个角点,边缘处的不算",type=int,metavar='',default="6")
parser.add_argument("--img_num",help="多少幅图像",type=int,metavar='',default="21")
args=parser.parse_args()
# 标定相机
cameraMatrix, distCoeffs = cam_calib_calibrate(args.img_dir, args.rlt_dir, args.row_num, args.col_num, args.img_num)
#矫正图片
cam_calib_correct_img(args.crct_img_dir, cameraMatrix, distCoeffs)
项目文件结构:
想要整体代码与资料的,请联系我。