使用D435测量体积

使用D435测量体积

简介

在实际应用中,经常需要测量诸如货架上的空间剩余空间,这时候就需要测量目标空间的体积。本次我们使用D435进行指定空间的剩余体积测量。 ## 思路 ### 思考 要测定空间中的的体积,根据体积公式V = S * h,我们首先要获得底面积和高度。高度可以用D435的测距来得到。但底面积比较难获得,因为随着距离的拉远,区域内的面积会改变,这是需要解决的问题。 ### 从相机视角获得面积 D435参数D435参数
从官方给的数据来看,D435彩色相机的视角为69.4°42.5°,也就是说横向视角为69.4°,纵向视角为42.5°,将这视角简化为三角形可以得到距离和视野长度之间的关系,如下图:
计算计算
我们将每一个像素视为一个单位,根据上述式子可以算出单位面积S0和单位体积V0。 ### 总体思路 现在看来,求得指定区域的体积的思路就很明确了:
获取彩色图和深度图 * 将深度图对齐到彩色图 * 划定测量区域 * 获取每个像素点对应的深度h * 计算每个单位体积S0 * 将单位体积求和得到总体体积

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import pyrealsense2 as rs
import numpy as np
import cv2
import sys
import math

pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 1280, 720, rs.format.z16, 30)#此处比例必须为16:9
config.enable_stream(rs.stream.color, 1280, 720, rs.format.bgr8, 30)

profile = pipeline.start(config)

mouse_config_p = 0

#单位面积/体积基数
S0 = 4*math.tan(34.7/180*math.pi)*math.tan(21.25/180*math.pi)/1280/720

# 空间坐标
x_min = 0
y_min = 0
x_max = 0
y_max = 0

#鼠标交互
def onmouse(event, x, y, flags, param): #标准鼠标交互函数
global mouse_config_p,x_min,y_min,x_max,y_max
if event==cv2.EVENT_LBUTTONDOWN: #当鼠标点击时
if mouse_config_p == 0 :
x_min = x #获取坐标
y_min = y
mouse_config_p += 1
elif mouse_config_p == 1:
x_max = x
y_max = y
mouse_config_p += 1
with open("./config.ini","w") as f: #存储到文件(预留)
f.write(str(x_min))
f.write(" ")
f.write(str(y_min))
f.write(" ")
f.write(str(x_max))
f.write(" ")
f.write(str(y_max))

#划定选区
def Region_config():
finish = False
while finish == False: #循环直到获取到有效帧
cv2.namedWindow('FreshCompanion')
cv2.setMouseCallback('FreshCompanion', onmouse) #绑定鼠标动作
frames = pipeline.wait_for_frames() #获取帧
color_frame = frames.get_color_frame() #获取彩色帧
if not color_frame :
continue
color_image = np.asanyarray(color_frame.get_data())
cv2.imshow("FreshCompanion", color_image)
cv2.waitKey(1) #必须使用waitkey,否则会卡住
if x_min != 0 and y_min != 0 and x_max != 0 and y_max != 0: #判断是否完成
finish = True

def get_V():
while True:

for i in range(5):#忽略前几帧
pipeline.wait_for_frames()

frames = pipeline.wait_for_frames()

depth_frame = frames.get_depth_frame()#获取深度帧

color_frame = frames.get_color_frame()#获取图像帧

if not depth_frame or not color_frame:
continue

#转换为numpy数组
depth_image = np.asanyarray(depth_frame.get_data())
color_image = np.asanyarray(color_frame.get_data())


depth = np.asanyarray(depth_frame.get_data())
#仅保留选取
depth = depth[y_min:y_max,x_min:x_max].astype(float)

depth_scale = profile.get_device().first_depth_sensor().get_depth_scale()#获取设备统计单位
depth = depth[depth!=0]#忽略0元素
depth = depth * depth_scale
V0 = depth*depth*depth*S0*1000
V = np.sum(V0)
dist, _, _, _ = cv2.mean(depth)
cv2.rectangle(color_image, (x_min, y_min),(x_max, y_max), (255, 255, 255), 2)
cv2.putText(color_image, "V = " + str(V) + "L", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
cv2.putText(color_image, "Dis = " + str(dist) + "m", (10, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
cv2.imshow("FreshCompanion", color_image)
cv2.waitKey(1)


Region_config()
get_V()

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2017-2022 Ink East
  • 访问人数:1829 | 浏览次数:2680

请我喝杯咖啡吧~

支付宝
微信