【OpenCV】摄像机标定+畸变校正
摄像机标定
本文目的在于记录如何使用MATLAB做摄像机标定,并通过OpenCV进行校正后的显示。
首先关于校正的基本知识通过OpenCV官网的介绍即可简单了解:
http://docs.opencv.org/2.4/doc/tutorials/calib3d/camera_calibration/camera_calibration.html
对于摄像机我们所关心的主要参数为摄像机内参,以及几个畸变系数。上面的连接中后半部分也给了如何标定,然而OpenCV自带的标定程序稍显繁琐。因而在本文中我主推使用MATLAB的工具箱。下面让我们开始标定过程。
标定板
标定的最开始阶段最需要的肯定是标定板。两种方法,直接从opencv官网上能下载到:
http://docs.opencv.org/2.4/_downloads/pattern.png
方法二:逼格满满(MATLAB)
J = (checkerboard(300,4,5)>0.5);
figure, imshow(J);
- 1
- 2
- 1
- 2
采集数据
那么有了棋盘格之后自然是需要进行照片了。不多说,直接上程序。按q键即可保存图像,尽量把镜头的各个角度都覆盖好。
#include "opencv2/opencv.hpp"
#include <string>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
VideoCapture inputVideo(0);
//inputVideo.set(CV_CAP_PROP_FRAME_WIDTH, 320);
//inputVideo.set(CV_CAP_PROP_FRAME_HEIGHT, 240);
if (!inputVideo.isOpened())
{
cout << "Could not open the input video " << endl;
return -1;
}
Mat frame;
string imgname;
int f = 1;
while (1) //Show the image captured in the window and repeat
{
inputVideo >> frame; // read
if (frame.empty()) break; // check if at end
imshow("Camera", frame);
char key = waitKey(1);
if (key == 27)break;
if (key == 'q' || key == 'Q')
{
imgname = to_string(f++) + ".jpg";
imwrite(imgname, frame);
}
}
cout << "Finished writing" << endl;
return 0;
}
保存大约15到20张即可。大家可以看到我的方法,直接对着实验室的屏幕拍摄的。这个阶段有个注意事项就是测量好屏幕上每个方格的大小,这个标定的时候会用到。
进行标定
直接而在MATLAB的Command Window里面输入cameraCalibrator即可调用标定应用。
首先先把之前照好的图像添加进去,这是出现:
这就是之前让你记录的标定板中每个方格的大小。
输入无误后就涉及到最关键的一步了(MATLAB的这个实在太方便了,都是傻瓜式操作),选择参数。
为什么说他关键呢,因为如果你仔细阅读了OpenCV的说明之后你会大概明白畸变参数,总共有五个,径向畸变3个(k1,k2,k3)和切向畸变2个(p1,p2)。
径向畸变:
切向畸变:
以及在OpenCV中的畸变系数的排列(这点一定要注意k1,k2,p1,p2,k3),千万不要以为k是连着的。
并且通过实验表明,三个参数的时候由于k3所对应的非线性较为剧烈。估计的不好,容易产生极大的扭曲,所以我们在MATLAB中选择使用两参数,并且选择错切和桶形畸变。
点击开始后等待一段时间即可完成标定。并且MATLAB给出的可视化还是很不错的,可以对比校正前后的样子。
点击show Undistorted即可看到无畸变的图像。
到这为止,你已经完成了标定过程。选择导出参数,即可把参数进行保存。
保存后可以退出标定应用,在MATLAB主界面中将保存的Mat文件打开。
第二行就是参数
里面的RadialDistortion对应k1,k2,k3设置为0了。
TangentialDistortion对应p1,p2。
IntrinsicMatrix对应内参,注意这个和OpenCV中是转置的关系,注意不要搞错。
对应
OpenCV中查看标定的结果
直接上代码。
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
VideoCapture inputVideo(0);
if (!inputVideo.isOpened())
{
cout << "Could not open the input video: " << endl;
return -1;
}
Mat frame;
Mat frameCalibration;
inputVideo >> frame;
Mat cameraMatrix = Mat::eye(3, 3, CV_64F);
cameraMatrix.at<double>(0, 0) = 4.450537506243416e+02;
cameraMatrix.at<double>(0, 1) = 0.192095145445498;
cameraMatrix.at<double>(0, 2) = 3.271489590204837e+02;
cameraMatrix.at<double>(1, 1) = 4.473690628394497e+02;
cameraMatrix.at<double>(1, 2) = 2.442734958206504e+02;
Mat distCoeffs = Mat::zeros(5, 1, CV_64F);
distCoeffs.at<double>(0, 0) = -0.320311439187776;
distCoeffs.at<double>(1, 0) = 0.117708464407889;
distCoeffs.at<double>(2, 0) = -0.00548954846049678;
distCoeffs.at<double>(3, 0) = 0.00141925006352090;
distCoeffs.at<double>(4, 0) = 0;
Mat view, rview, map1, map2;
Size imageSize;
imageSize = frame.size();
initUndistortRectifyMap(cameraMatrix, distCoeffs, Mat(),
getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0),
imageSize, CV_16SC2, map1, map2);
while (1) //Show the image captured in the window and repeat
{
inputVideo >> frame; // read
if (frame.empty()) break; // check if at end
remap(frame, frameCalibration, map1, map2, INTER_LINEAR);
imshow("Origianl", frame);
imshow("Calibration", frameCalibration);
char key = waitKey(1);
if (key == 27 || key == 'q' || key == 'Q')break;
}
return 0;
}
相信此时你的镜头的畸变也得到了修复。
还有就是之前讨论的为什么选2系数而不是3系数。因为。。。。。。。
下面是三系数的修正结果,惨不忍睹啊。
【OpenCV】摄像机标定+畸变校正的更多相关文章
- Matlab 摄像机标定+畸变校正
博客转载自:http://blog.csdn.net/Loser__Wang/article/details/51811347 本文目的在于记录如何使用MATLAB做摄像机标定,并通过opencv进行 ...
- OpenCV两种畸变校正模型源代码分析以及CUDA实现
图像算法中会经常用到摄像机的畸变校正,有必要总结分析OpenCV中畸变校正方法,其中包括普通针孔相机模型和鱼眼相机模型fisheye两种畸变校正方法. 普通相机模型畸变校正函数针对OpenCV中的cv ...
- OpenCV畸变校正源代码分析
图像算法中会经常用到摄像机的畸变校正,有必要总结分析OpenCV中畸变校正方法,其中包过普通针孔相机模型和鱼眼相机模型fisheye两种畸变校正方法. 普通相机模型畸变校正函数针对OpenCV中的cv ...
- OpenCV畸变校正原理以及损失有效像素原理分析
上一篇博客简要介绍了一下常用的张正友标定法的流程,其中获取了摄像机的内参矩阵K,和畸变系数D. 1.在普通相机cv模型中,畸变系数主要有下面几个:(k1; k2; p1; p2[; k3[; k4; ...
- [OpenCV-Python] OpenCV 中摄像机标定和 3D 重构 部分 VII
部分 VII摄像机标定和 3D 重构 OpenCV-Python 中文教程(搬运)目录 42 摄像机标定 目标 • 学习摄像机畸变以及摄像机的内部参数和外部参数 • 学习找到这些参数,对畸变图像进行修 ...
- 机器视觉学习笔记(5)——基于OpenCV的单目摄像机标定
本文CameraCalibrator类源代码来自于OpenCV2 计算机视觉编程手册(Robert Laganiere 著 张静 译) 强烈建议阅读机器视觉学习笔记(4)--单目摄像机标定参数说明之后 ...
- 用OpenCV进行摄像机标定
用OpenCV进行摄像机标定 照相机已经存在很长时间了.然而,随着廉价针孔相机在20世纪末的引入,日常生活中变得司空见惯.不幸的是,这种廉价伴随着它的代价:显著的扭曲.幸运的是,这些常数,通过校准和一 ...
- Opencv——相机标定
相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的选择和平移矩阵),内参和外参系数可以对之后相机拍摄的图像就进行矫正,得到畸变相对很小的图像. 相机标定的输入:标定图像上所有内角 ...
- 使用OpenCV进行标定(转载)
转载自牛猫靖 http://www.cnblogs.com/2008nmj/p/6278076.html 使用OpenCV进行相机标定 1. 使用OpenCV进行标定 相机已经有很长一段历史了.但是 ...
随机推荐
- Python操作Saltstack
1.代码 # -*- coding:utf-8 -*- import urllib.request import urllib.parse import json class saltAPI(): d ...
- 20155211《网络对抗》Exp02 后门原理与实践
20155211<网络对抗>Exp02 后门原理与实践 实验内容 (1)使用netcat获取主机操作Shell,cron启动 (2)使用socat获取主机操作Shell, 任务计划启动 ( ...
- Macaca 基础原理浅析
导语 前面几篇文章介绍了在Macaca实践中的一些实用技巧与解决方案,今天简单分析一下Macaca的基础原理.这篇文章将以前面所分享的UI自动化Macaca-Java版实践心得中的demo为基础,进行 ...
- mybatis源码-解析配置文件(二)之解析的流程
目录 1. 简介 2. 配置文件解析流程分析 2.1 调用 2.2 解析的目的 2.3 XML 解析流程 2.3.1 build(parser) 2.3.2 new XMLConfigBuilder( ...
- MQ见解
MQ 消息队列是系统级.模块级的通信.RPC是对象级.函数级通信. 1) 什么是推模式,什么是拉模式 2) 有没有消息丢失情况,如何防止 3) MQ用来解决什么问题 4) 你们用的什么MQ,为什么要用 ...
- okhttp3.4.1+retrofit2.1.0实现离线缓存
关于Retrofit+OkHttp的强大这里就不多说了,还没了解的同学可以自行去百度.这篇文章主要讲如何利用Retrofit+OkHttp来实现一个较为简单的缓存策略:即有网环境下我们请求数据时,如果 ...
- 阿里云centos 安装禅道
下载 我的阿里云服务器系统是 centos6.8 64 位,下载的禅道版本是 Linux 64位一键安装包(适用于Linux 64位) 由于阿里云服务器没桌面,所以下载用不了浏览器,可考虑在本地下载后 ...
- (转载)利用SIFT和RANSAC算法(openCV框架)实现物体的检测与定位,并求出变换矩阵(findFundamentalMat和findHomography的比较) 置顶
原文链接:https://blog.csdn.net/qq_25352981/article/details/46914837#commentsedit 本文目标是通过使用SIFT和RANSAC算法, ...
- 如何基于 K8S 多租能力构建 Serverless Container
当前 Kubernetes 已经成为名副其实的企业级容器编排规范,很多云平台都开始提供兼容 Kubernetes 接口的容器服务.而在多用户支持方面,多数平台选择直接提供专属虚机集群,用户需要花费大量 ...
- 课堂讨论 alpha版最后总结
议时间:组队开发最后总结会议 星期一 下午4:30-5:30 会议地点:学院楼自习室 到会人员:唐野野 胡潘华 王永伟 魏孟 会议概要: 1.展示最后开发成果: 2.交流开发过程心得体会: 会 ...