赞
踩
最近研究了一下单目测距,关于单目测距的原理有各位大神的讲解,这里只写一些自已使用上的记录,使用环境为windows10+opencv3.1+vs2015。
买了一个摄像头(笔记本的定焦摄像头也可以),不知道具体参数,想用它实现测距功能。
原理上就是根据三角性的相似性,假设摄像头焦距为f,摄像头距物体距离为dmm,物体在图像中的尺寸为p个像素(假设物体水平放置,为水平上的长度),物体实际长度为xmm, 根据三角形相似性,有
显然,这里的焦距是以图像像素为单位的。
这里我们可以以棋盘纸为标准,用于计算相关参数,我所画的棋盘纸是在A4纸上打印的单元格为为20m*20mm,7行*10列个格,即boardSize为9*6。
显然,现在焦距f是未知的,为了计算f,我们可以在距摄像头距离d的位置横放一张带有棋盘的A4纸。
首先,我们估计一下摄像头的焦距,调整A4纸的位置,使的横放的A4纸的一边刚好填满图像的横坐标,测量此时A4纸距摄像头的距离d1 = 300mm,因为A4纸的尺寸是固定的为210mm*297mm,若图像尺寸为640*480,则也就是将297mm的宽度填满图像中的640像素,这样就有
于是可以计算出焦距f。这里的值只是个大概估计值,可以用来后来用棋盘纸校准的时候相对照估量。
下面使用棋盘纸进行单目校准,关于棋盘纸的单目校准原理也有很多大神讲解,下面贴出来的仅为部分代码。里面缺少类成员函数声明以及相关头文件。
- //打开摄像头
- bool CCamera::OpenCamera(int index, VideoCapture &cap)
- {
-
- if (cap.isOpened())
- {
- std::cout << "警告!摄像头"<<index<<"已经被打开!" << std::endl;
- }
-
- if (cap.open(index))
- {
-
- cout << "摄像头" << index << "打开成功!" << endl;
- }
- else
- {
- cout << "Error!摄像头" << index << "打开失败." << endl;
- return false;
- }
-
- return true;
-
- }
- //获取图像
- void CCamera::GetCameraImage(VideoCapture cap, Mat &img)
- {
- if (!cap.isOpened())
- {
- cout << "摄像头未打开!" << endl;
- return;
- }
-
- cap >> img;
-
-
- }
- //保存图像
- int CCamera::SaveCameraImage(VideoCapture cap, int nGroup)
- {
-
- Mat img;
-
- string imgName;
- int index = 1;
-
- cout << "--------操作指南--------" << endl;
- cout << "按'q'或'Q'退出图像采集\n";
- cout <<
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。