# 单目测距原理与实现（代码可运行）

Opencv3实现单目视觉测距

## 一、前言

### 二、单目测距原理

F = (P x D) / W

F = (248px x 24in) / 11in = 543.45

D’ = (W x F) / P

D’ = (11in x 543.45) / 170 = 35 英寸

D’ = (W x F) / P

## 三、实现代码：

import cv2
import numpy as np

win_width = 1920
win_height = 1200
mid_width = int(win_width / 2)
mid_height = int(win_height / 2)

foc = 2810.0
real_wid = 11.69
font = cv2.FONT_HERSHEY_SIMPLEX
w_ok = 1

capture = cv2.VideoCapture(1)
capture.set(3, win_width)
capture.set(4, win_height)

while(True):
# frame = cv2.flip(frame, 1)
if ret == False:
break

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
ret, binary = cv2.threshold(gray, 127, 255, 0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))
binary = cv2.dilate(binary, kernel, iterations=2) # 形态学膨胀
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# cv2.drawContours(frame, contours, -1, (0, 255, 0), 2)
for c in contours:
if cv2.contourArea(c) < 2000: # 对于矩形区域，只显示大于给定阈值的轮廓，所以一些微小的变化不会显示。对于光照不变和噪声低的摄像头可不设定轮廓最小尺寸的阈值
continue

x, y, w, h = cv2.boundingRect(c) # 该函数计算矩形的边界框

if x > mid_width or y > mid_height:
continue
if (x + w) < mid_width or (y + h) < mid_height:
continue
if h > w:
continue
if x == 0 or y == 0:
continue
if x == win_width or y == win_height:
continue

w_ok = w
cv2.rectangle(frame, (x + 1, y + 1), (x + w_ok - 1, y + h - 1), (0, 255, 0), 2)

dis_inch = (real_wid * foc) / (w_ok - 2)
dis_cm = dis_inch * 2.54
# os.system("cls")
# print("Distance : ", dis_cm, "cm")
frame = cv2.putText(frame, "%.2fcm" % (dis_cm), (5, 25), font, 0.8, (0, 255, 0), 2)
frame = cv2.putText(frame, "+", (mid_width, mid_height), font, 1.0, (0, 255, 0), 2)

cv2.namedWindow('res', 0)
cv2.namedWindow('gray', 0)
cv2.resizeWindow('res', win_width, win_height)
cv2.resizeWindow('gray', win_width, win_height)
cv2.imshow('res', frame)
cv2.imshow('gray', binary)

c = cv2.waitKey(40)
if c ==27:
break

cv2.destroyAllWindows()

### 程序效果图如下：

• 33
点赞
• 299
收藏
觉得还不错? 一键收藏
• 打赏
• 27
评论
04-20
09-24
12-22 3723
10-29 2万+
12-14 9188
04-09 6108
01-17 8800
05-25 5万+
05-28 1570
09-27 6636
04-27 2604
07-28 1026

¥1 ¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。