matlab mat文件变成图片_计算机视觉入门项目:手把手教你利用Matlab实现摄像头单目标定...

单目标定

摄像头的标定是每个计算机视觉初学者绕不过去的坑,相比对数学要求较高的双目标定,单目标定可谓简单许多,这里作者手把手来教你如何利用Matlab标定工具箱来实现摄像头的单目标定。

一、环境准备:

标定工具:MatlabR2019b(这个版本上下也都可以)

运行环境:Xcode(MacOS)+ opencv4.1.1(只要有C++和opencv环境的即可)

棋盘格一张:测量好每个方格的大小,这个标定的时候会用到。(这步必做哦)

Tips:不要选择正方形,即横竖格子数量相同的棋盘,否则后面标定过程中,Matlab会有一个Warning:“The checkerboard must be asymmetric: one side should be even, and the other should be odd.Otherwise, the orientation of the board may be detected incorrectly.”大体意思就是棋盘必须不对称:一面应为偶数,另一面应为奇数,否则,可能会错误地检测到板的方向。

直接给你一张图吧,知道你懒:

1a2ee0079435dc1743a01fd0be6cffdc.png

二、操作步骤(附详细代码):

  • 首先用IDE运行以下代码,按下“q”键拍摄一张图片

  • 拍摄约15~20张相片(各个角度和方向)

  • 相片会存放在工程文件夹中,因为matlab将以访问路径的方式添加相片,为了方便,建议先弄清楚相片的路径

#include "opencv2/opencv.hpp"
#include
#include

using namespace cv;
using namespace std;

int main()
{
VideoCapture inputVideo(0); //视情况选择预标定摄像头
//inputVideo.set(CAP_PROP_FRAME_WIDTH, 320); //可选项,调整窗口大小
//inputVideo.set(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; //按ESC退出
if (key == 'q' || key == 'Q')
{
imgname = to_string(f++) + ".jpg"; //输出文件名为 f.jpg, 保留在工程文件夹中
imwrite(imgname, frame);
}
}
cout << "Finished writing" << endl;
return 0;
}
  • 打开Matlab,在命令行中输入cameraCalibrator命令,回车打开标定程序(如下图)

b8bfa9b6420778ce0e315ddbe3a8634f.png

  • 点击Add Images,添加刚刚工程中的相片84c2cfd4e57f7f3e20f1ffac76389d2b.png

  • 输入每个格子的大小,默认为毫米528aaa26de106fe36096a11c2d50bb50.png

  • 设定参数16dd6c40cbbbaa1d2350c4818fb6e7d1.png

  • 笔者是这样设置的680ed61b08f52d6d7bfe1503d5d642bf.png

  • 然后点击Calibrate开始标定,结果如下图所示

49eba3843fafa2ef8b5b570bb6b1b596.png

  • 左边箭头所指可以查看矫正后的图像,右边箭头点击保存参数3e766d86da453e8d3b3935aaa6c462ac.png

  • 然后给输出文件一个名字,退出标定程序,会在主界面看到如下图所示16d60a9b7cbc6ab6918207eb6a63bbbe.png

  • 这里我们主要需要的是内参矩阵、径向畸变和切向畸变68abb6074d71541ed866da085e7db748.png

  • 然后在主程序中输入cameraParams.Intrinsics以及cameraParams.IntrinsicMatrix我们会得到下图所示的详细参数

72978de42c1e3b7ae06166436c77a0df.png

  • 既然得到了参数,那么下一步就是在程序中对摄像头实现矫正啦

  • 我们需要把参数写到程序中去,我们需要以下这几个参数,可以参考下面代码中笔者对应的参数位置,但其实一细看,就是在opencv中要对矩阵求一次转置,再把矩阵中对应位置赋值。

  • 然后用IDE运行代码b95ee85b2cc221443674b65c1671aa9d.png93c959a3a265586cb3c3a6741579a5cc.png

#include "opencv2/opencv.hpp"
#include

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) = 6.489845e+02; //对应内参矩阵
cameraMatrix.at<double>(0, 1) = -0.2892;
cameraMatrix.at<double>(0, 2) = 3.279820e+02;
cameraMatrix.at<double>(1, 1) = 6.489241e+02;
cameraMatrix.at<double>(1, 2) = 2.395932e+02;

Mat distCoeffs = Mat::zeros(5, 1, CV_64F);
distCoeffs.at<double>(0, 0) = -0.0339; //对应Radial Distortion 径向畸变
distCoeffs.at<double>(1, 0) = 0.3045;
distCoeffs.at<double>(2, 0) = -0.0033; //对应Tangential Distortion 切向畸变
distCoeffs.at<double>(3, 0) = 0.0012;
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;
}

  • 这里由于笔者未能找到合适的场景,所以用纸巾挡了一下镜头,但是效果还是很明显的,下面的处理后的镜头视野畸变被矫正35700e42f688ae4bd3926ecc04e1e6f7.png

  • 最后如果你也得到了类似效果,那么恭喜你,大功告成!

公众号篇幅有限,有兴趣的小伙伴可以在我的CSDN上查看原文章。CSDN链接:https://blog.csdn.net/qq_45165703/article/details/104304583

参考博文:
https://blog.csdn.net/qq_40855366/article/details/81177201
https://blog.csdn.net/Loser__Wang/article/details/51811347

好了,今天这篇文章就到这里啦,相信你已经搞定了单目标定?,笔者会不定期做一些技术分享和工具使用心得,欢迎大家阅读和转发!

b88248a10036f0766d4597042379e6f2.png

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值