google tango / opencv android 相机应用程序崩溃/挂起
Posted
技术标签:
【中文标题】google tango / opencv android 相机应用程序崩溃/挂起【英文标题】:google tango / opencv android camera app crashes/hangs 【发布时间】:2017-10-22 01:07:40 【问题描述】:我正在开发一个原型应用程序,利用探戈深度相机进行模板匹配。到目前为止,我已经能够在已经回答的问题、文档等的帮助下解决所有问题。
然而,现在我似乎停了下来。我所做的最后一项重大更改是在显示之前在相机预览图像上绘制轮廓。无论我现在做什么,该应用程序都会运行一段时间,然后崩溃。
我查看了 android Studio 中的堆转储和分配跟踪。唯一可能奇怪的是堆转储中的 FinalizerReference 对象可能有很多内存......
我还尝试将处理移至 AsyncTask,并跳过每个颜色帧,直到任务完成(这样一次只运行一个任务)并显示处理后的帧,但问题仍然存在。
我使用 Google Tango 获取颜色和深度相机数据,使用 java 中的 opencv 分析数据并进行模板匹配。
有人知道这些 logcat 消息的含义吗?
Logcat 错误:
E/lowmemorykiller:打开 /proc/10173/oom_score_adj 时出错;错误号=2 E/mm-camera-isp2: abf40_trigger_update:587 aec_ratio.ratio = 0.039062 W / ActivityManager:计划重新启动崩溃的服务 com.lenovo.lsf.device/com.lenovo.lsf.push.service.PushService in 68068ms W/ActivityManager:计划在 88020 毫秒内重新启动崩溃的服务 com.qualcomm.qti.modemtestmode/.MbnSystemService E/InputDispatcher: 通道 '478a66c com.android.documentsui/com.android.documentsui.DocumentsActivity (server)' ~ 通道已损坏,将被处理掉! E/lowmemorykiller:写入 /proc/10113/oom_score_adj 时出错;错误号=22 E/JavaBinder:!!! Binder 交易失败!!! (包裹大小 = 76) E/lowmemorykiller:写入 /proc/32408/oom_score_adj 时出错;错误号=22 E/InputDispatcher: 通道 '85c4188 com.android.launcher3/com.android.launcher3.Launcher (server)' ~ 通道已不可恢复地损坏,将被丢弃! E/mm-camera-isp2: abf40_trigger_update:587 aec_ratio.ratio = 0.000000 E/ConnectivityService:RemoteException 在尝试为 NetworkRequest [ id=332, legacyType=-1, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED] ]发送回调消息时被捕获 E/mm-camera:mct_util_timer_handler:HAL 命令引发 SIGABRT 期间错误后端卡住 E/JavaBinder:!!! Binder 交易失败!!! (包裹大小 = 76) E/lowmemorykiller:写入 /proc/32437/oom_score_adj 时出错;错误号=22 E/JavaBinder:!!! Binder 交易失败!!! (包裹大小 = 308) E/JavaBinder:!!! Binder 交易失败!!! (包裹大小 = 76) E/lowmemorykiller:写入 /proc/32437/oom_score_adj 时出错;错误号=22 E/JavaBinder:!!! Binder 交易失败!!! (包裹大小 = 76) E / mm-camera:mct_util_timer_handler:HAL命令引发SIGABRT期间错误后端卡住 E / Surface:queueBuffer:错误排队缓冲区到SurfaceTexture,-32 E/Surface: queueBuffer: 到 SurfaceTexture 的错误队列缓冲区,-32 E/mm-camera: cpp_module_send_buf_divert_event:545] 收到缓冲区事件,没有转移配置 E/mm-camera: cpp_module_send_buf_divert_event:545] 收到缓冲区事件,没有转移配置 E/Camera3-OutputStream:getBufferLocked:流 0:无法将下一个输出缓冲区出列:管道损坏 (-32) E/Camera3-OutputStream:returnBufferCheckedLocked:流 0:将缓冲区排队到本机窗口时出错:管道损坏 (-32) E/Camera3-Device:RequestThread:无法获取输出缓冲区,跳过请求:Broken pipe (-32) E/Camera3-设备:无法将缓冲区返回到其流:管道损坏 (-32) E/Camera3-OutputStream:getBufferLocked:流 0:无法将下一个输出缓冲区出列:管道损坏 (-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 也是不利的。
【讨论】:
以上是关于google tango / opencv android 相机应用程序崩溃/挂起的主要内容,如果未能解决你的问题,请参考以下文章