镜头变形是摄影中常见的现象,使用广角的时候更可以看的出来,失真主要有以下两种:

  • 径向畸变(radial distortion)

  • 切向畸变(tangential distortion)

径向畸变

光线经入透镜折射后会产生偏折,造成形变,而当透镜越小时形变会越明显,也就是原本的直线会出现弯曲,而离中心点越远,变化会越来越严重,广角的话常产生下图中间的形变,而长焦镜头则常是右侧的形变。

切向畸变

主要发生在硬件瑕疵上,当镜头没有完全与成像平面对齐时,便会产生误差,有些图片会比想像中的来的更紧密。

我们需要的参数

透过上述俩个式子,我们需要找出五个系数,以及相机固有/外部参数

  • Five params

  • Intrinsic Params

  • Extrinsix Params

Five params

Intrinsic Params

有焦距(focal length)→(fx,fy),光学中心(optical center)→(cx,cy)等信息,我们可以将它们组合成一个矩阵来去除因特定相机镜头而造成的失真。显而易见,这个matrix只需调整一次,便可应用在这个相机拍摄的不同照片上。

Extrinsix Params

外部参数则是对应于3D坐标系的转换(旋转/平移),要找到这些参数,我们需要透过一些(至少>10张)来找到相关的某个特定点的。(例如:国际象棋,利用正方形边框的顶点)。因为我们已经知道现实空间中棋盘格各点的坐标,也知道图片内的各点坐标,如此便可消除失真的影响。

让我们进入代码实作部分

现在提供Github Repository,让大家可以运行:

https://github.com/tarkers/Camera_Calibration_OpenCV

先定义一下关键字:3D点叫对象点(object points),2D像点叫图像点(image points)

我们所需要的就是在图像中的棋盘中寻找有一组对象点的图像点,因为有照片,所以对我们来说是相对比较好找的。我们知道棋盘格在这几张图片内,有不同的位置及方向, 那对象点(X,Y,Z)我们又该如何找呢?

因为3维太麻烦了,我们可以将棋盘格定为XY平面(Z=0),然后让我们把摄像机放在它上面,这样我们只须找出X,Y即可。我们可以简单的标点上去

  1. 若不知道棋盘大小,那我们的基本长度就是以格子为单位:(0,0),(0,1),(0,2)……

  2. 若已知每格是M毫米,那我们也可以标为:(0,0),(0,M)(0,2M)....。

以这次实例,我们第一次实作。

openCV Func 介绍:

  • cv.findChessboardCorners()

    • https://docs.opencv.org/4.x/d9/d0c/group__calib3d.html#ga93efa9b0aa890de240ca32b11253dd4a

  • cv.cornerSubPix

    • https://docs.opencv.org/4.x/dd/d1a/group__imgproc__feature.html#ga354e0d7c86d0d9da75de9b9701a9a87e

  • cv.calibrateCamera()

    • https://docs.opencv.org/4.x/d9/d0c/group__calib3d.html#ga3207604e4b1a1758aa66acb6ed5aa65d

来自 OpenCV 的简单代码

将图像读入并计算2D/3D点,利用opencv的calibrateCameramatrix和distortion coefficients。这样便能修正图片了

import numpy as np
import cv2 as cv
import glob
# termination criteria
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((6*7,3), np.float32)
objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)
# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.
images = glob.glob('*.jpg')
for fname in images:img = cv.imread(fname)gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)# Find the chess board cornersret, corners = cv.findChessboardCorners(gray, (7,6), None)# If found, add object points, image points (after refining them)if ret == True:objpoints.append(objp)corners2 = cv.cornerSubPix(gray,corners, (11,11), (-1,-1), criteria)imgpoints.append(corners)# Draw and display the cornerscv.drawChessboardCorners(img, (7,6), corners2, ret)cv.imshow('img', img)cv.waitKey(500)
cv.destroyAllWindows()
#calibration
ret, mtx, dist, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
# get undistorted image
img = cv.imread('left12.jpg')
h,  w = img.shape[:2]
newcameramtx, roi = cv.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))
# undistort
dst = cv.undistort(img, mtx, dist, None, newcameramtx)
# crop the image
x, y, w, h = roi
dst = dst[y:y+h, x:x+w]
cv.imwrite('calibresult.png', dst)

结果

可以看到棋盘边缘明显弯曲的线,有被修正回来

左:失真,右:失真

透过这样的介绍,相信大家对校准有更深的认识啦!我们下回见:

参考:

https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html

https://allen108108.github.io/blog/2020/02/15/%E5%BD%B1%E5%83%8F%E7%95%B8%E8%AE%8A%20Image%20Distortion/

https://learnopencv.com/camera-calibration-using-opencv/

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

