【C++改装】让全线奥比相机用上Python接口

作者 | yunswj
编辑 | 3D视觉开发者社区
✨如果觉得文章内容不错,别忘了三连支持下哦😘~

奥比中光的相机是通过Type-C连接的,目前直接获得码流的SDK是OpenNi2,但是哇,这个SDK是13年就不维护了。年久失修吗?不,宝刀未老!各家的RGBD相机都适配了这个SDK,上层的接口给开发人员使用,下层的驱动层给厂家适配。

但是哇,我就是怕C++,我不是不会,就是讨厌样板代码,那我肯定想办法搞个Python的接口~

时间紧,任务重,从头写来不及,我只能改装啦!

首先安装:

pip install primesense

安装这个就好啦。
在这里插入图片描述
上面是编译过后的py脚本,下面是未编译前

我们就使用这个库的openni2的的接口。
在这里插入图片描述
里面包装了很多的C++方法
在这里插入图片描述
我们就看一个方法就好,大概就知道实现方法啦!

接下来就是更换我们的驱动了,方法有了,接口也有了,缺最终的引擎。
在这里插入图片描述
建立一个这样的文件夹
在这里插入图片描述
把我们OrbbecViewer的dll文件放成我上面的样子

import numpy as np
import cv2
from primesense import openni2
from primesense import _openni2 as c_api
openni2.initialize("./Redist")
if (openni2.is_initialized()):
    print("openNI2 initialized")
else:
    print("openNI2 not initialized")
写个初始化的代码。
![图片alt](https://developer-orbbec-oss.oss-cn-shenzhen.aliyuncs.com/forum/20220308112944.png ''图片title'')

成功
from primesense import openni2
from primesense import _openni2 as c_api
import numpy as np
import cv2
openni2.initialize("./Redist")
dev = openni2.Device.open_any()
print(dev.get_device_info())
depth_stream = dev.create_depth_stream()
depth_stream.start()

while True:
    # 显示深度图
    frame = depth_stream.read_frame()
    dframe_data = np.array(frame.get_buffer_as_triplet()
                           ).reshape([480, 640, 2])
    dpt1 = np.asarray(dframe_data[:, :, 0], dtype='float32')
    dpt2 = np.asarray(dframe_data[:, :, 1], dtype='float32')
    dpt2 *= 255
    dpt = dpt1 + dpt2
    cv2.imshow('dpt', dpt)

    # 按下q键退出循环
    key = cv2.waitKey(10)
    if int(key) == 113:
        break

# 人走带门,关闭设备
depth_stream.stop()
dev.close()
输出深度流

OniDeviceInfo(uri = b’\?\usb#
vid_2bc5
&
pid_0614#6&5dea7dd&0&2#
{c3b5f022-5a42-1980-1909-ea72095601b1}’,
vendor = b’Orbbec’,
name = b’Astra’,
usbVendorId = 11205,
usbProductId = 1556)
输出的信息,可以看到输得正确
图片alt
输出了

图片alt接口就是这样的

在这里插入图片描述上面的输出信息来看这个地方(我写的)

在这里插入图片描述
在设备管理器也可以看到,深度相机

在这里插入图片描述
rgb是UVC实现

在这里插入图片描述
调用rgb相机

在这里插入图片描述出流

接下来的是,来自于3D视觉开发者社区论坛的硬货:悟空分享的OpenNI协议小结

1.OpenNI协议命令是基于USB控制传输,使用默认的控制端点0;而图像数据传输是基于USB实现的批量传输,而后者根据取决于数据类型。图像传输端点:
在这里插入图片描述

2.OpenNI协议命令

使用默认的控制端点HOST使用USB默认端点0发送请求,协议包含一个头部信息,结构如下:

typedef struct{
uint16_t nMagic;
uint16_t nSize;
uint16_t nOpcode;
uint16_t nId;
}ProtocolHeader;
其中,Request: nMagic=0x4252, Response: nMagic=0x4d47, nSize表示数据长度,nOpcode表示命令类型,如获取版本号、设置参数等,nId表示包号,设备应答时就使用接收到Request中的nId;

数据部分限制最大长度为512字节。具体实现在protocol.c中,命令类型定义在protocol.h中。

3.OpenNI图像传输

OpenNI支持IR/DEPTH/RGB传输,协议与UVC类似,OpenNI 12字节头部信息定义:
在这里插入图片描述

其中,PACKAGE TYPE定义:
在这里插入图片描述

根据USB工作模式,在USB3.0下,每帧最大长度为1024字节,USB2.0则为512字节。

这里需要注意的是:

  1. 大小端,package_id 是小端,而package_size和TimeStamp是大端;

  2. 帧包与包号:package_id表示包号,每个传输完一个包加1;TimeStamp表示帧号,每传输完一帧加1,但每帧的第一个包,TimeStamp=0;

  3. 包长度,SOF和Normal均为0xC00,而最后一包取决于实际所剩长度last_size,则pakage_size=last_size+12.

后面通过融合,可以获取到点云图。
我下面发一段demo,感兴趣可以直接运行一下:

import open3d as o3d
import matplotlib.pyplot as plt

if __name__ == "__main__":
    print("Read Redwood dataset")
    color_raw = o3d.io.read_image("color.jpg")
    depth_raw = o3d.io.read_image("depth.png")
    rgbd_image = o3d.geometry.create_rgbd_image_from_color_and_depth(
        color_raw, depth_raw)
    print(rgbd_image)

    plt.subplot(1, 2, 1)
    plt.title('grayscale image')
    plt.imshow(rgbd_image.color)
    plt.subplot(1, 2, 2)
    plt.title('depth image')
    plt.imshow(rgbd_image.depth)
    plt.show()

    pcd = o3d.geometry.create_point_cloud_from_rgbd_image(
        rgbd_image,
        o3d.camera.PinholeCameraIntrinsic(
            o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault))
    pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
    o3d.io.write_point_cloud("test.pcd", pcd)
    o3d.visualization.draw_geometries([pcd])

另外,在ubuntu上也可以这样操作,上层的API是一样的,使用在Linux平台下的二进制驱动文件的路径。

版权声明:本文为奥比中光3D视觉开发者社区特约作者授权原创发布,未经授权不得转载,本文仅做学术分享,版权归原作者所有,若涉及侵权内容请联系删文

3D视觉开发者社区是由奥比中光给所有开发者打造的分享与交流平台,旨在将3D视觉技术开放给开发者。平台为开发者提供3D视觉领域免费课程、奥比中光独家资源与专业技术支持。点击加入3D视觉开发者社区,和开发者们一起讨论分享吧~

也可移步微信关注官方公众号3D视觉开发者社区 ,获取更多干货知识哦~

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值