【问题标题】:How to use OpenCV to handle picture taken by Custom camera如何使用 OpenCV 处理自定义相机拍摄的图片
【发布时间】:2019-05-07 20:59:16
【问题描述】:

我在 Android 上使用 OpenCV,我想使用 OpenCV 来处理我的自定义相机拍摄的照片,下面是我的代码:

//mOriginBitmap is taken by my custom camera.
mOriginMat = new Mat(mOriginBitmap.getHeight(), mOriginBitmap.getWidth(), CvType.CV_8UC4);

Utils.bitmapToMat(mOriginBitmap,mOriginMat);

mDestMat=new Mat(mOriginBitmap.getHeight(), mOriginBitmap.getWidth(), CvType.CV_8UC4);

Imgproc.GaussianBlur(mOriginMat,mDestMat,new Size(3,3),0);

Utils.matToBitmap(mDestMat,mDestBitmap);

mDestImage.setImageBitmap(mDestBitmap);

提前致谢。

更多细节,下面是异常,由Utils.bitmapToMat(mOriginBitmap,mOriginMat);抛出:

com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1037) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832) 
         Caused by: CvException [org.opencv.core.CvException: OpenCV(3.4.4) /build/3_4_pack-android/opencv/modules/java/generator/src/cpp/utils.cpp:38: error: (-215:Assertion failed) AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0 in function 'void Java_org_opencv_android_Utils_nBitmapToMat2(JNIEnv*, jclass, jobject, jlong, jboolean)'
        ]
            at org.opencv.android.Utils.nBitmapToMat2(Native Method)
            at org.opencv.android.Utils.bitmapToMat(Utils.java:93)
            at org.opencv.android.Utils.bitmapToMat(Utils.java:102)
            at com.example.dell.suppercamera.PictureActivity.onGaussianBlur(PictureActivity.java:103)

【问题讨论】:

    标签: android opencv camera


    【解决方案1】:

    我解决了,Android相机拍的图片是YUV420sp,但是Mat需要ARGB888,所以我用Imgcodecs.imread方法加载图片:

    File file = new File(getCacheDir(), "text.jpg");
    mOriginMat = Imgcodecs.imread(file.getAbsolutePath());
    Imgproc.cvtColor(mOriginMat,mOriginMat,Imgproc.COLOR_BGR2RGB);
    mDestMat=new Mat(mOriginMat.rows(), mOriginMat.cols(), CvType.CV_8UC4);
    Imgproc.GaussianBlur(mOriginMat,mDestMat,new Size(3,3),0);
    mDestBitmap = Bitmap.createBitmap(mOriginMat.cols(), mOriginMat.rows(), Bitmap.Config.ARGB_8888);
    Utils.matToBitmap(mDestMat,mDestBitmap);
    mDestImage.setImageBitmap(mDestBitmap);
    

    【讨论】:

      【解决方案2】:

      很高兴知道 mOriginalBitmap 的来源及其价值。但是,您可以尝试使用 Mat 默认构造函数,它会处理宽度和高度本身以及类型本身。

      mOriginMat = new Mat();
      
      Utils.bitmapToMat(mOriginBitmap,mOriginMat);
      

      如果 mOriginBitmap 设置正确,这应该可以工作。

      【讨论】:

      • mOriginBitmap 是 YUV,因为它来自相机。我尝试将其转换为 RGB,但没有成功。
      • BitmapToMat 通常应该处理转换。使用我发布的代码时,您是否遇到相同的错误
      • 是的,我仍然遇到异常。 github.com/xiaolvzi/SuperCamera,这是我的github,你可以试试。
      【解决方案3】:

      仔细看报错信息,核心部分是这样的:

      Assertion failed) AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0
      

      lockPixels 方法描述在这里:https://developer.android.com/ndk/reference/group/bitmap#group___bitmap_1ga2908d42fa4db286c34b7f8c11f29206f

      由于您没有发布自定义相机类的代码,我只能猜测,但我会假设您正在创建的位图不使用直接缓冲区(另请参见此处:https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html),这会导致 lockPixels 失败。

      【讨论】:

      • 我不知道是什么原因导致Assertion failed。我的自定义相机是正常的,只是拍照存为文件,然后我拿来显示。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多