建设网站的网站空间,男女做那个的小视频网站,用wordpress建立电商网站,小程序模板页1.相机标定
根据张正友校正算法#xff0c;利用棋盘格数据校正对车载相机进行校正#xff0c;计算其内参矩阵#xff0c;外参矩阵和畸变系数。
标定的流程是#xff1a;
准备棋盘格数据#xff0c;即用于标定的图片对每一张图片提取角点信息在棋盘上绘制提取到的角点利用棋盘格数据校正对车载相机进行校正计算其内参矩阵外参矩阵和畸变系数。
标定的流程是
准备棋盘格数据即用于标定的图片对每一张图片提取角点信息在棋盘上绘制提取到的角点非必须只是为了显示结果利用提取的角点对相机进行标定获取相机的参数信息
1.1. 标定的图片
标定的图片需要使用棋盘格数据在不同位置、不同角度、不同姿态下拍摄的图片最少需要3张当然多多益善通常是10-20张。该项目中我们使用了20张图片如下图所示 把这些图片存放在项目路径中的camera_cal文件夹中。
1.2. 相机校正
下面我们对相机进行校正OPenCV中提供了对相机进行校正的代码在本项目中直接使用opencv中的API进行相机的校正如下所示:
# 1. 参数设定:定义棋盘横向和纵向的角点个数并指定校正图像的位置
nx 9
ny 6
file_paths glob.glob(./camera_cal/calibration*.jpg)
# 2. 计算相机的内外参数及畸变系数
def cal_calibrate_params(file_paths):object_points [] # 三维空间中的点3Dimage_points [] # 图像空间中的点2d# 2.1 生成真实的交点坐标类似(0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)的三维点objp np.zeros((nx * ny, 3), np.float32)objp[:, :2] np.mgrid[0:nx, 0:ny].T.reshape(-1, 2) # 2.2 检测每幅图像角点坐标for file_path in file_paths:img cv2.imread(file_path)# 将图像转换为灰度图gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 自动检测棋盘格内4个棋盘格的角点2白2黑的交点rect, corners cv2.findChessboardCorners(gray, (nx, ny), None)# 若检测到角点则将其存储到object_points和image_pointsif rect True:object_points.append(objp)image_points.append(corners)# 2.3 获取相机参数ret, mtx, dist, rvecs, tvecs cv2.calibrateCamera(object_points, image_points, gray.shape[::-1], None, None)return ret, mtx, dist, rvecs, tvecs
在这里有几个API给大家介绍下
寻找棋盘图中的棋盘角点
rect, corners cv2.findChessboardCorners(image, pattern_size, flags)参数 Image: 输入的棋盘图必须是8位的灰度或者彩色图像 Pattern_size:棋盘图中每行每列的角点个数内角点。 flags: 用来定义额外的滤波步骤以有助于寻找棋盘角点。所有的变量都可以单独或者以逻辑或的方式组合使用。取值主要有 CV_CALIB_CB_ADAPTIVE_THRESH 使用自适应阈值通过平均图像亮度计算得到将图像转换为黑白图而不是一个固定的阈值。 CV_CALIB_CB_NORMALIZE_IMAGE 在利用固定阈值或者自适应的阈值进行二值化之前先使用cvNormalizeHist来均衡化图像亮度。 CV_CALIB_CB_FILTER_QUADS 使用其他的准则如轮廓面积周长方形形状来去除在轮廓检测阶段检测到的错误方块。
返回
Corners:检测到的角点 rect: 输出是否找到角点找到角点返回1否则返回0 检测完角点之后我们可以将将测到的角点绘制在图像上使用的API是 cv2.drawChessboardCorners(img, pattern_size, corners, rect)参数 Img: 预绘制检测角点的图像pattern_size : 预绘制的角点的形状corners: 角点矩阵rect 表示是否所有的棋盘角点被找到可以设置为findChessboardCorners的返回值注意如果发现了所有的角点那么角点将用不同颜色绘制每行使用单独的颜色绘制并且把角点以一定顺序用线连接起来如下图所示 利用定标的结果计算内外参数
ret, mtx, dist, rvecs, tvecs cv2.calibrateCamera(object_points, image_points, image_size, None, None)参数
Object_points:世界坐标系中的点在使用棋盘的场合我们令z的坐标值为0而x,y坐标用里面来度量选用英寸单位那么所有参数计算的结果也是用英寸表示。最简单的方式是我们定义棋盘的每一个方块为一个单位。image_points:在图像中寻找到的角点的坐标包含object_points所提供的所有点image_size: 图像的大小以像素为衡量单位
返回 ret: 返回值 mtx: 相机的内参矩阵大小为3*3的矩阵 dist: 畸变系数为5*1大小的矢量 rvecs: 旋转变量 tvecs: 平移变量
1.3 图像去畸变
效果预览 处理前: 处理后 上一步中我们已经得到相机的内参及畸变系数我们利用其进行图像的去畸变最直接的方法就是调用opencv中的函数得到去畸变的图像
def img_undistort(img, mtx, dist):dst cv2.undistort(img, mtx, dist, None, mtx)return dst
我们看下求畸变的API:
dst cv2.undistort(img, mtx, dist, None, mtx)参数
Img: 要进行校正的图像mtx: 相机的内参dist: 相机的畸变系数
返回
dst: 图像校正后的结果总结 标定的图片 不同角度和方向拍摄的棋盘格图片数据 相机校正 检测棋盘格数据的角点 cv2.findChessboardCorners 计算相机的内参数和外参数cv2.calibrateCamera 图像去畸变 cv2.undistort() 代码总览
# encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
#遍历文件夹
import glob
from moviepy.editor import VideoFileClip参数设置
nx 9
ny 6
#获取棋盘格数据
file_paths glob.glob(./camera_cal/calibration*.jpg)# 绘制对比图
def plot_contrast_image(origin_img, converted_img, origin_img_titleorigin_img, converted_img_titleconverted_img,converted_img_grayFalse):fig, (ax1, ax2) plt.subplots(1, 2, figsize(15, 20))ax1.set_title origin_img_titleax1.imshow(origin_img)ax2.set_title converted_img_titleif converted_img_gray True:ax2.imshow(converted_img, cmapgray)else:ax2.imshow(converted_img)plt.show()#相机矫正使用opencv封装好的api
#目的:得到内参、外参、畸变系数
def cal_calibrate_params(file_paths):#存储角点数据的坐标object_points [] #角点在真实三维空间的位置image_points [] #角点在图像空间中的位置#生成角点在真实世界中的位置objp np.zeros((nx*ny,3),np.float32)#以棋盘格作为坐标每相邻的黑白棋的相差1objp[:,:2] np.mgrid[0:nx,0:ny].T.reshape(-1,2)#角点检测for file_path in file_paths:img cv2.imread(file_path)#将图像灰度化gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#角点检测rect,coners cv2.findChessboardCorners(gray,(nx,ny),None)#角点检测结果的绘制# imgcopy img.copy()# cv2.drawChessboardCorners(imgcopy,(nx,ny),coners,rect)# plot_contrast_image(img,imgcopy)#若检测到角点则进行保存 即得到了真实坐标和图像坐标if rect True :object_points.append(objp)image_points.append(coners)# 相机较真ret, mtx, dist, rvecs, tvecs cv2.calibrateCamera(object_points, image_points, gray.shape[::-1], None, None)return ret, mtx, dist, rvecs, tvecs# 图像去畸变利用相机校正的内参畸变系数
def img_undistort(img, mtx, dist):dis cv2.undistort(img, mtx, dist, None, mtx)return disif __name__ __main__:ret, mtx, dist, rvecs, tvecs cal_calibrate_params(file_paths)if np.all(mtx!None):img cv2.imread(test/test1.jpg)undistort_img img_undistort(img,mtx,dist)plot_contrast_image(img,undistort_img)print(done)else:print(failed)