使用安卓相机拍摄图像后将位图转换为Mat

37
Mat b = new Mat();
Bitmap bmp = getIntent().getExtras().getParcelable("image_send");

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_display_image);
    Mat tmp = new Mat (bmp.getWidth(), bmp.getHeight(), CvType.CV_8UC1);
    Utils.bitmapToMat(bmp, tmp);
    Imgproc.cvtColor(tmp, tmp, Imgproc.COLOR_RGB2GRAY);
    //Imgproc.cvtColor(tmp, tmp, Imgproc.COLOR_GRAY2RGB, 4);
    Utils.matToBitmap(tmp, bmp);

    iv = (ImageView) findViewById(R.id.imageView1);
    iv.setImageBitmap(bmp);
}

无法显示bmp图像。在拍照后,我的应用程序停止工作。


你不能在onCreate中使用OpenCV代码(因为原生so库还没有被加载)。 - berak
4个回答

61

Utils.bitmapToMat可以将Android Bitmap转换为OpenCV Mat。它需要一个ARGB_8888RGB_565类型的位图。

import org.opencv.android.Utils;

Mat mat = new Mat();    
Bitmap bmp32 = bmp.copy(Bitmap.Config.ARGB_8888, true);
Utils.bitmapToMat(bmp32, mat);

1
这行代码 Bitmap bmp32 = bmp.copy(Bitmap.Config.ARGB_8888, true); 有什么用?为什么不能直接使用 Utils.bitmapToMat(bmp, mat); - Nagabhushan S N
我真的非常需要帮助解决这个问题,你可以帮我吗?谢谢!https://dev59.com/q1IH5IYBdhLWcg3wGZC5 - Carlos Diego
1
我可以回答上面的问题。bitmapToMat只接受特定的位图类型。这确保它是ARGB_8888格式。如果格式不正确,你的mat会出现垃圾数据。 - John Lord

7

Mat tmp = new Mat(bmp.getWidth(), bmp.getHeight(), CvType.CV_8UC1);

OpenCV的Mat构造函数需要行和列作为参数,而不是宽度和高度,请将其对调。

改为:

Mat tmp = new Mat(bmp.getHeight(), bmp.getWidth(), CvType.CV_8UC1);


类型也是错误的,在转换时图像仍然是彩色+alpha(CV_8UC4)。 - Antonio

0

使用 Camera2,这个任务非常快速,你只需要配置 ImageReaderYUV_420_888ImageFormat,然后像这样使用 OpenCV 处理帧:

// You can read image with differents patterns for example grayscale:
Mat mGray(height, width, cv::IMREAD_GRAYSCALE, pFrameData); 

下一个答案中有完整的实现https://dev59.com/P6Pia4cB1Zd3GeqPv0RU#49331546


-1
我的应用也有同样的问题。在主活动中,我必须渲染OpenCV以使其可用。 (我假设您的应用程序在使用Mat库时会抛出链接错误)。 所有示例应用程序都是这样做的。在主要活动中包含这个。
 private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS:
                {
                    Log.i("OpenCVManager setup", "OpenCV loaded successfully");
                  //Use openCV libraries after this  
                } break;
                default:
                {
                    super.onManagerConnected(status);
                } break;
            }
        }
    };

    @Override
    public void onResume()
    {
        super.onResume();
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_9, this,
                mLoaderCallback);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接