简易激光测距 手持式激光测距仪

抽空做了个简单的激光测距的小东西,这个方案简单易实现,而且可以用现有的opencv库很容易作进一步性能改进。之前在一个老外的网上看到介绍,现在找不到了。基本原理:



这个图很清晰的解释了测距的基本原理,假设激光投射到目标物体上,同时位于同一平面的摄像头画面内能够捕捉到激光照射点,(所以要求摄像头和激光头之间的距离h不能太远),激光光线和摄像头成像轴完全平行。这样,照射到目标物体的激光点和摄像头成像平面连线和摄像头轴线之间会有一个夹角theta,通过在摄像帧图像里面对这个激光点相对于轴心的像素点的判断,可以确定出theta的大小,从而就能得到距离D。D越远,画面中激光点离中心越近,D越小,激光点离中心越远。画面的激光点判断可以简单的认为最亮的点就是激光点,逐像素扫描。当然可以使用opencv的API实现更复杂更精确的激光点确定方法。
整个算法比较简单但是很实用。

D很容易由下式得出:


所以只有一个未知量theta,theta由几个因素决定,一个是画面中激光点离轴心的距离pfc,这个可以通过帧画面的处理得到,另外两个是固定量,和具体摄像头有关,每个摄像头都不一样,rpc表示每个像素的弧度(其实就是与pfc想乘的因子),还有 一个是弧度偏移补偿量,用于矫正。

这样我们可以得到下式:


经过上面的分析,只有pfc一个变量,其他的都算已知量。那怎么得到rpc和ro呢?可以通过实验得到:在实际试验中先得到两组数据,分别是激光点离中心的距离和真实的距离D
矫正数据
光点离中心距离D (cm)
61137
13764

代入137 =7.350/tan(61x+y)64 =7.350/tan(137x+y)
这样得到

Offset (ro)=0.0053867radians

Gain (rpc)=0.000795302radians/pixel

采用的摄像头,很普通的那种,640*480像素

做好了的实验板:



代码:
#include <iostream>
usingnamespacestd;
#include"opencv/cv.h"
#include"opencv2/highgui/highgui.hpp"

intmain( int argc, char** argv ) {
cvNamedWindow( "Example", CV_WINDOW_AUTOSIZE );
CvCapture* capture;
if (argc==1) {
capture= cvCreateCameraCapture( 0 );
} else{
capture= cvCreateFileCapture( argv[1] );
}
assert( capture != NULL );

IplImage* frame;
while(1){
frame= cvQueryFrame( capture );
if( !frame ) break;

//对取到的图像做处理

unsignedint W, H;
unsignedint row, col;
unsignedlong i;
unsignedint max_row;
unsignedint max_col;
简易激光测距 手持式激光测距仪
unsignedchar max_val = 0;

constdouble gain = 0.000795302;
constdouble offset = 0.0053867;
constdouble h_cm = 7.350; //我的摄像头和激光头距离7.35cm
double range;
unsignedint pixels_from_center;

W= frame->width;
H= frame->height;
unsignedchar*img_d = (unsignedchar*)frame->imageData;

//假设激光点是最亮点,最简单的实现,一般来说确实是这样,但是在背景干扰大的情况下会误判,还有很大的提高空间

for(row = 0; row < H; row++) {
for(col = 0; col < W; col++) {
i = (unsignedlong)(row*3*W+ 3*col);

if (*(img_d + i) >= max_val)
{
max_val= *(img_d + i);
max_row= row;
max_col= col;
}
}
}

max_val= 0;

//找到了画十字线标注
for(row = 0; row < H; row++) {
for(col = 0; col < W; col++) {
i = (unsignedlong)(row*3*W+ 3*col);
if((row == max_row) || (col == max_col))
*(img_d + i) =
*(img_d + i + 1) =
*(img_d + i + 2) = 255;
}
}

pixels_from_center = max_row - H/2;

//算出距离并打印出来
range= h_cm / tan(pixels_from_center * gain + offset);

cout<<"W= " <<W <<", H= " <<H <<", Max Value atx="
<<max_col <<", y= " <<max_row <<", range= "<<range <<endl;


cvShowImage( "Example", frame );
charc = cvWaitKey(10);
if( c == 27 ) break;
}
cvReleaseCapture( &capture );
cvDestroyWindow( "Example" );
}



实际测试中误差还算可以,在5%以内,最主要是激光点的判断还有很大提高空间,opencv提供了不少API,网上也有一些文章距离64cm:





距离152cm:


  

爱华网本文地址 » http://www.aihuau.com/a/25101014/225935.html

更多阅读

激光脱毛有副作用吗 激光脱毛一般多少钱

激光脱毛有副作用吗?近几年来,选择激光脱毛的人士越来越多,但一些女性表示对激光脱毛存在一大疑虑,她们担心激光脱毛后会出现副作用,针对这个实在性的问题,请有关专家为大家做出详细介绍。疑虑之一、激光脱毛影响排汗吗? 有的网友

近视眼激光手术价格 眼睛激光要多少钱

近视眼激光手术价格——简介 虽然近视眼,但还是不想戴眼镜,隐形眼镜又太干,怎么办?看来唯一的方法就是去做近视眼激光手术了。听说眼睛近视手术费用是笔大收费,近视眼激光手术价格要多少钱?近视眼激光手术价格——工具/原料

激光点痣会留疤吗?如何让不留疤? 激光点痣留疤吗

激光点痣会留疤吗?如何让不留疤?——简介每个人身上都会长出黑色的平的或高出皮肤的小点,医学上称为色素痣,俗称痣;痣每个人都有,但若是好在脸上,就不太好看了,很多人想把痣去掉,医学上比较常用的办法是用激光;问激光点痣会留疤吗?如何让不留疤

声明:《简易激光测距 手持式激光测距仪》为网友落影执迷离分享!如侵犯到您的合法权益请联系我们删除