0

我正在開發一個原型應用程序,利用探戈深度相機進行模板匹配。到目前爲止,我已經能夠在已經回答的問題,文檔等的幫助下解決所有問題。谷歌探戈/ opencv安卓相機應用程序崩潰/掛起

但是,現在我似乎已經停下來了。我做的最後一項重大改變是在顯示相機預覽圖像之前繪製輪廓。無論我現在做什麼,該應用程序都會在崩潰之前運行一段時間。

我已經看過Android Studio中的堆轉儲和分配跟蹤。唯一可能的奇怪的事情是,堆轉儲中的FinalizerReference對象上可能存在大量內存......

我也嘗試將處理移動到AsyncTask,並跳過每個顏色框直到完成任務(以便一次只運行一個任務)並顯示處理後的框架,但問題依然存在。

我使用Google Tango獲取顏色和深度相機數據以及java中的opencv用於分析數據並進行模板匹配。

有人知道這些logcat消息的含義嗎?

logcat的錯誤:

E/lowmemorykiller:錯誤開口的/ proc/10173/oom_score_adj;錯誤號= 2
E /毫米照相機ISP2:abf40_trigger_update:587 aec_ratio.ratio = 0.039062
W/ActivityManager:墜毀服務的調度重新啓動 com.lenovo.lsf.device/com.lenovo.lsf.push.service .PushService在68068ms
W/ActivityManager:墜毀服務com.qualcomm.qti.modemtestmode的調度重新啓動/ .MbnSystemService在88020ms
E/InputDispatcher:信道「478a66c com.android.documentsui/com.android.documentsui.DocumentsActivity(服務器)'〜通道無法恢復破碎,將被丟棄!
E/lowmemorykiller:Error writing/proc/10113/oom_score_adj; errno = 22
E/JavaBinder:!!!失敗的粘合劑交易!!! (parcel size = 76)
E/lowmemorykiller:Error writing/proc/32408/oom_score_adj; errno = 22
E/InputDispatcher:channel'85c4188 com.android.launcher3/com.android.launcher3.Launcher(server)'〜Channel is unrecoverably broken and will dispos!
E /毫米照相機ISP2:abf40_trigger_update:587 aec_ratio.ratio = 0.000000
E/ConnectivityService:RemoteException的捕獲嘗試發送回調味精NetworkRequest [ID = 332,legacyType = -1,[能力:INTERNET & NOT_RESTRICTED &信任]]
E/mm-camera:mct_util_timer_handler:在HAL命令提升過程中出現錯誤後端卡住SIGABRT
E/JavaBinder:!!!失敗的粘合劑交易!!! (parcel size = 76)
E/lowmemorykiller:Error writing/proc/32437/oom_score_adj; errno = 22
E/JavaBinder:!!!失敗的粘合劑交易!!! (parcel size = 308)
E/JavaBinder:!!!失敗的粘合劑交易!!! (parcel size = 76)
E/lowmemorykiller:Error writing/proc/32437/oom_score_adj; errno = 22
E/JavaBinder:!!!失敗的粘合劑交易!!!(parcel size = 76)
E/mm-camera:mct_util_timer_handler:在HAL命令提升SIGABRT E /表面時出現錯誤後端卡:queueBuffer:錯誤排隊緩衝區到SurfaceTexture,-32
E/Surface:queueBuffer:error queuing buffer to表面紋理,-32
E /毫米照相機:cpp_module_send_buf_divert_event:cpp_module_send_buf_divert_event::無轉接配置
E/Camera3-的OutputStream接收545]緩衝器事件沒有轉接配置
E /毫米攝像機接收545]緩衝器事件: getBufferLocked:流0:不能出隊下一輸出緩衝器:斷管(-32)
E/Camera3-的OutputStream:returnBufferCheckedLocked:流0:錯誤排隊緩衝區天然無線ndow:破損的管道(-32)
E/Camera3-設備:RequestThread:無法獲得輸出緩衝區,跳過請求:損壞的管道(-32)
E/Camera3-設備:無法將緩衝區返回到其流:破損的管道(-32)
E/Camera3-OutputStream:getBufferLocked:流0:無法將下一個輸出緩衝區出列:損壞的管道(-32)
E/Camera3-設備:RequestThread:無法獲得輸出緩衝區跳過請求:斷開的管(-32)

代碼用於顯示相機預覽:

mTango.experimentalConnectOnFrameListener(TangoCameraIntrinsics.TANGO_CAMERA_COLOR, new Tango.OnFrameAvailableListener() { 
    byte[] imageByteArray = new byte[colorCameraIntrinsics.height * colorCameraIntrinsics.width * 3/2]; 
    Mat yuvMat = new Mat(colorCameraIntrinsics.height + colorCameraIntrinsics.height/2, colorCameraIntrinsics.width, CvType.CV_8UC1); 
    Bitmap bitmapDisplay = Bitmap.createBitmap(colorCameraIntrinsics.width, colorCameraIntrinsics.height, Bitmap.Config.ARGB_8888); 
    Mat colorMatDisplay; 

    @Override 
    public void onFrameAvailable(TangoImageBuffer imageBuffer, int cameraId) { 
     Log.d(TAG, "onFrameAvailable: color frame available"); 
     if (colorFrameCounter < 3) { //only use every 3rd frame 
      Log.d(TAG, "onFrameAvailable: skipping frame " + colorFrameCounter); 
      colorFrameCounter++; 
     } else { 
      colorFrameCounter = 0; 
      if (!stopCameraView.get()) { // Only view frame if camera view is not stopped 

       // convert image buffer data to byte array 
       imageBuffer.data.get(imageByteArray); 

       // byte array to Mat object with YUV coding (NV21) 
       yuvMat.put(0, 0, imageByteArray); 

       // locking access to lastColorFrameMat 
       synchronized (lockVar) { 
        Log.d(TAG, "onFrameAvailable: converting to bitmap"); 
        // convert from YUV (NV21) Mat to RGBA Mat and place in lastColorFrameMat (global) 
        Imgproc.cvtColor(yuvMat, lastColorFrameMat, Imgproc.COLOR_YUV2RGBA_NV21, 4); 
        colorMatDisplay = lastColorFrameMat.clone(); 
       } 

       if (templateContours != null) { 
        Imgproc.drawContours(colorMatDisplay, templateContours, templateContourMaxIdx, new Scalar(0, 255, 0, 255), 5); 
       } 

       // convert colorMatDisplay to bitmap, for display in imageview 
       Utils.matToBitmap(colorMatDisplay, bitmapDisplay); 

       Log.d(TAG, "onFrameAvailable: view lastColorFrameMat on phone display"); 

       // View colorImage in imageViewer on UI thread 
       runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         imageViewer.setImageBitmap(bitmapDisplay); 
        } 
       }); 
      } 
     } 

    } 
}); 

回答

1

這裏有兩件事情可能發生在這裏:

  1. 攝像機圖像的緩衝區超出了範圍。

對於目前的Tango的SDK,onFrameAvailable回調的被調用者只能在回調的範圍內對imageBuffer進行控制。這意味着,如果你在一個AsynTask參考imageBuffer,你可能會得到一個空緩衝區,並導致崩潰。 Tango解決它的方法是始終從回調中深度複製數據,並在另一個線程中處理它。

  • 進程正在阻塞Tango的螺紋太久。
  • 沒有AsyncTask,可能發生的情況是處理阻止了Tango的線程時間過長,並且這對Tango來說也是不好的。