精品自制激光测距仪.docx

上传人:b****5 文档编号:12707404 上传时间:2023-04-21 格式:DOCX 页数:14 大小:291.20KB
下载 相关 举报
精品自制激光测距仪.docx_第1页
第1页 / 共14页
精品自制激光测距仪.docx_第2页
第2页 / 共14页
精品自制激光测距仪.docx_第3页
第3页 / 共14页
精品自制激光测距仪.docx_第4页
第4页 / 共14页
精品自制激光测距仪.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

精品自制激光测距仪.docx

《精品自制激光测距仪.docx》由会员分享,可在线阅读,更多相关《精品自制激光测距仪.docx(14页珍藏版)》请在冰豆网上搜索。

精品自制激光测距仪.docx

精品自制激光测距仪

激光:

基于摄像头的激光测距仪

2009-02—2321:

45

介绍

有很多现成的测距组件包括超声波、红外线、甚至是激光测距仪。

这些设备运行的很好,但是对于飞行机器人来说,重量是一个主要考虑因素。

一个可行的办法是增加现有组件的功能,并安装在机身上.例如微型空中机器人的有效载荷是100g。

它能利用USB连接的摄像头(或mini无线摄像头)执行视觉任务,例如避障等。

更好的是,如采用两个摄像头,能提供立体的机器视觉,这样能增强避障性能,因为双镜头提供了视觉深度。

但缺点是需要增加另外一个摄像头的重量.这篇文章就是讨论如何利用一个激光笔和一个摄像头来提供一个单镜头机器视觉和测距的.

这个项目很大一部分是基于下面这个教程的

http:

//www.eng。

buffalo。

edu/ubr/ff03laser。

php

工作原理

下图显示了如何将激光点投射到目标物上,并在摄像头上显示.摄像头和激光点的距离是可以通过计算而得出的.公式很简单,因此这个技术在需要很快运行的机器视觉应用上是适合的.

 

介绍一下工作原理.一束激光被投射到目标物上,并在摄像头上被显示。

激光束被认为是理想的平行于摄像头的中心光轴。

激光点由摄像头的其余部分所捕获。

一个简单的计算就是寻找最亮点。

如果设激光点就是这个场景的最亮点(似乎在室内我的激光发射器确实是最亮的),那么这个点的位置在图帧中的位置是确定的.然后我们只需要计算这个点在沿着y轴的距离,就能计算出目标物离摄像头的距离,激光点距离中心越近,离目标物越远。

如同公式所示,距离D是可以被计算出来的。

为了计算这个等式,我们需要知道激光器和摄像头之间的距离h,这是个常数,还有角度,角度可以计算。

其中:

pfc=从焦平面到中心的像素数量

rpc=单个像素的弧度

ro=弧度补偿(弥补对齐错误)代入上式,我们得到:

这样,从图像中就能将焦平面到激光点像素数计算出来。

那其他的常数怎么办呢?

我们需要执行一个校准来得到这些数据。

为了校准这个系统,我们需要收集一系列测量的数据,每次测得的目标物的距离和这个激光点离中心点的像素数。

数据如下

校正数据

pixelsfromcenter

actualD(cm)

103

29

81

45

65

58

55

71

49

90

45

109

41

127

39

159

37

189

35

218

使用下面的公式,我们能够利用激光器和摄像头之间的距离h和真实距离计算出真实的角度:

θactual=真实角度

Dactual=真实距离(测量得出)

现在我们有了公式中的每个数值,我们可以利用一个关系式来计算点离中点的像素数。

我用了一个线性关系式。

这个公式看起来很有用,……

从我的校正数据中,我计算出:

Offset(ro)=—0.056514344radians

Gain(rpc)=0。

0024259348radians/pixel

使用:

下表是列举了根据上面ro和rpc值计算出的距离值,实际距离值和误差:

RoboticFan

实际和计算的测量数据

pixelsfromcenter

calcD(cm)

actualD(cm)

%error

103

29.84

29

2.88

81

41.46

45

—7。

87

65

57.55

58

-0。

78

55

75。

81

71

6。

77

49

93.57

90

3。

96

45

110。

85

109

1.70

41

135。

94

127

7.04

39

153.27

