OpenCV / Android BufferQueue错误:表面纹理已被放弃

时间:2012-12-22 20:27:29

标签: android opencv

Android和OpenCV新手。一直试图从新书中实现代码,使用实用计算机视觉项目掌握OpenCV 。该应用程序基本上使用OpenCV在相机预览上呈现卡通化图像。您可以触摸屏幕以保存卡通图像。

作者的源代码位于here

我对CartoonifierApp.java文件进行了一些小修改(见下文),以便我可以使用OpenCV Manager应用程序静态加载漫画器库(原始代码抛出了UnsatisfiedLinkError)。

我面临的问题是,当我将应用加载到我的Galaxy Nexus(Android 4.1.1)上时,我会看到一个空的黑屏。我的LogCat说:

  

E / BufferQueue(4744):[unnamed-4744-0] setBufferCount:SurfaceTexture   已经被遗弃了! E / Cartoonifier :: SurfaceView(4744):   startPreview()失败

我认为这是一个记忆问题。我知道cpp代码可以工作,因为它在我的计算机上运行良好 - 虽然在相对较新的笔记本电脑(华硕U46E)上渲染很慢。

我不知道如何解决这个问题。我找到的唯一有用的建议是here。如果我在CatoonifierVewBase.java中替换我的setPreview方法

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
     mCamera.setPreviewTexture( new SurfaceTexture(10) );
 else
     mCamera.setPreviewDisplay(null);

 mCamera.setPreviewDisplay(mHolder);
然后会发生什么事情,相机正常工作,我可以通过触摸屏幕保存卡通图像。请注意,这并不是理想的结果,因为我想在相机预览上不断地对图像进行漫画。相机只是工作,因为我没有写到表面视图(至少这是我的理解)。前面提到的site中的答案有一些解决方法,但我不知道他在说什么。

BTW我已经尝试了所有OpenCV4Android示例应用程序,它们工作得很好。我也使用OpenCV 2.4.3版。 API级别目标是15.

完整Logcat:

  

12-22 15:33:07.966:I / CartoonifierApp(5999):实例化的新课程   com.Cartoonifier.CartoonifierApp 12-22 15:33:07.966:   I / CartoonifierApp(5999):调用onCreate 12-22 15:33:07.966:   I / CartoonifierApp(5999):尝试加载OpenCV库12-22   15:33:07.982:I / Cartoonifier :: SurfaceView(5999):实例化新的   class com.Cartoonifier.CartoonifierView 12-22 15:33:07.990:   I / CartoonifierApp(5999):onResume 12-22 15:33:07.990:   I / Cartoonifier :: SurfaceView(5999):openCamera 12-22 15:33:07.990:   I / Cartoonifier :: SurfaceView(5999):releaseCamera 12-22 15:33:08.099:   D / OpenCVManager / Helper(5999):创建服务连接12-22   15:33:08.099:D / OpenCVManager / Helper(5999):尝试获取库路径   12-22 15:33:08.138:D / OpenCVManager / Helper(5999):试着搞定   库清单12-22 15:33:08.169:D / OpenCVManager / Helper(5999):库   清单:"" 12-22 15:33:08.169:D / OpenCVManager / Helper(5999):首先   尝试加载库12-22 15:33:08.169:D / OpenCVManager / Helper(5999):   尝试初始化OpenCV库12-22 15:33:08.169:   D / OpenCVManager / Helper(5999):尝试加载库   /data/data/org.opencv.engine/lib/libopencv_java.so 12-22 15:33:08.169:

     

D / dalvikvm(5999):尝试加载lib   /data/data/org.opencv.engine/lib/libopencv_java.so 0x41936a40 12-22

     

15:33:08.193:D / dalvikvm(5999):添加了共享库   /data/data/org.opencv.engine/lib/libopencv_java.so 0x41936a40 12-22

     

15:33:08.193:D / OpenCVManager / Helper(5999):OpenCV libs init没问题!

     

12-22 15:33:08.193:D / OpenCVManager / Helper(5999):首次尝试   加载库是好的12-22 15:33:08.193:D / OpenCVManager / Helper(5999):Init   完成状态0 12-22 15:33:08.193:   D / OpenCVManager / Helper(5999):解除服务12-22 15:33:08.200:   D / OpenCVManager / Helper(5999):使用回调12-22进行呼叫   15:33:08.200:I / CartoonifierApp(5999):OpenCV已成功加载

     

12-22 15:33:08.200:D / dalvikvm(5999):尝试加载lib   /data/data/com.Cartoonifier/lib/libcartoonifier.so 0x41936a40 12-22

     

15:33:08.200:D / dalvikvm(5999):添加了共享库   /data/data/com.Cartoonifier/lib/libcartoonifier.so 0x41936a40 12-22

     