​[openCV Calibration] 相机矫正相关推荐

  1. 要matlab标定数据做双目相机矫正OpenCV C++

    双目相机矫正 系列文章来了,C/CPP实现双目矫正(不使用OpenCV)及矫正源码解析正在更新中. 开始本文内容 标定步骤: matlab标定较为准确,命令行中输入stereoCameraCalibr ...

  2. OpenCV全向相机校准Omnidirectional Camera Calibration

    OpenCV全向相机校准 全向相机校准 前言 单相机校准 立体校准 图像校正 立体声重建 全向相机校准 前言 本教程将介绍全向摄像机校准模块的以下部分: 校准单个摄像机. 校准一对立体声摄像机. 校正 ...

  3. 使用OpenCV进行相机标定

    1. 使用OpenCV进行标定 相机已经有很长一段历史了.但是,伴随着20世纪后期的廉价针孔照相机的问世,它们已经变成我们日常生活的一种常见的存在.不幸的是,这种廉价是由代价的:显著的变形.幸运的是, ...

  4. Camera Calibration 相机标定

    Camera Calibration 相机标定 一.相机标定方法 在opencv中提供了一组函数用于实现相机的标定,标定返回的值包括:相机内参矩阵(fx fy xc yc).相机外参矩阵(R t)以及 ...

  5. C/C++实现双目矫正(不使用OpenCV内部函数)及矫正源码解析

    C/CPP实现双目矫正(不使用OpenCV)及矫正源码解析 这篇文章是之前[要matlab标定数据做双目相机矫正OpenCV C++]的补充,再加上了双目矫正的原理及代码注释.更新中-- 本文所需数据 ...

  6. 用VISP+Opencv做相机到机械臂的标定

    用VISP+Opencv做相机到机械臂的标定(hand eye calibration) 首先要解决的问题如下图,需要知道的是camera到robot base(world)的变换矩阵: 然后可以简化 ...

  7. python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)

    python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码 一.前言 今天的低价单孔摄像机(照相机)会给图像带来很多畸变.畸变主要有两 种:径向畸变和切想畸变.如下图所示,用 ...

  8. 利用OpenCV执行相机校准

    文章目录 什么是相机校准,为什么它很重要? 为什么要使用棋盘? 使用 OpenCV 执行相机校准 打印棋盘 测量正方形长度 从不同的距离和方向拍摄棋盘的照片 找到角点 编写用于相机校准的 Python ...

  9. OpenCV与相机的关系

    经常碰到朋友,尤其是计算机视觉初学者朋友问到我关于OpenCV怎么获取图片,怎么把OpenCV跟相机结合起来这一类的问题.本人不才,不过,在平时的工作中,都接触到这方面,今天特意发文章给有些朋友们解惑 ...

最新文章

  1. APK加壳【1】初步方案实现详解
  2. Ajax请求Session超时解决
  3. redis rdb aof区别_聊一聊RDB、AOF在redis持久化里的底层原理
  4. Code POJ - 1780(栈模拟dfs)
  5. 关于多线程的一点补充
  6. SQL的Join使用图解教程
  7. C程序设计语言现代方法02:C语言基本概念
  8. 前端系列之HTML基础知识概述
  9. 36 岁清华 IT 男,死前对妈妈说:我好累
  10. Spring boot 拦截器(HandlerInterceptor) 与 自定义资源映射虚拟路径,WebMvcConfigurer
  11. php要求输入是个数求平均值、_如何在Excel中求数字个数
  12. R语言中三线表是什么?使用table1包绘制(生成)三线表实战
  13. 用户画像第四章(企业级360°用户画像_标签开发_挖掘标签_ 客户价值模型-RFM)
  14. excel转置怎么操作_EXCEL/WPS如何快速将一行转置成一列,一列转置成一行?
  15. Elasticsearch+Hbase实现海量数据秒回查询
  16. 如何快速发表一篇SCI论文
  17. mos管和三极管的区别/管子的三种状态
  18. Robomaster小陀螺
  19. 盘符没有显示,磁盘管理器提示磁盘没有初始化(已解决)
  20. 用C/C++打造电脑微信多开神器,值得体验一把!

热门文章

  1. 会声会影点击无任何反应问题
  2. dump_stack()
  3. 68-C语言-打鱼晒网问题
  4. 给小铄做的围棋入门思道导图
  5. 【云服务器部署】---Linux下安装MySQL
  6. Codeforces Round #839 (Div. 3) C. Different Differences
  7. matlab在管理学中的应用简matlab基础【三】
  8. java url转urf8_怎么把图片路径64位编码的转化成正常的路径,不编码的
  9. slicer安装_对3D Slicer软件安装离线扩展包
  10. 在Slicer中添加点、直线和曲线