OpenCV实现相机标定

本文实例为大家分享了OpenCV实现相机标定的具体代码,供大家参考,具体内容如下

一、相机与针孔相机模型

1.相机模型

现代科技加持下的相机已经成为制造精密设计巧妙的消费品,相机的光学结构也比诞生之初复杂了许多
典型单反相机光学结构:

在众多相机模型中,针孔相机又称投影相机模型是相对简单而常用的模型。简单的说,针孔相机模型就是把相机简化成单纯的小孔成像,可想而知,这种简化对于精度要求高的情况或者特殊镜头的相机是不适用的。
小孔成像原理:

2.引入透镜

单纯的小孔成像模型中没有考虑镜头,现实条件下,由一片或多片透镜组成的镜头才能让利用了小孔成像原理的相机成像清晰的同时保持画面亮度。所以我们需要向模型引入透镜。
透镜成像原理:

但是,新的问题也随之而来:虚焦、畸变
一般我们称之为径向畸变,即光线在院里透镜中的地方比靠近中心的地方更加弯曲。径向畸变又分为中短焦距、近距离的桶形畸变和长焦距、远距离会出现的枕形畸变。

二、相机参数

1.坐标系约定

我们约定三个坐标系

1、世界坐标系矩阵:X

2、摄像机坐标系:Xc,

3、图像(像素)坐标系:x

4、相机矩阵:P

2.像平面到像素平面的投影

将三维空间中一点,过该点取一平面与像素平面平行,该平面就是像平面。设该三位点P,齐次坐标为X。投影为图像点P’,平面坐标x。
针孔相机模型:

在针孔相机模型中,像素坐标和像坐标之间的关系:
λx = PX
其中,λ是三位点的逆深度。P为相机矩阵,可以分解为:
P = R[K|t]
R 是描述照相机方向的旋转矩阵,t 是描述照相机中心位置的三维平移向量,内标定矩阵K 描述照相机的投影性质。标定矩阵仅和照相机自身的情况有关,通常可以写成:

焦距f是像在平面到像素平面中心的距离。s是倾斜参数,α是纵横比例参数。
在像素数组在传感器上没有偏斜且像素是正方形的时候,可以设 s = 0,α = 1。标定矩阵可以简化为:

三、相机标定

实验图片如下:

代码如下:

import cv2
import numpy as np
import glob

# 找棋盘格角点
# 阈值
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
#棋盘格模板规格
w = 7   #内角点个数,内角点是和其他格子连着的点
h = 7

# 世界坐标系中的棋盘格点,例如(0,0,0), (1,0,0), (2,0,0) ....,(8,5,0),去掉Z坐标,记为二维矩阵
objp = np.zeros((w*h,3), np.float32)
objp[:,:2] = np.mgrid[0:w,0:h].T.reshape(-1,2)
# 储存棋盘格角点的世界坐标和图像坐标对
objpoints = [] # 在世界坐标系中的三维点
imgpoints = [] # 在图像平面的二维点

images = glob.glob('picture/*.jpg')
for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    # 找到棋盘格角点
    # 棋盘图像(8位灰度或彩色图像)  棋盘尺寸  存放角点的位置
    ret, corners = cv2.findChessboardCorners(gray, (w,h),None)
    # 如果找到足够点对,将其存储起来
    if ret == True:
        # 角点精确检测
        # 输入图像 角点初始坐标 搜索窗口为2*winsize+1 死区 求角点的迭代终止条件
        cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
        objpoints.append(objp)
        imgpoints.append(corners)
        # 将角点在图像上显示
        cv2.drawChessboardCorners(img, (w,h), corners, ret)
        cv2.imshow('findCorners',img)
        cv2.waitKey(1000)