15:33:08.200:D / dalvikvm(5999):没有找到JNI_OnLoad   /data/data/com.Cartoonifier/lib/libcartoonifier.so 0x41936a40,   跳过init 12-22 15:33:08.200:D / OpenCVManager / Helper(5999):   服务连接创建12-22 15:33:08.200:   D / OpenCVManager / Helper(5999):尝试获取库路径12-22

     

15:33:08.232:D / OpenCVManager / Helper(5999):试图获取库列表   12-22 15:33:08.271:D / OpenCVManager / Helper(5999):图书馆清单:""

     

12-22 15:33:08.271:D / OpenCVManager / Helper(5999):首次尝试   load libs 12-22 15:33:08.271:D / OpenCVManager / Helper(5999):试图

     

init OpenCV libs 12-22 15:33:08.271:D / OpenCVManager / Helper(5999):   试图加载库   /data/data/org.opencv.engine/lib/libopencv_java.so 12-22 15:33:08.271:   D / dalvikvm(5999):试图加载lib   /data/data/org.opencv.engine/lib/libopencv_java.so 0x41936a40 12-22

     

15:33:08.271:D / dalvikvm(5999):共享库   ' /data/data/org.opencv.engine/lib/libopencv_java.so'已装入   相同的CL 0x41936a40 12-22 15:33:08.271:D / OpenCVManager / Helper(5999):   OpenCV libs init还可以! 12-22 15:33:08.271:   D / OpenCVManager / Helper(5999):首次尝试加载库是正常的

     

12-22 15:33:08.271:D / OpenCVManager / Helper(5999):初始化状态为0   12-22 15:33:08.271:D / OpenCVManager / Helper(5999):取消绑定服务   12-22 15:33:08.271:D / OpenCVManager / Helper(5999):使用回调调用   12-22 15:33:08.271:I / CartoonifierApp(5999):OpenCV加载成功   12-22 15:33:08.279:D / dalvikvm(5999):尝试加载lib /data/data/com.Cartoonifier/lib/libcartoonifier.so 0x41936a40   12-22 15:33:08.279:D / dalvikvm(5999):共享lib' /data/data/com.Cartoonifier/lib/libcartoonifier.so'已加载到相同的CL 0x41936a40   12-22 15:33:08.302:I / Cartoonifier :: SurfaceView(5999):surfaceCreated   12-22 15:33:08.302:I / Cartoonifier :: SurfaceView(5999):surfaceChanged()。窗口大小:1196x670   12-22 15:33:08.302:I / Cartoonifier :: SurfaceView(5999):setupCamera(1196x670)   12-22 15:33:08.302:I / Cartoonifier :: SurfaceView(5999):开始处理线程   12-22 15:33:08.310:I / Cartoonifier :: SurfaceView(5999):找到相机分辨率1920x1080   12-22 15:33:08.310:I / Cartoonifier :: SurfaceView(5999):发现相机分辨率1280x720   12-22 15:33:08.310:I / Cartoonifier :: SurfaceView(5999):发现相机分辨率960x720   12-22 15:33:08.310:I / Cartoonifier :: SurfaceView(5999):找到相机分辨率800x480   12-22 15:33:08.310:I / Cartoonifier :: SurfaceView(5999):找到相机分辨率720x576   12-22 15:33:08.310:I / Cartoonifier :: SurfaceView(5999):找到相机分辨率720x480   12-22 15:33:08.310:I / Cartoonifier :: SurfaceView(5999):发现相机分辨率768x576   12-22 15:33:08.310:I / Cartoonifier :: SurfaceView(5999):找到相机分辨率640x480   12-22 15:33:08.310:I / Cartoonifier :: SurfaceView(5999):找到相机分辨率320x240   12-22 15:33:08.310:I / Cartoonifier :: SurfaceView(5999):找到相机分辨率352x288   12-22 15:33:08.310:I / Cartoonifier :: SurfaceView(5999):找到相机分辨率240x160   12-22 15:33:08.310:I / Cartoonifier :: SurfaceView(5999):找到相机分辨率176x144   12-22 15:33:08.310:I / Cartoonifier :: SurfaceView(5999):找到相机分辨率128x96   12-22 15:33:08.318:I / Cartoonifier :: SurfaceView(5999):选择相机预览尺寸:1280x720   12-22 15:33:08.333:D / dalvikvm(5999):GC_FOR_ALLOC释放131K,2%释放10807K / 11011K,暂停13ms,总计13ms

     

12-22 15:33:08.333:I / dalvikvm-heap(5999):将堆(frag case)增长到11.902MB,用于1382416字节分配

     

12-22 15:33:08.357:D / dalvikvm(5999):GC_CONCURRENT释放1K,3%免费12156K / 12423K,暂停12ms + 1ms,总计24ms

     

12-22 15:33:08.357:D / dalvikvm(5999):WAIT_FOR_CONCURRENT_GC阻止了11ms

     

