测距

假定我们想通过OpenMV所获得的图像, 近似计算出小球离摄像头的距离, 我们应该如何去做?

参数定义

openmv_distance_detect_theory

摄像头视角的一半 α \alpha

小球边缘与镜头的水平线夹角 β \beta

纸板高度H H , 单位:m

纸板令画面满屏是距离镜头的距离L L, 单位:m

小球的实际半径 R R , 单位:m

小球距离镜头的距离 Ltarget L_{target}, 单位:m, 也就是我们想求得的值

摄像头画面上的高度H H', 单位:像素个数

画面中小球的半径R R', 单位:像素个数

假想的画面与镜头的距离L L' , 单位: 像素个数

操作步骤

  • STEP 1求得视角一半 α \alpha的值
  • STEP 2 求得所得图像, 小球的半径R R'
  • STEP 3 计算出大概的距离 Ltarget L_{target}

计算公式与推倒

实际上我们也不是真的要算出α \alpha

就是要求得H HL L

先说一下纸板是怎么会事儿, 为了要求得tan(α) tan(\alpha), 我们找一个纸板, 比例与镜头成像的比例最好相同 4:3

然后调整纸板与镜头之间的距离, 使得纸板刚刚充满整个画面, 记录下纸板与镜头之间的距离 L L , 与纸板的高度H H

tan(α)=H/(2L)=H/(2L) tan(\alpha) = H / (2*L) = H' / (2 * L')

L L' 是我们不知道的, 其他的值我们已经求出来了

所以 L=(HL)/H L' = (H' * L) / H

tan(β)=R/L=R/Ltarget tan(\beta) = R' / L' = R / L_{target}

可得 Ltarget=(RL)/R L_{target} = (R * L') / R'

带入L=(HL)/H L' = (H' * L) / H

使得Ltarget=(1/R)(RHL)/H L_{target} = (1/R') * (R * H' * L) / H

其中(RHL) (R * H' * L) 是一个常数, 我们记为K K

可以看出来, 实际的距离Ltarget L_{target} 与图片中圆球的半径成反比, 这也符合我们常识.

小球在画面占的空间越大就说明离镜头越近.

Ltarget=1/RK L_{target} = 1/R' * K

源代码


import sensor, image, time

# 小球的颜色阈值,根据颜色追踪小球
target_color_threshold   = ( 56, 83, 5, 57, 63, 80)

sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.RGB565) # use RGB565.
sensor.set_framesize(sensor.QQVGA) # use QQVGA for speed.
sensor.skip_frames(10) # Let new settings take affect.
sensor.set_auto_whitebal(False) # turn this off.
clock = time.clock() # Tracks FPS.

K=5000 # K是我们计算出来的常数

def calc_radius(blob):
    # 计算图像中色块的半径 , 比较粗暴
    return (blob.w() + blob.h()) / 2

while(True):
    clock.tick() # Track elapsed milliseconds between snapshots().
    img = sensor.snapshot() # Take a picture and return the image.

    # 寻找目标颜色的小球
    blobs = img.find_blobs([target_color_threshold])
    if len(blobs) == 1:
        # Draw a rect around the blob.
        blob = blobs[0]
        img.draw_rectangle(blob.rect())
        img.draw_cross(blob.cx(), blob.cy())
        # 图像中小球的半径
        img_ball_r= calc_radius(blob)
        # 小球离镜头的距离 根据我们的公式计算
        ball_distance = K / img_ball_r
        print("小球距离: %d"%ball_distance)

算法分析

首先小球必须在画面正中间, 公式才成立

另外,误差较大

Copyright 杭州云江科技有限公司 2017 all right reserved,powered by Gitbook该文件修订时间: 2018-04-02 09:53:12

results matching ""

    No results matching ""