簡體   English   中英

使用Project Tango用顏色提取點雲; 即獲取當前的相機框架

[英]Extract pointclouds WITH colour using the Project Tango; i.e. getting the current camera frame

我試圖產生一個點雲,每個點都有顏色。 我可以只得到點雲,也可以讓相機拍照,但是我需要它們盡可能地同時進行。 如果可以在調用onXYZijAvailable()時使用時間戳查詢RGB圖像或調用函數以獲取當前幀,則可以完成。 我可以越過這些點,找出與圖像平面相交的位置並獲得該像素的顏色。

到目前為止,我還沒有找到任何獲取圖像像素信息或獲取色點的方法。 我看到過將相機連接到CameraView AR應用程序,然后將事物渲染到頂部,但是應用程序從未觸及相機流。

根據這篇文章,應該有可能獲得我想要的數據,並通過簡單的轉換使點雲和圖像平面同步。 這篇文章也說了類似的話。 但是,我不知道如何獲取RGB數據。 我找不到任何開源項目或教程。

我得到的最接近的結果是通過使用以下命令找出框架准備就緒的時間:

     public void onFrameAvailable(final int cameraId) {
          if (cameraId == TangoCameraIntrinsics.TANGO_CAMERA_COLOR) {
               //Get the new rgb frame somehow.
          }
     }

我正在使用Java API,如果可能的話,我非常想不去研究JNI和NDK。 如何獲得與當前點雲的時間戳最接近的幀?

謝謝您的幫助。

更新:

我實現了它的CPU版本,即使對其進行了一些優化,我也只能在小點雲上獲得0.5 FPS。 這也是由於必須將顏色從android native NV21顏色空間轉換為GPU native RGBA顏色空間這一事實。 我本可以進一步對其進行優化,但是我不會因此獲得實時效果。 android設備上的CPU根本無法表現良好。 如果您想在幾千個點上執行此操作,請避免使用GPU的額外麻煩,也可以在后期執行。

Tango通常將顏色像素數據直接傳遞到OpenGLES紋理。 在Java中,創建目標的質地和與它注冊Tango.connectTextureId() ,然后在onFrameAvailable()回調更新與紋理Tango.updateTexture() 。 將彩色圖像放入紋理中后,就可以使用OpenGLES繪圖調用和着色器對其進行訪問。

如果您的目標是為探戈點雲着色,則最有效的方法是在GPU中。 也就是說,您無需將彩色圖像從GPU中拉出並用Java訪問它,而是將點數據傳遞到GPU中,並使用OpenGLES着色器將3D點轉換為2D紋理坐標,並從紋理中查找顏色。 如果您是第一次這樣做,要想正確就相當棘手,但是為了獲得可接受的性能可能需要這樣做。

如果確實要直接訪問像素數據而不使用C API,則需要將紋理渲染到緩沖區中,然后從緩沖區中讀取顏色數據。 這是一種棘手的,如果你不使用OpenGL和寫作着色器,但該證明一個Android應用工作室在這里 ,並在進一步描述這個答案 該項目演示了如何在屏幕上繪制相機紋理,以及如何繪制到屏幕外緩沖區並讀取RGBA像素。

如果您真的想直接訪問像素數據,但認為NDK可能不如OpenGLES那么痛苦,則C API具有TangoService_connectOnFrameAvailable() ,可直接為您提供像素數據,即無需通過OpenGLES。 但是請注意,像素數據的格式為NV21, 而不是 RGB或RGBA。

我現在通過使用onXYZijAvailable()捕獲深度和使用onFrameAvailable()捕獲圖像來進行此操作。 我正在使用本機代碼,但在Java中也應如此。 對於每個onFrameAvailable(),我都會獲取圖像數據並將其放入預分配的環形緩沖區中。 我有10個插槽和一個計數器/指針。 每個新圖像使計數器遞增,計數器從9循環回到0。計數器是圖像陣列的索引。 我將圖像時間戳保存在類似的環形緩沖區中。 當我獲得深度圖像onXYZijAvailable()時,將獲取數據和時間戳。 然后,我從最近的圖像開始向后瀏覽,然后向后移動,直到找到時間戳最接近深度數據的圖像。 如前所述,您知道圖像數據不會與深度數據來自同一幀,因為它們使用同一台相機。 但是,使用這兩個調用(在JNI中),我可以始終保持在+/- 33毫秒之內,即上一幀或下一幀。

我還沒有檢查過天真地使用最新更新的rgb圖像幀有多近,但這應該非常接近。

只需確保使用onXYZijAvailable()來驅動時序,因為深度更新要比rgb慢。

我發現使用OpenCV :: imwrite()將單個圖像寫入文件系統不能跟上攝像機的實時速度。 我沒有嘗試使用視頻編解碼器流式傳輸到文件。 那應該更快。 根據最終打算對數據進行的處理,您將需要謹慎保存結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM