上面的文章也说了,输出的视频流其实是一种raw的格式,这个东西怎么用确实是取决于我们,那这篇文章以源码包装的手段探究一下其中的情况。读完以后感觉还是收获很大的。怎么说呢,感觉科学其实就是在操作数据,数据在流转,数据在转换,数据在重塑。不说了,继续看。 因为是raw的格式,很自然的就去转换格式,下面是找了几个库。 我找到一个库是处理这个的库 https://github.com/letmaik/rawpy.git clone下来 https://pypi.org/project/rawpy/ 准备好了~ 给了个不好看,这个我具体代码就不看了,不玩了 球的麻袋,我找到一个好玩的: https://pypi.org/project/colour-hdri/ 一个自动HDR的工具 我们注意到这里有一个下划线开头的包,据我研究是:下划线开头其实是对C++库的方法和一些量的包装。属于低级的API,或者是不想让用户碰的东西。 openni2 就比较高级了,就好像是C++版本的#include<Openni2.h>的头文件一样。 没错一模一样 from primesense import openni2 from primesense import _openni2 as c_api 导入这两个 大概就是一些找dll的操作 主要是它 然后这里处理完返回True就行(我也没有看得很明白,我以后再补) if (openni2.is_initialized()): print("openNI2 initialized") else: print("openNI2 not initialized")
调用这个函数看是不是初始化完成 返回得就是上面得这个值 看到这个就很开心 返回得是C_api里面得一个信息值 包装如下 def __repr__(self): return 'OniDeviceInfo(uri = %r, vendor = %r, name = %r, usbVendorId = %r, usbProductId = %r)' % (self.uri, self.vendor, self.name, self.usbVendorId, self.usbProductId) 这个是给人看得方法。 创建深度流,先问有没有深度传感器 再这里 这个是查询传感器得方法 然后里面是得到传感器得方法,俄罗斯套娃? 在设备信息里面,大概懂了 成功之后是返回得这个,我觉得我离真相不远了 你看这个,都是从视频流得函数里面取东西。 你看这里 看初始化得方法,第三个参数的流转 里面开始转到c的接口了 在深入些是这个dll的信息 往上看是在openni2的dll文件 开启传输 兜兜转转又回来了 重点看这个读帧的方法 一帧有什么?这里告诉你 里面正经的读帧在这个方法里面 和我想的一样,它又去找dll了 读帧的话还没有开始 dframe_data = np.array(frame.get_buffer_as_triplet() ).reshape([480, 640, 2]) 这句是 使用的是这个方法 看这个地方 上面的意思是,c的一个类型乘一个int。后面是从结构体里面获得数据的大小除以类型的占用字节数,然后使用获得的哪个函数(我猜的)。 得到我们的数据载荷,就是这里 这个是这样的 果然是个指针 CPP的结构体 Python的结构体,一模一样的 dataSize = 'ctypes.c_int' 下面的调用时时相当于一个无符号的8位数据。 C++的调用 Python的调用 应该是,Python的3是深度的位数 因为是这样的定义的,至于为什么Python不是这个,应该是Python没有这个数据的封装。 frame = depth_stream.read_frame() dframe_data = np.array(frame.get_buffer_as_triplet()) print(dframe_data.shape) print(dframe_data.dtype) 基本的获取代码 get_buffer_as_triplet U8 x 3 get_buffer_as_uint8 U8 我还算了一下这个。。。 get_buffer_as_uint16 U16 可以看到默认的方法,和我们可以传的参数 自己试试 我传了64的进去 有了数据端口级好说了,我们可以进行数据重塑了。 dframe_data = np.array(frame.get_buffer_as_triplet()). reshape([480, 640, 2]) 使用这个reshape的函数就可以了。 我希望你没有忘记这个 它是307200的数据 输出后的数据样子 其实到这里核心的问题已经解决了,但是很多问题都没有解决,那是接下来的工作了。 |
|