Android和OpenCV的新功能.一直在努力实施新书中的代码,掌握OpenCV与实用计算机视觉项目.该应用程序基本上使用OpenCV在相机预览上呈现卡通化图像.您可以触摸屏幕以保存卡通图像.
作者的源代码位于此处.
我对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)上渲染很慢.
我不知道如何解决这个问题.我找到的唯一有用的建议是在这里.如果我在CatoonifierVewBase.java中替换我的setPreview方法
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
mCamera.setPreviewTexture( new SurfaceTexture(10) );
else
mCamera.setPreviewDisplay(null);
Run Code Online (Sandbox Code Playgroud)
同
mCamera.setPreviewDisplay(mHolder);
Run Code Online (Sandbox Code Playgroud)
然后发生的事情是相机正常工作,我可以通过触摸屏幕保存卡通图像.请注意,这并不是理想的结果,因为我想在相机预览上不断地对图像进行漫画.相机只是工作,因为我没有写到表面视图(至少这是我的理解).前面提到的网站的答案有一些解决方法,但我不知道他在说什么.
顺便说一句,我已经尝试了所有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):实例化新类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:3 3: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):初始化状态为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):加入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中没有找到JNI_OnLoad,跳过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):首次尝试加载库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):共享库'/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/Cartoonifie r :: 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的+ 1毫秒,总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,暂停11毫秒+ 1毫秒,总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%自由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%自由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%释放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的,总22毫秒
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();
}
}
Run Code Online (Sandbox Code Playgroud)
这个问题不久前在OpenCV中得到了解决.
不确定它是应用程序还是操作系统错误.问题是调用Bitmap.createBitmap分离SurfaceTexture用于可视化的对象.
解决方法是修改基类的setupCamera方法View并进行更改
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);
Run Code Online (Sandbox Code Playgroud)
至
/* 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);
}
Run Code Online (Sandbox Code Playgroud)
(线的顺序改变了)