我试图产生一个点云,其中每一个点有一个颜色。我可以得到点云或我可以让相机拍照,但我需要他们尽可能的同时。如果我能够查找带有时间戳的RGB映像,或者在调用onXYZijAvailable()时调用一个函数来获取当前帧,那么我就完成了。我可以通过这些点,找出它将与图像平面相交的地方,并得到那个像素的颜色。
因为现在,我还没有找到任何方法来获取图像的像素信息或得到彩色点。我见过AR应用程序,相机连接到CameraView上,然后在上面呈现,但是应用程序从来没有碰过相机流。
根据这 post,应该可以通过简单的转换获得我想要的数据,并同步点云和图像平面。这的帖子也在说类似的话。但是,我不知道如何获得RGB数据。我找不到任何开源项目或教程。
我得到的最接近的方法是通过以下方法找出框架何时准备好了:
public void onFrameAvailable(final int cameraId) {
if (cameraId == TangoCameraIntrinsics.TANGO_CAMERA_COLOR) {
//Get the new rgb frame somehow.
}
}我正在使用Java,如果可能的话,我非常不想深入研究JNI和NDK。如何获得与当前点云时间戳最接近的框架?
谢谢你的帮助。
更新:
我实现了它的CPU版本,即使在对其进行了一些优化之后,我也只能在一个小点云上获得.5 FPS。这也是因为这些颜色必须从android原生NV21颜色空间转换为GPU本地RGBA颜色空间。我可以进一步优化它,但我不会得到一个实时的效果。android设备上的CPU不能表现得足够好。如果你想在几千点以上做这件事,那就去做额外的使用GPU的麻烦或者在post中做吧。
发布于 2015-12-10 22:07:12
探戈通常将彩色像素数据直接传递到OpenGLES纹理。在Java中,创建目标纹理并将其注册到Tango.connectTextureId(),然后在onFrameAvailable()回调中使用Tango.updateTexture()更新纹理。一旦在纹理中有了彩色图像,就可以使用OpenGLES绘图调用和着色器来访问它。
如果您的目标是着色探戈点云,最有效的方法是在GPU。也就是说,不是从GPU中提取彩色图像并在Java中访问它,而是将点数据传递到GPU并使用OpenGLES着色器将3D点转换为2D纹理坐标并从纹理中查找颜色。如果您是第一次这样做,那么这是相当棘手的问题,但可能是可接受的性能所必需的。
如果您确实希望直接访问像素数据而不使用C API,则需要将纹理呈现到缓冲区中,然后从缓冲区读取颜色数据。如果你不习惯OpenGL和编写着色器,那就有点棘手了,但是有一个Android应用程序,它演示了这里,并在这个答案中作了进一步的描述。该项目演示了如何将相机纹理绘制到屏幕上,以及如何绘制到屏幕外的缓冲区并读取RGBA像素。
如果您确实希望直接访问像素数据,但决定NDK可能比OpenGLES更少痛苦,则data有直接提供像素数据的connectOnFrameAvailable(),即不需要通过OpenGLES。但是,请注意,像素数据的格式是NV21,而不是RGB或RGBA。
发布于 2016-01-06 21:31:05
我现在通过使用onXYZijAvailable()捕获深度和用onFrameAvailable()捕获图像来实现这一点。我使用的是本机代码,但在Java中也是如此。对于每个onFrameAvailable(),我都会获取图像数据,并将其放入预先分配的环形缓冲区中。我有10个插槽和一个计数器/指针。每个新映像都会增加计数器,计数器将从9返回到0。计数器是图像数组的索引。我将图像时间戳保存在类似的环形缓冲区中。当我得到深度图像onXYZijAvailable()时,我获取数据和时间戳。然后,我回顾这些图像,从最近的图像开始,然后向后移动,直到找到最接近深度数据的时间戳。正如您所提到的,您知道图像数据将不会来自与深度数据相同的帧,因为它们使用相同的照相机。但是,使用这两个调用(在JNI中),我在+/- 33毫秒内,即上一帧或下一帧内,在一致的基础上。
我没有检查过,仅仅天真地使用最近更新的rgb图像帧是多么的接近,但这应该是相当接近的。
只需确保使用onXYZijAvailable()来驱动计时,因为深度更新要比rgb慢。
我发现使用OpenCV::imwrite()将单个图像写入文件系统并不能满足相机的实时性要求。我还没有尝试使用视频编解码器流到文件中。那应该快得多。最后,根据您计划如何处理这些数据,您需要注意如何存储结果。
https://stackoverflow.com/questions/34140023
复制相似问题