java - 谷歌探戈/opencv Android 相机应用程序崩溃/挂起

标签 java android opencv android-camera google-project-tango

我正在开发一个原型(prototype)应用程序,利用探戈深度相机进行模板匹配。到目前为止,我已经能够借助已经回答的问题、文档等解决所有问题。

但是,现在我似乎停了下来。我所做的最后一个主要更改是在显示相机预览图像之前绘制轮廓。无论我现在做什么,应用程序都会运行一段时间,然后就会崩溃。

我查看了 Android Studio 中的堆转储和分配跟踪。唯一可能奇怪的事情是堆转储中的 FinalizerReference 对象上可能有大量内存...

我还尝试将处理移至 AsyncTask,并跳过每个颜色帧,直到任务完成(以便一次只运行一个任务)并显示处理后的帧,但问题仍然存在。

我使用 Google Tango 获取颜色和深度相机数据,并使用 java 中的 opencv 来分析数据并进行模板匹配。

有人知道这些 logcat 消息的含义吗?

Logcat 错误:

E/lowmemorykiller: Error opening /proc/10173/oom_score_adj; errno=2
E/mm-camera-isp2: abf40_trigger_update:587 aec_ratio.ratio = 0.039062
W/ActivityManager: Scheduling restart of crashed service com.lenovo.lsf.device/com.lenovo.lsf.push.service.PushService in 68068ms
W/ActivityManager: Scheduling restart of crashed service com.qualcomm.qti.modemtestmode/.MbnSystemService in 88020ms
E/InputDispatcher: channel '478a66c com.android.documentsui/com.android.documentsui.DocumentsActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
E/lowmemorykiller: Error writing /proc/10113/oom_score_adj; errno=22
E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (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 be disposed!
E/mm-camera-isp2: abf40_trigger_update:587 aec_ratio.ratio = 0.000000
E/ConnectivityService: RemoteException caught trying to send a callback msg for NetworkRequest [ id=332, legacyType=-1, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED] ]
E/mm-camera: mct_util_timer_handler:Error Backend stuck during HAL Command Raising SIGABRT
E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 76)
E/lowmemorykiller: Error writing /proc/32437/oom_score_adj; errno=22
E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 308)
E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 76)
E/lowmemorykiller: Error writing /proc/32437/oom_score_adj; errno=22
E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 76)
E/mm-camera: mct_util_timer_handler:Error Backend stuck during HAL Command Raising SIGABRT E/Surface: queueBuffer: error queuing buffer to SurfaceTexture, -32
E/Surface: queueBuffer: error queuing buffer to SurfaceTexture, -32
E/mm-camera: cpp_module_send_buf_divert_event:545] buffer event received with no divert config
E/mm-camera: cpp_module_send_buf_divert_event:545] buffer event received with no divert config
E/Camera3-OutputStream: getBufferLocked: Stream 0: Can't dequeue next output buffer: Broken pipe (-32)
E/Camera3-OutputStream: returnBufferCheckedLocked: Stream 0: Error queueing buffer to native window: Broken pipe (-32)
E/Camera3-Device: RequestThread: Can't get output buffer, skipping request: Broken pipe (-32)
E/Camera3-Device: Can't return buffer to its stream: Broken pipe (-32)
E/Camera3-OutputStream: getBufferLocked: Stream 0: Can't dequeue next output buffer: Broken pipe (-32)
E/Camera3-Device: RequestThread: Can't get output buffer, skipping request: Broken pipe (-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. 相机图像的缓冲区超出范围。

在当前的 Tango SDK 中,onFrameAvailable 回调的被调用方只能控制回调范围内的 imageBuffer。这意味着如果您在 AsynTask 中引用 imageBuffer,您可能会得到一个空缓冲区,并导致崩溃。 Tango解决这个问题的方法是始终从回调中深拷贝出数据,并在另一个线程中处理它。

  • 该进程阻塞 Tango 线程的时间过长。
  • 如果没有 AsyncTask,可能会发生处理阻塞 Tango 线程太长时间的情况,而这对 Tango 来说也是不利的。

    关于java - 谷歌探戈/opencv Android 相机应用程序崩溃/挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44111775/

    相关文章:

    java - 无法在 Eclipse 中从 Nvidia Tegra Developer Pack 导入 o​​rg.opencv[...]

    java - 如何使用 XStream 将同名节点反序列化为两个不同的类

    java - 在运行时 JavaFX 中更改 Canvas 颜色

    android - Intellij IDEA 14 - 包 R 不存在

    android - setForeground() 可以被具有相同通知的多个服务使用吗?

    c# - Emgu 相机校准

    c++ - 如何通过引用返回对象?

    java - ScrollPane 未显示在 JLabel 上

    android:到达市场上所有屏幕的最佳方式

    c++ - openCV 报错