12-22 15:33:08.365:D / dalvikvm(5999):GC_FOR_ALLOC释放0K,3%免费12156K / 12423K,暂停9ms,总计9ms

     

12-22 15:33:08.372:I / dalvikvm-heap(5999):将堆(frag case)增长到13.219MB,用于1382416字节分配

     

12-22 15:33:08.388:D / dalvikvm(5999):GC_CONCURRENT释放0K,3%释放13506K / 13831K,暂停11ms + 1ms,总计21ms

     

12-22 15:33:08.388:D / dalvikvm(5999):WAIT_FOR_CONCURRENT_GC阻止了7ms

     

12-22 15:33:08.404:D / dalvikvm(5999):GC_FOR_ALLOC释放< 1K,3%free 13506K / 13831K,暂停9ms,总计10ms

     

12-22 15:33:08.411:I / dalvikvm-heap(5999):将堆(frag case)增长到16.735MB进行3686416字节分配

     

12-22 15:33:08.427:D / dalvikvm(5999):GC_CONCURRENT释放< 1K,3%free 17106K / 17479K,暂停12ms + 1ms,总共22ms

     

12-22 15:33:08.427:D / dalvikvm(5999):WAIT_FOR_CONCURRENT_GC阻止了10ms

     

12-22 15:33:08.443:D / dalvikvm(5999):GC_FOR_ALLOC释放< 1K,3%free 17106K / 17479K,暂停10ms,总计10ms

     

12-22 15:33:08.450:I / dalvikvm-heap(5999):将堆(frag case)增长到20.250MB进行3686416字节分配

     

12-22 15:33:08.466:D / dalvikvm(5999):GC_CONCURRENT释放0K,2%释放20706K / 21127K,暂停12ms + 2ms,总计22ms

     

12-22 15:33:08.466:D / dalvikvm(5999):WAIT_FOR_CONCURRENT_GC阻止了5ms

     

12-22 15:33:08.466:I / Cartoonifier :: SurfaceView(5999):开始预览

     

12-22 15:33:08.497:E / BufferQueue(5999):[unnamed-5999-0] setBufferCount:SurfaceTexture已被放弃!

     

12-22 15:33:08.505:E / Cartoonifier :: SurfaceView(5999):mCamera.startPreview()失败

来自CartoonifierApp.java的片段显示我的修改

private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS:
            {
                Log.i(TAG, "OpenCV loaded successfully");

                // Load native library after(!) OpenCV initialization
                System.loadLibrary("cartoonifier");
            } break;
            default:
            {
                super.onManagerConnected(status);
            } break;
        }
    }
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    Log.i(TAG, "called onCreate");
    super.onCreate(savedInstanceState);

    Log.i(TAG, "Trying to load OpenCV library");
    if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback))
    {
      Log.e(TAG, "Cannot connect to OpenCV Manager");
    }

    requestWindowFeature(Window.FEATURE_NO_TITLE);

    mView = new CartoonifierView(this);
    setContentView(mView);

    // Call our "onTouch()" callback function whenever the user touches the screen.
    mView.setOnTouchListener(this);
}


@Override
protected void onPause() {
    Log.i(TAG, "onPause");
    super.onPause();
    mView.releaseCamera();
}

@Override
public void onResume()
{
    super.onResume();
    Log.i(TAG, "onResume");
    if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback))
    {
      Log.e(TAG, "Cannot connect to OpenCV Manager");
    }   

    if( !mView.openCamera() ) {
        AlertDialog ad = new AlertDialog.Builder(this).create();  
        ad.setCancelable(false); // This blocks the 'BACK' button  
        ad.setMessage("Fatal error: can't open camera!");  
        /*ad.setButton("OK", new DialogInterface.OnClickListener() {  
            public void onClick(DialogInterface dialog, int which) {  
                dialog.dismiss();                      
                finish();
            }  
        });  */
        ad.show();
    }
}

1 个答案:

答案 0 :(得分:9)

此问题在前一段时间在OpenCV中得到了解决。

不确定是应用程序还是操作系统错误。问题是调用用于可视化的Bitmap.createBitmap分离SurfaceTexture对象。

解决方法是修改基础View类的setupCamera方法并更改

try {
    setPreview();
} catch (IOException e) {
    Log.e(TAG, "mCamera.setPreviewDisplay/setPreviewTexture fails: " + e);
}

/* Notify that the preview is about to be started and deliver preview size */
onPreviewStarted(params.getPreviewSize().width, params.getPreviewSize().height);

/* Notify that the preview is about to be started and deliver preview size */
onPreviewStarted(params.getPreviewSize().width, params.getPreviewSize().height);

try {
    setPreview();
} catch (IOException e) {
    Log.e(TAG, "mCamera.setPreviewDisplay/setPreviewTexture fails: " + e);
}

(行的顺序改变)