【OpenCV】摄像机标定+畸变校正_opencv相机畸变标定软件-程序员宅基地

技术标签: calibratio  MATLAB  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);

这里写图片描述

采集数据

那么有了棋盘格之后自然是需要进行照片了。不多说,直接上程序。按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系数。因为。。。。。。。
下面是三系数的修正结果,惨不忍睹啊。
这里写图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Loser__Wang/article/details/51811347

智能推荐

29、基于51单片机智能消防灭火小车 寻光自动红外壁障车设计_灭火小车设计方案-程序员宅基地

文章浏览阅读1k次,点赞2次,收藏16次。智能作为现代的新发明,是以后的发展方向,他可以按照预先设定的模式在一个环境里自动的运作,不需要人为的管理,可应用于科学勘探等等的用途。智能小车就是其中的一个体现,本次设计的多功能智能灭火避障小车,以STC89C52单片机作为微控制器,设计出一种可以寻找火源(火源以蜡烛模拟)和自动避开障碍物的小车。通过光敏晶体管传感器检测火源信号当检测到火源,小车自动调整姿态,对准火源。灭火电机启动将蜡烛吹灭实现模拟灭火。通过红外光电开关感应控制小车避障行驶。工作状态实时显示在1602液晶上。_灭火小车设计方案

Ubuntu虚拟机总是死机,然后重启就进不去打不开了怎么办_ubuntu卡死之后重启,打不开了-程序员宅基地

文章浏览阅读4.6k次。从网上搜到的方法都解决不了我的问题,分享一点我自己的实在的解决经验:养成保存快照的习惯,比什么方法都靠谱。 即打开VMWare->虚拟机->快照->拍摄快照,简单填写一下你现在做到的程度,然后点击拍摄快照,存一下,养成习惯,每做出些什么东西了,就存一个快照,哪天莫名其妙又死机了,开机又黑屏进不去了,直接用快照恢复到最近的进度继续做就好。..._ubuntu卡死之后重启,打不开了

LDR6028乐得瑞OTG充电直播数据方案-程序员宅基地

文章浏览阅读51次。随着type-c接口越来越普及,手机逐渐取消了3.5mm耳机接口,只留一个多功能type-c接口,这使得3.5mm有线耳机的用户多少有些不习惯,那为什么他们不选择使用无线耳机,笔者分析认为有以下几种原因:价格,有线耳机相比于无线耳机便宜,当然有线耳机也有昂贵品牌,这也是原来用户一直不舍得换的原因。音质,有线耳机确实比不少无线耳机音质要更好(估计是有线耳机不用考虑供电问题,耳机喇叭能做更高的功率,无线耳机因为要考虑电池续航,耳机喇叭要控制电量损耗,没法做更高的规格)。

Netty专题-程序员宅基地

文章浏览阅读147次。1.Netty是什么面试官:介绍一下自己对netty的认识吧!小伙砸~我:好的!我就用简单的几点来概括下netty吧Netty 是一个基于NIO 的 client-server(客户端服务端框架),使用它可以快速简单第开发网络应用程序。它极大地简化并优化了TCP和UDP套接字服务器等网络编程,并且性能以及安全性等很多方面甚至都要更好。支持多种协议 如FTP,SMTP,HTTP以及各种二进制和基于文本的传统协议。用官方的总结就是:Netty 成功地找到了一种在不妥协可维护和性能的情况下实现易于_netty专题

六个office免费学习的精品教程 office自学教程让你从小白到高手-程序员宅基地

文章浏览阅读4.4k次。今天给大家分享六个免费学习的精品教程,包括了word,ppt,excel常用的办公三剑客,学会这三个让你办公无忧,也能让你靠这些技术找到一份好工作,这些office自学教程让你从小白到高手。一.PPT零基础入门教程PPT教程PPT零基础,PPT入门小白脱白系列,让你从做PPT的小白到高手,职场无敌。学习地址为:https://www.bilibili.com/video/av1205327...

OpenGL 创建窗口/三角形VAO、VBO、EBO_opengl bao-程序员宅基地

文章浏览阅读963次,点赞3次,收藏7次。Day 1 使用OpenGL创建三角形程序运行效果VAO vertex array object 顶点数组对象VBO vertex buffer object 顶点缓冲对象EBO element(index) buffer object 索引缓冲对象VBO and VAOData Flow from CPU to GPUVertex Buffer Object (VBO)VBO..._opengl bao

随便推点

苍穹外卖12 (Apache POI操作 Excel 文件,导入工作台代码,导出运营数据Excel报表)_apache poi 导出excel-程序员宅基地

文章浏览阅读997次,点赞32次,收藏14次。Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是,我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。一般情况下,POI 都是用于操作 Excel 文件。Apache POI 的应用场景:银行网银系统导出交易明细各种业务系统导出Excel报表批量导入业务数据。_apache poi 导出excel

spring_创建user类怎么写-程序员宅基地

文章浏览阅读383次。spring知识点总结测试代码五、构建Maven项目5.1 新建项目使用IDEA打开已创建的文件夹目录5.2 选择Maven目录选择Maven项目5.3 GAV坐标GAV坐标六、Spring环境搭建6.1 pom.xml中引入Spring常用依赖6.2 创建Spring配置文件七、Spring工厂编码八、依赖与配置文件详解8.1 S..._创建user类怎么写

6.3.2Transmit OFF power——翻译_transmit on/off power-程序员宅基地

文章浏览阅读1k次。1、测试目的为了验证UE发射OFF功率低于测试要求中指定的值。过大的发射OFF功率可能会增加反向干扰(RoT),因此会减少其他UE的小区覆盖范围。2、测试适用性此测试适用于所有类型的NR UE版本15及更高版本。 注意:当前,此测试用例只能支持Band n257和PC3。3、测试说明1、初始条件初始条件是需要测试UE的一组测试配置,以及SS与UE一起采取的步骤以达到正确的测量状态。初始测试配置包括环境条件,测试频率,测试信道带宽和基于表5.3.5-1中指定的NR工作频带的子._transmit on/off power

Manjaro安装一款好用的截图工具Deepin-screenshot_manjaro dwm窗口下好用的截图软件-程序员宅基地

文章浏览阅读7.3k次,点赞2次,收藏7次。效果图安装yaourt deepin-screenshot自定义快捷键截图配置设置--->设备   keyboard--------&gt; 新建快捷键-->点击+号 使用:直接点一下键盘上的截屏键即可:PrtSc(是个缩写) ..._manjaro dwm窗口下好用的截图软件

网易云音乐移动端项目实战(分解上),2024年最新学it主要学什么-程序员宅基地

文章浏览阅读537次,点赞9次,收藏11次。/获取歌单的详情api 下的index.js//获取轮播图API/*0: pc1: android2: iphone3: ipad*///获取推荐歌单默认十条数据//获取歌单的详情router 下的index.jspath: ‘/’,},},routes})views下的listview.vue。

Intellij IDEA--生成UML类图的方法_intellij idea生成java uml-程序员宅基地

文章浏览阅读3.1k次。本文介绍Idea如何生成UML类图。_intellij idea生成java uml

推荐文章

热门文章

相关标签