159

—3.60

37

175.66

189

—7.06

35

205.70

218

—5。

64

所需零部件

我的测距仪没有多少部件。

我使用一块硬纸板来固定激光发射器和摄像头.摄像头和激光发射器被平行的布置在一起.

我组装的测距仪是这样的

软件

我通过两个方式编写了这个软件,一个是vc++,一个是VB。

你能发现VB版本的软件会比VC++的软件更容易一些,但是各有取舍。

VC++版本能够自由的加入其他软件中?

VB版本需要第三方软件支持(在VisualStudio中)

VisualBasic

vb_laser_ranger.zip

这里可以下载到我的VB版本软件.

要使用上面的程序,你必须要安装VideoOCXActiveX控件

主程序如下:

PrivateSubexit_Click()

'onlyifrunning.。

.

If(Timer1。

Enabled)Then

Timer1。

Enabled=False’StopTimer

VideoOCX。

Stop

VideoOCX.CloseEndIfEnd

EndSub

PrivateSubStart_Click()'InitVideoOCXControl,allocatememoryandstartgrabbingIf(NotTimer1.Enabled)Then

Start.Caption=”Stop”'DisableinternalerrormessagesinVideoOCX

VideoOCX。

SetErrorMessagesFalse'Initcontrol

If(NotVideoOCX。

Init)Then

'Initfailed。

Displayerrormessageandendsub

MsgBoxVideoOCX。

GetLastErrorString,vbOKOnly,”VideoOCXError”

End

Else

'Allocatememoryforglobalimagehandle

capture_image=VideoOCX。

GetColorImageHandle

’result_image=VideoOCX_Processed.GetColorImageHandleTimer1.Enabled=True'Startcapturetimer’StartCapturemode

If(NotVideoOCX.Start)Then

'Startfailed。

Displayerrormessageandendsub

MsgBoxVideoOCX.GetLastErrorString,vbOKOnly,”VideoOCXError”

End

EndIf

EndIf

Else

Start.Caption="Start"

Timer1.Enabled=False'StopTimer

VideoOCX.Stop

VideoOCX。

Close

EndIfEndSub

PrivateSubTimer1_Timer()

'Timerforcapturing—handlesvideoOCXTools

DimmatrixAsVariant

Dimheight,widthAsInteger

Dimr,cAsInteger

Dimmax_r,max_cAsInteger

Dimmax_redAsInteger

Dimgain,offsetAsVariant

Dimh_cmAsVariant

DimrangeAsInteger

Dimpixels_from_centerAsInteger’Calibratedparameterforpixeltodistanceconversion

gain=0.0024259348

offset=—0.056514344

h_cm=5。

842max_red=0’Captureanimage

If(VideoOCX.Capture(capture_image))Then'VideoOCX。

Showcapture_image’Matrixtransformationinitialization

matrix=VideoOCX。

GetMatrix(capture_image)height=VideoOCX.GetHeight

width=VideoOCX.GetWidth’Imageprocessingcode’Thelaserdotshouldnotbeseenabovethemiddlerow(withalittlepad)

Forr=height/2-20Toheight—1’Ourphysicalsetupisroughlycalibratedtomakethelaser

'dotinthemiddlecolumns。

.dontbotherlookngtoofaraway

Forc=width/2-25Towidth/2+24’Lookforthelargestredpixelvalueinthescene(redlaser)

If(matrix(c,r,2)〉max_red)Then

max_red=matrix(c,r,2)

max_r=r

max_c=c

EndIf

Nextc

Nextr’Calculatethedistanceforthelaserdotfrommiddleofframe

pixels_from_center=max_r-120

’Calculaterangeincmbasedoncalibratedparameters

range=h_cm/Tan(pixels_from_center*gain+offset)

’Printlaserdotpositionrowandcolumntoscreen

row_val。

Caption=max_r

col_val.Caption=max_c’Printrangetolaserilluminatedobjecttoscreen

range_val.Caption=range'Drawaredverticallinetointersecttarget

Forr=0Toheight-1

matrix(max_c,r,2)=255

Nextr’Drawaredhorizontallinetointersecttarget

Forc=0Towidth—1

matrix(c,max_r,2)=255

NextcVideoOCX。

ReleaseMatrixToImageHandle(capture_image)RoboticFanEndIfVideoOCX。

Showcapture_image

EndSub

截屏如下:

VisualC++

我的代码是基于PaulOh教授的教程。

你需要注意,当跟进这个教程的时候,一些必要的文件也许不再正常连接或丢失,他们可以在下面的位置下载。

qcsdk.exe

qc543enu。

exe

根据TRIPOD的教程的说明,可以在其源程序中插入一段用户自己的图像处理代码,在这里,我插入了下面的代码:

voidCTripodDlg:

:

doMyImageProcessing(LPBITMAPINFOHEADERlpThisBitmapInfoHeader)

{

//doMyImageProcessing:

Thisiswhereyou'dwriteyourownimageprocessingcode

//Task:

Readapixel'sgrayscalevalueandprocessaccordingly

unsignedintW,H;//WidthandHeightofcurrentframe[pixels]

unsignedintrow,col;//Pixel'srowandcolpositions

unsignedlongi;//Dummyvariableforrow-columnvector

unsignedintmax_row;//Rowofthebrightestpixel

unsignedintmax_col;//Columnofthebrightestpixel

BYTEmax_val=0;//Valueofthebrightestpixel

//Valuesusedforcalculatingrangefromcapturedimagedata

//thesevaluesareonlyforaspecificcameraandlasersetup

constdoublegain=0。

0024259348;//GainConstantusedforconverting

//pixeloffsettoangleinradians

constdoubleoffset=—0.056514344;//OffsetConstant

constdoubleh_cm=5.842;//Distancebetweencenterofcameraandlaser

doublerange;//Calculatedrange

unsignedintpixels_from_center;//Brightestpixellocationfromcenter

//notbottomofframecharstr[80];//Toprintmessage

CDC*pDC;//Devicecontextneedtoprintmessage

RoboticFan

W=lpThisBitmapInfoHeader—>biWidth;//biWidth:

numberofcolumns

H=lpThisBitmapInfoHeader->biHeight;//biHeight:

numberofrowsfor(row=0;row

for(col=0;col〈W;col++){

//Recalleachpixeliscomposedof3bytes

i=(unsignedlong)(row*3*W+3*col);//Ifthecurrentpixelvalueisgreaterthananyother,itisthenewmaxpixel

if(*(m_destinationBmp+i)>=max_val)

max_val=*(m_destinationBmp+i);

max_row=row;

max_col=col;

}

//Aftereachframe,resetmaxpixelvaluetozero

max_val=0;

for(row=0;row

for(col=0;col

i=(unsignedlong)(row*3*W+3*col);//Drawawhitecross-hairoverbrightestpixelintheoutputdisplay

if((row==max_row)||(col==max_col))

*(m_destinationBmp+i)=

*(m_destinationBmp+i+1)=

*(m_destinationBmp+i+2)=255;

//Calculatedistanceofbrightestpixelfromcenterratherthanbottomofframe

pixels_from_center=120-max_row;

//Calculaterangeincmbasedonbrightpixellocation,andsetupspecificconstants

range=h_cm/tan(pixels_from_center*gain+offset);

//Toprintmessageat(row,column)=(75,580)

pDC=GetDC();

//Displayframecoordinatesaswellascalculatedrange

sprintf(str,"MaxValueatx=%u,y=%u,range=%fcm”,max_col,max_row,range);

pDC—〉TextOut(75,580,str);

ReleaseDC(pDC);

}

完整的代码可以在下面下载到:

LaserRange.zip

可执行文件可在下面下载到:

LaserRange.exe

注意,为了执行这个文件,你可能需要qcsdk和qc543这两个驱动文件。

下面是摄像头激光测距仪的工作截图,注意它是如何工作的。

在第二个例子中,有两个激光点,其中的一个是激光点在摄像头里面的反射,这个反射点由于没有那么强烈的,所以不适用于运算法则.

将来的工作

一个重要的改进就是将点改为线,这样可以计算每个光柱的距离而不是单个的光柱。

这样的设置可以使车辆能够探测最大的前进距离,同样的,障碍物的最小距离也可以被探测到。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 计算机硬件及网络

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1