cv2.destroyAllWindows()
#标定、去畸变
# 输入:世界坐标系里的位置 像素坐标 图像的像素尺寸大小 3*3矩阵,相机内参数矩阵 畸变矩阵
# 输出:标定结果 相机的内参数矩阵 畸变系数 旋转矩阵 平移向量
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
# mtx:内参数矩阵
# dist:畸变系数
# rvecs:旋转向量 (外参数)
# tvecs :平移向量 (外参数)
print (("ret:"),ret)
print (("mtx:\n"),mtx)        # 内参数矩阵
print (("dist:\n"),dist)      # 畸变系数   distortion cofficients = (k_1,k_2,p_1,p_2,k_3)
print (("rvecs:\n"),rvecs)    # 旋转向量  # 外参数
print (("tvecs:\n"),tvecs)    # 平移向量  # 外参数
# 去畸变
img2 = cv2.imread('picture/6.jpg')
h,w = img2.shape[:2]
# 我们已经得到了相机内参和畸变系数,在将图像去畸变之前,
# 我们还可以使用cv.getOptimalNewCameraMatrix()优化内参数和畸变系数,
# 通过设定自由自由比例因子alpha。当alpha设为0的时候,
# 将会返回一个剪裁过的将去畸变后不想要的像素去掉的内参数和畸变系数;
# 当alpha设为1的时候,将会返回一个包含额外黑色像素点的内参数和畸变系数,并返回一个ROI用于将其剪裁掉
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),0,(w,h)) # 自由比例参数

dst = cv2.undistort(img2, mtx, dist, None, newcameramtx)
# 根据前面ROI区域裁剪图片
x,y,w,h = roi
dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibresult.jpg',dst)

# 反投影误差
# 通过反投影误差,我们可以来评估结果的好坏。越接近0,说明结果越理想。
# 通过之前计算的内参数矩阵、畸变系数、旋转矩阵和平移向量,使用cv2.projectPoints()计算三维点到二维图像的投影,
# 然后计算反投影得到的点与图像上检测到的点的误差,最后计算一个对于所有标定图像的平均误差,这个值就是反投影误差。
total_error = 0
for i in range(len(objpoints)):
    imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
    error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
    total_error += error
