这篇写的比较详细但也比较乱,另一篇思路更清晰和简介一点,可供参考:
Ubutntu下使用realsense d435i(二):获取某二维像素点的三维坐标
00 说明
- 代码1
- 使用
aligned_depth_frame.get_distance()
与rs.rs2_deproject_pixel_to_point()
获得三维坐标 - opencv显示画面
- 并将内参保存到了脚本文件目录下的json格式
- 获取内参和图像帧的部分封装成函数
- 代码2
- 两种方法:方法一是
rs.rs2_deproject_pixel_to_point()
,方法二是“点云” - 其中,第二种点云方法,共有三种计算方法
① 先转为float
,再通过计算i
索引找到坐标
② 先计算i
索引找到坐标,再转为float
③ 直接reshape
,然后通过[y][x]
查找
上述三种计算方法,推荐使用reshape - 这里有两点需要注意:
① 计算索引i
时,i=y*宽度像素640+x
② reshape后查找是[y][x]
,而不是[x][y]
- opencv显示画面,并将坐标信息标注在画面上(这里需要注意,字体颜色排序不是RGB,而是BGR)
- 代码3
- opencv显示画面,并将坐标信息标注在画面上
- 使用
aligned_depth_frame.get_distance()
与rs.rs2_deproject_pixel_to_point()
获得三维坐标 - 将代码分开成两个函数,方便后续调用
关于 运行环境:
这是在Ubuntu18下运行,并且系统已安装ROS,所以是python2.7。
然后需要安装pyrealsense2包,安装过程可参考:https://blog.csdn.net/gyxx1998/article/details/121461293
因为是python2,所以文件首行需要添加:# -*- coding: utf-8 -*-
,才可以写中文注释;如果是python3则没有此问题。
文件首行需要添加:# encoding: utf-8print
,中文的print输出才可以正常显示
关于 注释:
上述三类代码都加了很详细的注释,可以都看一下,方便理解。
其中:
代码2我注释的比较详细,也有两种坐标获取方法,整体观感比较乱;
代码3为最后使用的,则比较简洁。
关于 遗留问题:
关于 参考:
- pyrealsense 的基本操作:https://www.cnblogs.com/penway/p/13416824.html
对于使用的api介绍简介清晰 - stack overflow:https://stackoverflow.com/questions/63266753/how-to-align-already-captured-rgb-and-depth-images
简洁清晰的代码(作用是根据深度,清除某些背景) - github官方api:https://github.com/IntelRealSense/librealsense/blob/jupyter/notebooks/distance_to_object.ipynb?language=en_US
介绍了和openCV dnn模块结合起来的用法示例 - realsense的官方api:
https://dev.intelrealsense.com/docs/projection-in-intel-realsense-sdk-20 - realsense获取深度值,点云,以及通过深度值z获得xyz:https://zhangzhe.blog.csdn.net/article/details/103730429
两种获得三维坐标的方法比较清晰,比较容易理清思路(获取深度&点云)
01 代码1
import pyrealsense2 as rs
import numpy as np
import cv2
import json
pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
profile = pipeline.start(config)
align_to = rs.stream.color
align = rs.align(align_to)
def get_aligned_images():
frames = pipeline.wait_for_frames()
aligned_frames = align.process(frames)
aligned_depth_frame = aligned_frames.get_depth_frame()
color_frame = aligned_frames.get_color_frame()
intr = color_frame.profile.as_video_stream_profile().intrinsics
depth_intrin = aligned_depth_frame.profile.as_video_stream_profile().intrinsics
camera_parameters = {'fx': intr.fx, 'fy': intr.fy,
'ppx': intr.ppx, 'ppy': intr.ppy,
'height': intr.height, 'width': intr.width,
'depth_scale': profile.get_device().first_depth_sensor().get_depth_scale()
}
with open('./intr7insics.json', 'w') as fp:
json.dump(camera_parameters, fp)
depth_image = np.asanyarray(aligned_depth_frame.get_data())
depth_image_8bit = cv2.convertScaleAbs(depth_image, alpha=0.03)
depth_image_3d = np.dstack((depth_image_8bit,depth_image_8bit,depth_image_8bit))
color_image = np.asanyarray(color_frame.get_data())
return intr, depth_intrin, color_image, depth_image, aligned_depth_frame
if __name__ == "__main__":
while 1:
intr, depth_intrin, rgb, depth, aligned_depth_frame = get_aligned_images()
print("============")
print(aligned_depth_frame)
x = 320
y = 240
dis = aligned_depth_frame.get_distance(x, y)
print("dis: ", dis)
camera_coordinate = rs.rs2_deproject_pixel_to_point(depth_intrin, [x, y], dis)
print(camera_coordinate)
cv2.imshow('RGB image',rgb)
key = cv2.waitKey(1)
if key & 0xFF == ord('q') or key == 27:
pipeline.stop()
break
cv2.destroyAllWindows()
效果
02 代码2
import pyrealsense2 as rs
import numpy as np
import cv2
'''
开启点云
'''
pc = rs.pointcloud()
points = rs.points()
'''
设置
'''
pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 15)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 15)
pipe_profile = pipeline.start(config)
depth_sensor = pipe_profile.get_device().first_depth_sensor()
depth_scale = depth_sensor.get_depth_scale()
print("Depth Scale is: ", depth_scale)
align_to = rs.stream.color
align = rs.align(align_to)
while True:
'''
获取图像帧与相机参数
'''
frames = pipeline.wait_for_frames()
aligned_frames = align.process(frames)
aligned_depth_frame = aligned_frames.get_depth_frame()
aligned_color_frame = aligned_frames.get_color_frame()
img_color = np.asanyarray(aligned_color_frame.get_data())
img_depth = np.asanyarray(aligned_depth_frame.get_data())
depth_intrin = aligned_depth_frame.profile.as_video_stream_profile().intrinsics
color_intrin = aligned_color_frame.profile.as_video_stream_profile().intrinsics
depth_to_color_extrin = aligned_depth_frame.profile.get_extrinsics_to(aligned_color_frame.profile)
depth_pixel = [320, 240]
x = depth_pixel[0]
y = depth_pixel[1]
'''
方法一:获取三维坐标(rs2_deproject_pixel_to_point方法)
'''
dis = aligned_depth_frame.get_distance(x, y)
print ('===============方法1:二维映射三维函数=============')
print ('depth: ',dis)
camera_coordinate = rs.rs2_deproject_pixel_to_point(depth_intrin, depth_pixel, dis)
print ('camera_coordinate: ',camera_coordinate)
color_point = rs.rs2_transform_point_to_point(depth_to_color_extrin, camera_coordinate)
color_pixel = rs.rs2_project_point_to_pixel(color_intrin, color_point)
print ('color_point: ',color_point)
print ('color_pixel: ',color_pixel)
'''
方法二:获取三维坐标(点云的另一种计算方法)
'''
print ('===============方法2:点云=============')
pc.map_to(aligned_color_frame)
points = pc.calculate(aligned_depth_frame)
vtx = np.asanyarray(points.get_vertices())
tex = np.asanyarray(points.get_texture_coordinates())
npy_vtx = np.zeros((len(vtx), 3), float)
for i in range(len(vtx)):
npy_vtx[i][0] = np.float(vtx[i][0])
npy_vtx[i][1] = np.float(vtx[i][1])
npy_vtx[i][2] = np.float(vtx[i][2])
npy_tex = np.zeros((len(tex), 3), float)
for i in range(len(tex)):
npy_tex[i][0] = np.float(tex[i][0])
npy_tex[i][1] = np.float(tex[i][1])
print (' ----------计算方法1:先转浮点,再i查找-----------')
print('npy_vtx_shape: ', npy_vtx.shape)
print('npy_tex_shape: ', npy_tex.shape)
i = y*640+x
print('pointcloud_output_vtx: ', npy_vtx[i])
print('pointcloud_output_tex: ', npy_tex[i])
'''
方法三:获取三维坐标(点云方法)
'''
pc.map_to(aligned_color_frame)
points = pc.calculate(aligned_depth_frame)
vtx = np.asanyarray(points.get_vertices())
print (' ----------计算方法2:先i查找,再转浮点-----------')
print ('vtx_before_reshape: ', vtx.shape)
i = y * 640 + x
print ('test_output_point', [np.float(vtx[i][0]),np.float(vtx[i][1]),np.float(vtx[i][2])])
print (' ----------计算方法3:reshape后数组查找-----------')
vtx = np.reshape(vtx,(480, 640, -1))
print ('vtx_after_reshape: ', vtx.shape)
print ('output_point', vtx[y][x][0])
tex = np.asanyarray(points.get_texture_coordinates())
'''
显示图像并显示三维坐标信息(以方法3结果为例)
'''
cv2.circle(img_color, (320,240), 8, [255,0,255], thickness=-1)
cv2.putText(img_color,"Dis:"+str(img_depth[320,240])+" m", (40,40), cv2.FONT_HERSHEY_SIMPLEX, 1.2,[255,0,255])
cv2.putText(img_color,"X:"+str(np.float(vtx[y][x][0][0]))+" m", (80,80), cv2.FONT_HERSHEY_SIMPLEX, 1.2,[255,0,255])
cv2.putText(img_color,"Y:"+str(np.float(vtx[y][x][0][1]))+" m", (80,120), cv2.FONT_HERSHEY_SIMPLEX, 1.2,[255,0,255])
cv2.putText(img_color,"Z:"+str(np.float(vtx[y][x][0][2]))+" m", (80,160), cv2.FONT_HERSHEY_SIMPLEX, 1.2,[255,0,255])
cv2.imshow('RealSence',img_color)
key = cv2.waitKey(1)
if key & 0xFF == ord('q'):
break
pipeline.stop()
效果
03 代码3
import pyrealsense2 as rs
import numpy as np
import cv2
'''
设置
'''
pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 15)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 15)
pipe_profile = pipeline.start(config)
align_to = rs.stream.color
align = rs.align(align_to)
'''
获取对齐图像帧与相机参数
'''
def get_aligned_images():
frames = pipeline.wait_for_frames()
aligned_frames = align.process(frames)
aligned_depth_frame = aligned_frames.get_depth_frame()
aligned_color_frame = aligned_frames.get_color_frame()
depth_intrin = aligned_depth_frame.profile.as_video_stream_profile().intrinsics
color_intrin = aligned_color_frame.profile.as_video_stream_profile().intrinsics
img_color = np.asanyarray(aligned_color_frame.get_data())
img_depth = np.asanyarray(aligned_depth_frame.get_data())
return color_intrin, depth_intrin, img_color, img_depth, aligned_depth_frame
'''
获取随机点三维坐标
'''
def get_3d_camera_coordinate(depth_pixel, aligned_depth_frame, depth_intrin):
x = depth_pixel[0]
y = depth_pixel[1]
dis = aligned_depth_frame.get_distance(x, y)
camera_coordinate = rs.rs2_deproject_pixel_to_point(depth_intrin, depth_pixel, dis)
return dis, camera_coordinate
if __name__=="__main__":
while True:
'''
获取对齐图像帧与相机参数
'''
color_intrin, depth_intrin, img_color, img_depth, aligned_depth_frame = get_aligned_images()
'''
获取随机点三维坐标
'''
depth_pixel = [320, 240]
dis, camera_coordinate = get_3d_camera_coordinate(depth_pixel, aligned_depth_frame, depth_intrin)
print ('depth: ',dis)
print ('camera_coordinate: ',camera_coordinate)
'''
显示图像与标注
'''
cv2.circle(img_color, (320,240), 8, [255,0,255], thickness=-1)
cv2.putText(img_color,"Dis:"+str(dis)+" m", (40,40), cv2.FONT_HERSHEY_SIMPLEX, 1.2,[0,0,255])
cv2.putText(img_color,"X:"+str(camera_coordinate[0])+" m", (80,80), cv2.FONT_HERSHEY_SIMPLEX, 1.2,[255,0,0])
cv2.putText(img_color,"Y:"+str(camera_coordinate[1])+" m", (80,120), cv2.FONT_HERSHEY_SIMPLEX, 1.2,[255,0,0])
cv2.putText(img_color,"Z:"+str(camera_coordinate[2])+" m", (80,160), cv2.FONT_HERSHEY_SIMPLEX, 1.2,[255,0,0])
cv2.imshow('RealSence',img_color)
key = cv2.waitKey(1)
效果
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)