实现一个抽帧算法+双目相机原理

2022-04-15 08:32:57 浏览数 (1)

很多人视觉算法处理慢找我,真头秃,我能给的方案都有限。而且最后都是想让我给写。。。

众所周知1秒24帧图像,如果你的单帧分辨率小点还好,大了肯定卡顿。

那解决方案其实比较固定的:

  1. 增加机器算力,以前1帧时间1,现在0.1,那就是提升了10倍
  2. 或者使用ROI,就是分辨率变小,也相对的算起来轻松
  3. 或者抽帧,也就是我用的方法,我一秒处理4帧,这个效率最高的

如果想直接使用,可以看文章下面的代码。

首先回忆一下深度图,它是灰度图像,该图像的每一个像素值都是摄像头到物体表面之间距离的估计值。

因为我也没带相机,这里就使用预先下载的图像集处理一下。

大致就是说,没有摄像机也不慌,别气,我们可以录制下来给你用

反正提供了好几个

免责声明:以上文件不是官方营销材料。这些是使用预生产硬件捕获的,其唯一目的是帮助开发人员、制造商和学生开始使用 RealSense 技术

简单的放了一下

RGB的参数

深度的参数

ROS的播放包

代码语言:javascript复制
pip install pyrealsense2
代码语言:javascript复制
pip install opencv-python

安装两个包,2代比一代强很多了。

没什么问题

这步就报错了,不知道为什么

抠抠屁股,参数写错了。

打印参数看看

相当ok

先对齐,接着读一帧

信息ok~

获取一张图,嘻嘻嘻,RGB的

打印一些帧的信息

这里使用一窗口呈现图片

显示一下深度的图像

获取点云的数据

这里处理一下

绘制出来

令人头秃的是,全是编译好的pyc

Optimizing Correlated Graspability Score and Grasp Regression for Better Grasp Prediction

代码语言:javascript复制
https://arxiv.org/pdf/2002.00872v1.pdf

论文位置,没有源码,看个锤子

论文里面一种抓取的图,真锤子

下面是双目相机的一点原理:

1 通用单目相机模型

通用相机模型中,X,Y,Z为世界坐标系,(x,y,z)为相机坐标系,根据x三角形相似性:

2 双目测距原理

双目立体视觉的深度相机对环境光照强度比较敏感,且依赖图像本身的特征,在光照不足,缺乏纹理的情况下很难提取到适合做匹配的特征。即左右两幅图像的对应关系不容易确定。

realsense解决了这样的问题,看下文:

1 有效深度视角:

real sense 在本质上属于双目立体视觉,所以,有效的深度视场应该是左成像器和右成像器的视场重叠的一部分,因为只有在左右两幅像中都有对应像素点的物理坐标,才能计算出深度值。如下图所示:

以realsense d415为例, d415参数如下,

带入参数,可以计算得到在不同高度z下,对应的水平方向上的有效视角

不同高度对应的有效深度视角

无效视角部分反应在深度图像上,会是黑洞,如图:

2 水平方向有效视场宽度(与相机连线水平,另一个垂直方向视角不会改变,计算简单,忽略)

在不同高度下,无效宽度和总视野宽度比例可以通过如下公式计算:

DBR = B/(2*Z*tan(HFOV/2))

Invalid depth band(in pixels) = HRES*DBR

其中hres 为Horizontal Resolution水平方向分辨率

根据有效视场宽度比例,可以计算不同深度下的水平方向有效视野宽度

不同深度下水平方向有效视野尺寸

根据视野尺寸(整个视野尺寸,非有效尺寸)和像素分辨率,可以计算水平方向的最小空间分辨率

最小空间分辨率(mm)= (视野尺寸/像素分辨率)* 3

其中,视野尺寸可以通过摄像机b模型计算得到,d415水平方向像素分辨率1280,根据香浓采样定理j并结合亚像素精度,系数取s3,

得到不同深度下,水平方向上可以做到的空间分辨精度:

3 综合计算realsense d415gs深度方向上各个参数如下表

real sense 参数

以上来自于这个小姐姐,没错~

这CV学的可以~写进我的书里面了~

这段代码是将RGB和Depth分帧保存。

这里是对硬件的一个初始化,这里要注意搞明白分辨率,也可以就像文章开头那样使用一个路径来分帧。

使用了一个try和finally来控制下面的帧

等待视频框架发一个完整的帧,将两个帧进行一次对齐操作

获得两个帧,然后确保两种视频流都读取到,接着把图像帧转换一下数据类型

深度图不方便显示,可以用applyColorMap把深度映射到彩色,更改cv2.COLORMAP_JET参数可以修改映射算法

!!!每20帧存一下

扫尾工作,接着显示出来

这样就有效的避免了算力不够的问题。

代码语言:javascript复制
import open3d as o3d
# 查看是否能检测到intel realsense设备
# o3d.t.io.RealSenseSensor.list_devices()
import pyrealsense2 as rs
import numpy as np
import cv2

# 设置rgb和depth图片的储存路径
rgb_file = './rgb'
depth_file = './depth'

# i为储存图片的序号;j记录视频流中图片数量,到20清空一次
i = 0
j = 0

if __name__ == "__main__":
    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)
    # 设置对齐对象,让Depth对齐RGB
    align_to = rs.stream.color
    align = rs.align(align_to)

    # start streaming
    pipeline.start(config)
    try:
        while True:
            j = j   1
            # 获得RGB,Depth框架
            frames = pipeline.wait_for_frames()
            # 深度与颜色对齐
            aligned_frames = align.process(frames)
            # 获得相机内参
            # profile = aligned_frames.get_profile()
            #intrinsics = profile.as_video_stream_profile().get_intrinsics()
            # pinhole_camera_intrinsic = o3d.camera.PinholeCameraIntrinsic(
            #    intrinsics.width, intrinsics.height, intrinsics.fx, intrinsics.fy, intrinsics.ppx, intrinsics.ppy)

            # 获得对齐的帧
            depth_frame = aligned_frames.get_depth_frame()
            color_frame = aligned_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())

            # 深度图不方便显示,可以用applyColorMap把深度映射到彩色,更改cv2.COLORMAP_JET参数可以修改映射算法
            depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(
                depth_image, alpha=0.03), cv2.COLORMAP_JET)

            # 储存图片
            if j % 20 == 0:
                i = i   1
                cv2.imwrite("./rgb/rgb_{}.jpg".format(i), color_image)
                cv2.imwrite("./depth/depth_{}.jpg".format(i), depth_colormap)

            # 把RGB和Depth沿行对齐,方便后续显示视频流
            images = np.hstack((color_image, depth_colormap))

            # 展示视频流
            cv2.namedWindow('realsense', cv2.WINDOW_AUTOSIZE)
            cv2.imshow('realsense', images)
            key = cv2.waitKey(1)

            # 退出
            if key & 0xFF == ord('q') or key == 27:
                cv2.destroyWindow()
                break

    finally:
        pipeline.stop()

完整代码

代码语言:javascript复制
https://www.zhihu.com/column/c_1264582588888354816
代码语言:javascript复制
https://github.com/IntelRealSense/librealsense/blob/master/doc/sample-data.md
代码语言:javascript复制
https://github.com/IntelRealSense/librealsense

0 人点赞