print (("total error: "), total_error/len(objpoints))

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Python opencv相机标定实现原理及步骤详解

    相机标定相机标定的目的 获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的选择和平移矩阵),内参和外参系数可以对之后相机拍摄的图像就进行矫正,得到畸变相对很小的图像. 相机标定的输入 标定图像上所有内角点的图像坐标,标定板图像上所有内角点的空间三维坐标(一般情况下假定图像位于Z=0平面上). 相机标定的输出 摄像机的内参.外参系数. 拍摄的物体都处于三维世界坐标系中,而相机拍摄时镜头看到的是三维相机坐标系,成像时三维相机坐标系向二维图像坐标系转换.不同的镜头成像时的转换矩阵不同,同时可能引

  • 基于python opencv单目相机标定的示例代码

    相机固定不动,通过标定版改动不同方位的位姿进行抓拍 import cv2 camera=cv2.VideoCapture(1) i = 0 while 1: (grabbed, img) = camera.read() cv2.imshow('img',img) if cv2.waitKey(1) & 0xFF == ord('j'): # 按j保存一张图片 i += 1 u = str(i) firename=str('./img'+u+'.jpg') cv2.imwrite(firename

  • OpenCV实现相机标定板

    本文实例为大家分享了OpenCV实现相机标定板的具体代码,供大家参考,具体内容如下 1.代码实现 #include <opencv.hpp> #include "highgui.h" #include "cxcore.h" using namespace cv; int main0(int argc, char *argv[]) { int width = 140;//width and heigth of single square int heigh

  • OpenCV实现相机标定示例详解

    目录 环境准备 相机标定 棋盘格图片 实时显示相机的画面 在线标定 实时显示相机画面,按键保存能检测到角点的 棋盘格图片 离线标定 畸变矫正 环境准备 vs2015+opencv4.10安装与配置 相机标定 棋盘格图片 可以自己生成,然后打印到A4纸上.(也可以去TB买一块,平价买亚克力板的,不反光买氧化铝材质,高精度买陶瓷的) /** * 生成棋盘格图片 **/ int generateCalibrationPicture() { //Mat frame = imread("3A4.bmp&q

  • OpenCV实现相机标定

    本文实例为大家分享了OpenCV实现相机标定的具体代码,供大家参考,具体内容如下 一.相机与针孔相机模型 1.相机模型 现代科技加持下的相机已经成为制造精密设计巧妙的消费品,相机的光学结构也比诞生之初复杂了许多典型单反相机光学结构: 在众多相机模型中,针孔相机又称投影相机模型是相对简单而常用的模型.简单的说,针孔相机模型就是把相机简化成单纯的小孔成像,可想而知,这种简化对于精度要求高的情况或者特殊镜头的相机是不适用的.小孔成像原理: 2.引入透镜 单纯的小孔成像模型中没有考虑镜头,现实条件下,由

  • 聊一聊OpenCV相机标定

    相机标定:简单的说,就是获得相机参数的过程.参数如:相机内参数矩阵,投影矩阵,旋转矩阵和平移矩阵等 什么叫相机参数? 简单的说,将现实世界中的人.物,拍成一张图像(二维).人或物在世界中的三维坐标,和图像上对应的二维坐标间的关系.表达两种不同维度坐标间的关系用啥表示?用相机参数. 相机的成像原理 先来看一下,相机的成像原理: 如图所示,这是一个相机模型.将物体简化看成一个点.来自物体的光,通过镜头,击中图像平面(图像传感器),以此成像.d0是物体到镜头的距离,di时镜头到图像平面的距离,f是镜头

  • OpenCV相机标定的全过程记录

    目录 一.OpenCV标定的几个常用函数 findChessboardCorners()棋盘格角点检测 cv::drawChessboardCorners()棋盘格角点的绘制 find4QuadCornerSubpix()对粗提取的角点进行精确化 cornerSubPix()亚像素检测 calibrateCamera()求解摄像机的内在参数和外在参数 initUndistortRectifyMap()计算畸变参数 二.绘制棋盘格,拍摄照片 三.相机标定 四.对图片进行校正 总结 一.OpenCV

  • OpenCV实现相机校正

    本文实例为大家分享了OpenCV实现相机校正的具体代码,供大家参考,具体内容如下 1. 相机标定 根据张正友校正算法,利用棋盘格数据校正对车载相机进行校正,计算其内参矩阵,外参矩阵和畸变系数. 标定的流程是: 准备棋盘格数据,即用于标定的图片 对每一张图片提取角点信息 在棋盘上绘制提取到的角点(非必须,只是为了显示结果) 利用提取的角点对相机进行标定 获取相机的参数信息 2.关于相机校正用到的几个API: 1.寻找棋盘图中的棋盘角点 rect, corners = cv2.findChessbo

  • OpenCV实现简易标定板

    本文实例为大家分享了OpenCV实现简易标定板的具体代码,供大家参考,具体内容如下 使用OpenCV生成标定板图片,然后找高精度打印机进行打印,贴在硬板上,就可以得到一个简易的标定板. 废话不多说,代码如下: //编程环境:VS2013, X64,OpenCV3.0.0 #include <iostream> #include <opencv2\core\core.hpp> #include <opencv2\opencv.hpp> using namespace st

  • 如何基于matlab相机标定导出xml文件

    1 参数选择 径向畸变3个参数还是两个参数 默认两个参数 如果是三个参数 2准备转化生成结果 二参数的转化代码 writeExternalandIntrinsicMatrix(cameraParams62,'cameraParams622.xml'); function writeExternalandIntrinsicMatrix(cameraParams,file) %writeXML(cameraParams,file) docNode = com.mathworks.xml.XMLUti

随机推荐