前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实现一个抽帧算法+双目相机原理

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

作者头像
云深无际
发布2022-04-15 08:32:57
8310
发布2022-04-15 08:32:57
举报
文章被收录于专栏:云深之无迹

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

众所周知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
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云深之无迹 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档