OpenCV之Mat与Bitmap之间的转换

        我们想在Android平台上开发OPenCV(处理图像);避免不了显示,通常在Android当中展示图像都是通过ImageView这个控件,当然展示的方式也有几种,在下面的内容中会简单介绍一下。但是我们在上一篇中关于Mat介绍中知道,OpenCV处理的是Mat对象,所以,为了接下来的工作更容易,我们本篇就要看一下Bitmap和Mat之间转换实现。

1  ImageView展示图像的实现方式

imageView.setImageBitmap();
imageView.setImageDrawable();
imageView.setBackground();

2  Bitmap与Mat之间转换

2.1  Utils

       在OpenCV4Android的SDK中,为了开发方便,里面专门提供了两者之间的转换API Utils,下面我们就来看看这个工具类究竟有什么可以调用的接口:

static void bitmapToMat(android.graphics.Bitmap bmp, Mat mat)

Short form of the bitmapToMat(bmp, mat, unPremultiplyAlpha=false).

static void bitmapToMat(android.graphics.Bitmap bmp, Mat mat, boolean unPremultiplyAlpha)

Converts Android Bitmap to OpenCV Mat.

static java.lang.String exportResource(android.content.Context context, int resourceId) 
static java.lang.String exportResource(android.content.Context context, int resourceId, java.lang.String dirname) 
static Mat loadResource(android.content.Context context, int resourceId) 
static Mat loadResource(android.content.Context context, int resourceId, int flags) 
static void matToBitmap(Mat mat, android.graphics.Bitmap bmp)

Short form of the matToBitmap(mat, bmp, premultiplyAlpha=false)

static void matToBitmap(Mat mat, android.graphics.Bitmap bmp, boolean premultiplyAlpha)

Converts OpenCV Mat to Android Bitmap.

从其方法列表中可以看出,其完完全全就是一个工具类,全是静态方法;且就是为了实现Mat与Bitmap转换而设计的。

现在我们就来抽取其中两个详细讲解一下:

(1)public static void bitmapToMat(android.graphics.Bitmap bmp, Mat mat, boolean unPremultiplyAlpha)

官方释义:

This function converts an Android Bitmap image to the OpenCV Mat. 
'ARGB_8888' and 'RGB_565' input Bitmap formats are supported. 
The output Mat is always created of the same size as the input Bitmap and of the 'CV_8UC4' type, it keeps the image in RGBA format. 
This function throws an exception if the conversion fails.

Parameters:

bmp - is a valid input Bitmap object of the type 'ARGB_8888' or 'RGB_565'.

mat - is a valid output Mat object, it will be reallocated if needed, so it may be empty.

unPremultiplyAlpha - is a flag, that determines, whether the bitmap needs to be converted from alpha premultiplied format (like Android keeps 'ARGB_8888' ones) to regular one; this flag is ignored for 'RGB_565' bitmaps.

简译:实现Bitmap图像转Mat,支持'ARGB_8888' 和 'RGB_565'像素类型,输出的Mat类型默认是CV_8UC4类型,大小和Bitmap一样,通道顺序为RGBA。最后一个参数对于RGB_565类型Bitmap无效,当类型为ARGB_8888时,决定是否保留透明度属性。

(2)public static void matToBitmap(Mat mat, android.graphics.Bitmap bmp, boolean premultiplyAlpha)

官方释义:

This function converts an image in the OpenCV Mat representation to the Android Bitmap. 
The input Mat object has to be of the types 'CV_8UC1' (gray-scale), 'CV_8UC3' (RGB) or 'CV_8UC4' (RGBA). 
The output Bitmap object has to be of the same size as the input Mat and of the types 'ARGB_8888' or 'RGB_565'. 
This function throws an exception if the conversion fails.

Parameters:

mat - is a valid input Mat object of types 'CV_8UC1', 'CV_8UC3' or 'CV_8UC4'.

bmp - is a valid Bitmap object of the same size as the Mat and of type 'ARGB_8888' or 'RGB_565'.

premultiplyAlpha - is a flag, that determines, whether the Mat needs to be converted to alpha premultiplied format (like Android keeps 'ARGB_8888' bitmaps); the flag is ignored for 'RGB_565' bitmaps.

简译:略

2.2 示例

        下面就来结合示例来说明一下在实际开发中使用的流程,其实整个流程通常是设备获取图片转化为BItmap对象,调用OpenCV Utils工具类转换为Mat对象,然后对Mat经过一系列处理之后再转为Bitmap对象,通过其他的图像显示载体展示出来(我们这里就是ImageView)

关于Bitmap到Mat的转换,可以参见第一篇中搭建OpenCV开发环境最后的示例--灰度图像处理,下面主要实现Mat到Bitmap的转换,先看一下效果图。

实现的主要逻辑代码如下:

 mat = mat.setTo(new Scalar(
                Double.parseDouble(rtext.getText().toString()),
                Double.parseDouble(gtext.getText().toString()),
                Double.parseDouble(btext.getText().toString()),
                Double.parseDouble(atext.getText().toString()))
        );
        Log.e(TAG, "generateColor: "+imageView.getHeight() );
        mat.create(new Size(imageView.getWidth(), imageView.getHeight()), CvType.CV_8UC4);
        //当前Mat与Bitmap转换,只支持ARGB_8888和RGB_565
        Bitmap bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(mat, bitmap,true);//添加透明度
        imageView.setImageBitmap(bitmap);

有时候,我们还想把Mat对象存储为常用的图片格式,可以通过如下方式实现:

 public void saveMatData(Mat mat,String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            file.mkdir();
        }

        //注意 Imgcodecs的imread()和imwrite()方法读取颜色值通道的顺序都是BGR
        Imgcodecs.imwrite(filePath, mat);
    }

好了,关于两者之间的转换就介绍到这里了;我们主要使用的就是Utils这个工具类,所以只要搞明白它里面的几个方法就可以了。更多内容请查看:

上一篇:OpenCV中Mat与Android中Bitmap简介

下一篇:OpenCV之基本绘图(在Mat和Bitmap上)

猜你喜欢

转载自blog.csdn.net/hfut_why/article/details/84706098