文章可以转载,但是必须表明出处!

本文使用Intel Realsense D435深度相机,拍摄RGB颜色图及16位深度图。

同时实现了以深度图和RGB颜色图为图像帧的视频显示、录制与保存。

以下为总体程序:

'''

使用realsense相机录制视频

'''

#!/usr/bin/env python

# coding=utf-8

import time

import h5py # 深度图格式所在库

import pyrealsense2 as rs

import numpy as np

import cv2

import os

class Camera(object):

'''

realsense相机处理类

'''

def __init__(self, width=1280, height=720, fps=30): # 图片格式可根据程序需要进行更改

self.width = width

self.height = height

self.pipeline = rs.pipeline()

self.config = rs.config()

self.config.enable_stream(rs.stream.color, self.width, self.height, rs.format.bgr8, fps)

self.config.enable_stream(rs.stream.depth, self.width, self.height, rs.format.z16, fps)

# self.config.enable_stream(rs.stream.infrared, 1, self.width, self.height, rs.format.y8, fps)

# self.config.enable_stream(rs.stream.infrared, 2, self.width, self.height, rs.format.y8, fps)

self.pipeline.start(self.config) # 获取图像视频流

def get_frame(self):

frames = self.pipeline.wait_for_frames() # 获得frame (包括彩色,深度图)

colorizer = rs.colorizer() # 创建伪彩色图对象

depth_to_disparity = rs.disparity_transform(True)

disparity_to_depth = rs.disparity_transform(False)

# 创建对齐对象

align_to = rs.stream.color # rs.align允许我们执行深度帧与其他帧的对齐

align = rs.align(align_to) # “align_to”是我们计划对齐深度帧的流类型。

aligned_frames = align.process(frames)

# 获取对齐的帧

aligned_depth_frame = aligned_frames.get_depth_frame() # aligned_depth_frame是对齐的深度图

color_frame = aligned_frames.get_color_frame()

# left_frame = frames.get_infrared_frame(1)

# right_frame = frames.get_infrared_frame(2)

color_image = np.asanyarray(color_frame.get_data())

colorizer_depth = np.asanyarray(colorizer.colorize(aligned_depth_frame).get_data())

depthx_image = np.asanyarray(aligned_depth_frame.get_data()) # 原始深度图

# left_frame = np.asanyarray(left_frame.get_data())

# right_frame = np.asanyarray(right_frame.get_data())

return color_image, depthx_image, colorizer_depth

# left_frame, right_frame

def release(self):

self.pipeline.stop()

if __name__ == '__main__':

# 视频保存路径

os.mkdir(f'D://Realsense//Video//{int(time.time())}')

video_path = f'D://Realsense//Video//{int(time.time())}//targetvideo_rgb.mp4'

video_depthc_path = f'D://Realsense//Video//{int(time.time())}//targetvideo_depthcolor.mp4'

video_depth16_path = f'D://Realsense//Video//{int(time.time())}//targetvideo_depth.h5'

# video_left_path = f'D://Realsense//Video//Stereo_left//{int(time.time())}_left.mp4'

# video_right_path = f'D://Realsense//Video//Stereo_right//{int(time.time())}_right.mp4'

# 初始化参数

fps, w, h = 30, 1280, 720

# fps, w, h = 30, 640, 480

mp4 = cv2.VideoWriter_fourcc(*'mp4v') # 视频格式

# 视频保存而建立对象

# wr_left = cv2.VideoWriter(video_left_path, mp4, fps, (w, h), isColor=False)

# wr_right = cv2.VideoWriter(video_right_path, mp4, fps, (w, h), isColor=False)

# 完成相机初始化

cam = Camera(w, h, fps)

flag_V = 0

idx = 0

id = 0

print('录制视频请按: s, 保存视频或退出请按:q')

while True:

# 读取图像帧,包括RGB图和深度图

color_image, depthxy_image, colorizer_depth = cam.get_frame()

cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)

cv2.imshow('RealSense', color_image)

key = cv2.waitKey(1)

if key & 0xFF == ord('s') :

flag_V = 1

# 创建视频文件

wr = cv2.VideoWriter(video_path, mp4, fps, (w, h), isColor=True)

wr_colordepth = cv2.VideoWriter(video_depthc_path, mp4, fps, (w, h), isColor=True)

wr_depth = h5py.File(video_depth16_path, 'w')

print('...录制视频中...')

if flag_V == 1:

# 保存图像帧

wr.write(color_image) # 保存RGB图像帧

wr_colordepth.write(colorizer_depth) # 保存相机自身着色深度图

# wr_left.write(left_image) # 保存左帧深度图

# wr_right.write(right_image) # 保存右帧深度图

# res, depth16_image = cv2.imencode('.png', depthxy_image) # 深度图解码方式一:点云小,但是出错

depth16_image = cv2.imencode('.png', depthxy_image)[1] # 深度图解码方式二:文件较大,测试稳定

depth_map_name = str(id).zfill(5) + '_depth.png'

# wr_depth[str(idx).zfill(5)] = depth16_image # 储存方法:1 前3帧和没11帧出现高质量点云,其他错误

wr_depth[depth_map_name] = depth16_image # 储存方法:2 所有点云准确,但是点云质量不高

idx += 1

id = id + 1

if key & 0xFF == ord('q') or key == 27:

cv2.destroyAllWindows()

print('...录制结束/直接退出...')

break

# 录制完毕,释放对象

wr.release()

wr_colordepth.release()

# wr_left.release()

# wr_right.release()

wr_depth.close()

cam.release()

print(f'若保存视频,则视频保存在:{video_path}')

程序阅读如下:

1.库引用

import time # 获取时间信息,用于创建不同文件名称的文件夹

import h5py # 深度图格式所在库

