K210实现单目测算距离—以21年电赛F题为例

K210实现单目测算距离—以21年电赛F题为例

单目测距在无人驾驶,路径规划中的地位越来越重要,比激光雷达和深度相机的成本更低,更适合于项目的开发。

原理

单目测算距离的原理就是初中物理上学的小孔成像原理,但是由于我们不知道高度,所以会造成深度丢失。所以我们第一步就是测量我们要测量物体的真实宽度和镜头的焦距。
镜头测算焦距,我们需要对着标定板拍照,然后将拍好的照片导入到Matlab中,计算出焦距。大家在初中学过相距和焦距之间的关系,相距应该在一倍焦距以内,因为焦距比较小,所以我们就将相距等于一倍焦距,这样误差也会很小。

程序

list(i.rect())

这个函数可以返回出所检测到目标画框出来的x,y坐标。

通过这个函数我们就可以得到图像的宽度

b=(int(list1[0])-int(list1[2]))

有可能它们相减得到的数据为负数,但现实生活中不可能存在负数,所以我们取绝对值。

if b<0:
                b=-b

其次我们只需要将像素宽度转化为实际宽度,我们k210采用的分辨率是22*224,感光元件为4,所以实际宽度为4/224×b

width_img=(4/224)*int(b)
L=int(width_True*0.75)/width_img/100  #物体实际的宽度

这样我们就可以算出大致的距离了,误差不会很大。


实测误差在3cm左右,这个误差个人觉得还是可以接受的。

完整代码

import sensor,image,lcd,time
import KPU as kpu
from machine import UART
from fpioa_manager import fm
lcd.init(freq=15000000)
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_hmirror(0)
sensor.run(1)
width_img=1
width_True=20
L=0
task = kpu.load("/sd/yolov3.kmodel")
f=open("anchors.txt","r")
anchor_txt=f.read()
L=[]
for i in anchor_txt.split(","):
    L.append(float(i))
anchor=tuple(L)
f.close()
f=open("lable.txt","r")
lable_txt=f.read()
lable = lable_txt.split(",")
f.close()
fm.register(10, fm.fpioa.UART1_TX, force=True)
fm.register(11, fm.fpioa.UART1_RX, force=True)
uart_A = UART(UART.UART1, 115200, 8, 1, 0, timeout=1000, read_buf_len=4096)
anchor = (0.3691, 0.2575, 0.4528, 0.4739, 0.6996, 0.5839, 0.9164, 0.9705, 2.3887, 1.7223)
sensor.set_windowing((224, 224))
a = kpu.init_yolo2(task, 0.5, 0.3, 5, anchor)
classes=["9","1","4","2","3","8","5","6","7" ]
while(True):
     img = sensor.snapshot()
     code = kpu.run_yolo2(task, img)
     if code:
         for i in code:
             a=img.draw_rectangle(i.rect())
             a = lcd.display(img)
             list1=list(i.rect())
             b=(int(list1[0])-int(list1[2]))
             if b<0:
                b=-b
             c=(list1[1]+list1[3])/2
             width_img=(4/224)*int(b)
             if width_img==0:
                width_img=1
             L=int(width_True*0.75)/width_img/100
             #print("物体是:",classes[i.classid()])
             #print("概率为:",100.00*i.value())
             #print("坐标为:",b,c)
             print("距离:",b)
             for i in code:
                 lcd.draw_string(i.x(), i.y(), '%f'%L, lcd.RED, lcd.WHITE)
                 #lcd.draw_string(i.x(), i.y()+12, '%f'%i.value(), lcd.RED, lcd.WHITE)
                 #lcd.draw_string(50, 200,str(b), lcd.RED, lcd.WHITE)
                 #lcd.draw_string(110, 200,str(c), lcd.RED, lcd.WHITE)
                 uart_A.write(classes[i.classid()]+'\r\n')
                 uart_A.write(str(b)+'\r\n')
                 uart_A.write(str(c)+'\r\n')
     else:
         a = lcd.display(img)
uart_A.deinit()
del uart_A
a = kpu.deinit(task)

来源:栈溢出工程师

物联沃分享整理
物联沃-IOTWORD物联网 » K210实现单目测算距离—以21年电赛F题为例

发表评论