作者 | yunswj 编辑 | 3D视觉开发者社区 ?如果你得文章内容不错,别忘了三连的支持哦~
通过奥比中光相机Type-C目前直接获得码流的连接SDK是OpenNi但是哇,这个SDK13年不维护。年久失修吗?不,宝刀不老!每个家庭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") 写一个初始。  成功
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) 输出的信息,可以看到输得正确 输出了
接口就是这样的
上面的输出信息来看这个地方(我写的)
在设备管理器也可以看到,深度相机
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字节。
这里需要注意的是:
-
大小端,package_id 是小端,而package_size和TimeStamp是大端;
-
帧包与包号:package_id表示包号,每个传输完一个包加1;TimeStamp表示帧号,每传输完一帧加1,但每帧的第一个包,TimeStamp=0;
-
包长度,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视觉开发者社区 ,获取更多干货知识哦~