import pyrealsense2 as rs # 相机集成库,用于相机初始化与相机视频流获取

import numpy as np # 将图像帧转换为数据信息以进行图像保存

import cv2 # 视觉图像库,用于保存图像帧与视频

import os # 系统操作库,用于系统路径寻觅与文件夹创建

2.相机初始化函数

class Camera(object):

'''

realsense相机处理类

'''

def __init__(self, width=1280, height=720, fps=30): # 图片格式可根据程序需要进行更改

self.width = width #获取图像帧设置

self.height = height

self.pipeline = rs.pipeline() #开放图像帧管道

self.config = rs.config() #配置初始化

self.config.enable_stream(rs.stream.color, self.width, self.height, rs.format.bgr8, fps)

self.config.enable_stream(rs.stream.depth, self.width, self.height, rs.format.z16, fps)

# self.config.enable_stream(rs.stream.infrared, 1, self.width, self.height, rs.format.y8, fps)

# self.config.enable_stream(rs.stream.infrared, 2, self.width, self.height, rs.format.y8, fps)

self.pipeline.start(self.config) # 获取图像视频流

3.图像流获取函数 

def get_frame(self):

frames = self.pipeline.wait_for_frames() # 获得frame (包括彩色,深度图)

colorizer = rs.colorizer() # 创建伪彩色图对象

depth_to_disparity = rs.disparity_transform(True)

disparity_to_depth = rs.disparity_transform(False)

# 创建对齐对象

align_to = rs.stream.color # rs.align允许我们执行深度帧与其他帧的对齐

align = rs.align(align_to) # “align_to”是我们计划对齐深度帧的流类型。

aligned_frames = align.process(frames)

# 获取对齐的帧

aligned_depth_frame = aligned_frames.get_depth_frame() # aligned_depth_frame是对齐的深度图

color_frame = aligned_frames.get_color_frame()

# left_frame = frames.get_infrared_frame(1)

# right_frame = frames.get_infrared_frame(2)

color_image = np.asanyarray(color_frame.get_data()) # 将图像帧转换为矩阵格式

colorizer_depth = np.asanyarray(colorizer.colorize(aligned_depth_frame).get_data())

depthx_image = np.asanyarray(aligned_depth_frame.get_data())

# left_frame = np.asanyarray(left_frame.get_data())

# right_frame = np.asanyarray(right_frame.get_data())

return color_image, depthx_image, colorizer_depth # 返回图像数据值

# left_frame, right_frame

4.相机功能释放函数

def release(self):

self.pipeline.stop() # 停止相机拍摄

5.主程序:文件路径需要根据本地情况进行修改,图片格式根据需求进行修改

if __name__ == '__main__':

# 视频保存路径 路径需要根据本地情况进行修改

os.mkdir(f'D://Realsense//Video//{int(time.time())}')

video_path = f'D://Realsense//Video//{int(time.time())}//targetvideo_rgb.mp4'

video_depthc_path = f'D://Realsense//Video//{int(time.time())}//targetvideo_depthcolor.mp4'

video_depth16_path = f'D://Realsense//Video//{int(time.time())}//targetvideo_depth.h5'

# video_left_path = f'D://Realsense//Video//Stereo_left//{int(time.time())}_left.mp4'

# video_right_path = f'D://Realsense//Video//Stereo_right//{int(time.time())}_right.mp4'

# 初始化参数

fps, w, h = 30, 1280, 720

# fps, w, h = 30, 640, 480

mp4 = cv2.VideoWriter_fourcc(*'mp4v') # 视频格式

# 视频保存对象

# wr_left = cv2.VideoWriter(video_left_path, mp4, fps, (w, h), isColor=False)

# wr_right = cv2.VideoWriter(video_right_path, mp4, fps, (w, h), isColor=False)

# 相机初始化

cam = Camera(w, h, fps)

flag_V = 0

idx = 0

id = 0

print('录制视频请按: s, 保存视频或退出请按:q')

# 循环保存图像帧以建立视频

while True:

# 读取图像帧,包括RGB图和深度图

color_image, depthxy_image, colorizer_depth = cam.get_frame()

cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)

cv2.imshow('RealSense', color_image)

key = cv2.waitKey(1)

if key & 0xFF == ord('s') :

flag_V = 1

# 创建视频文件

wr = cv2.VideoWriter(video_path, mp4, fps, (w, h), isColor=True)

wr_colordepth = cv2.VideoWriter(video_depthc_path, mp4, fps, (w, h), isColor=True)

wr_depth = h5py.File(video_depth16_path, 'w')

print('...录制视频中...')

if flag_V == 1:

# 保存图像帧

wr.write(color_image) # 保存RGB图像帧

wr_colordepth.write(colorizer_depth) # 保存相机自身着色深度图

# wr_left.write(left_image) # 保存左帧深度图

# wr_right.write(right_image) # 保存右帧深度图

depth16_image = cv2.imencode('.png', depthxy_image)[1] # 深度图解码

depth_map_name = str(id).zfill(5) + '_depth.png'

wr_depth[depth_map_name] = depth16_image # 所有点云准确

id = id + 1

if key & 0xFF == ord('q') or key == 27:

cv2.destroyAllWindows()

print('...录制结束/直接退出...')

break

# 录制完毕,释放视频对象

wr.release()

wr_colordepth.release()

# wr_left.release()

# wr_right.release()

wr_depth.close()

cam.release()

print(f'若保存视频,则视频保存在:{video_path}')

图片拍摄结果:

RGB图

16位深度图

 伪彩色图

总结:

对比上一篇文章,该程序完整的保存了16位深度图,而非将其转换为8位深度图;

16位深度图保存采用的h5py格式,在后续进行图片抽帧时需要对应的图片抽取程序。

具体代码可查看我后续的博客

 

精彩内容

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: