OpenCV中Mat与Android中Bitmap简介

        因为在介绍这部分系列的内容时,默认是对Android开发有一点基础的,所以这样的话,Bitmap可能就相对很熟悉了,相较陌生的是Mat,那我们就首先来看看Mat是什么。

1,Mat

1.1 Mat基本介绍

Mat是OpenCV中用于存储图像信息的类,它在OpenCV中作为一个很重要的信息载体,下面看一下文档中的介绍的关于其方法的部分:

构造方法:

Mat() 
Mat(int rows, int cols, int type) 
Mat(int rows, int cols, int type, java.nio.ByteBuffer data) 
Mat(int rows, int cols, int type, Scalar s) 
Mat(long addr) 
Mat(Mat m, Range rowRange) 
Mat(Mat m, Range rowRange, Range colRange) 
Mat(Mat m, Rect roi) 
Mat(Size size, int type) 
Mat(Size size, int type, Scalar s) 

成员方法:

Mat adjustROI(int dtop, int dbottom, int dleft, int dright) 
void assignTo(Mat m) 
void assignTo(Mat m, int type) 
int channels() 
int checkVector(int elemChannels) 
int checkVector(int elemChannels, int depth) 
int checkVector(int elemChannels, int depth, boolean requireContinuous) 
Mat clone() 
Mat col(int x) 
Mat colRange(int startcol, int endcol) 
Mat colRange(Range r) 
int cols() 
void convertTo(Mat m, int rtype) 
void convertTo(Mat m, int rtype, double alpha) 
void convertTo(Mat m, int rtype, double alpha, double beta) 
void copyTo(Mat m) 
void copyTo(Mat m, Mat mask) 
void create(int rows, int cols, int type) 
void create(Size size, int type) 
Mat cross(Mat m) 
long dataAddr() 
int depth() 
Mat diag() 
Mat diag(int d) 
static Mat diag(Mat d) 
int dims() 
double dot(Mat m) 
java.lang.String dump() 
long elemSize() 
long elemSize1() 
boolean empty() 
static Mat eye(int rows, int cols, int type) 
static Mat eye(Size size, int type) 
double[] get(int row, int col) 
int get(int row, int col, byte[] data) 
int get(int row, int col, double[] data) 
int get(int row, int col, float[] data) 
int get(int row, int col, int[] data) 
int get(int row, int col, short[] data) 
long getNativeObjAddr() 
int height() 
Mat inv() 
Mat inv(int method) 
boolean isContinuous() 
boolean isSubmatrix() 
void locateROI(Size wholeSize, Point ofs) 
Mat mul(Mat m) 
Mat mul(Mat m, double scale) 
static Mat ones(int rows, int cols, int type) 
static Mat ones(Size size, int type) 
void push_back(Mat m) 
int put(int row, int col, byte[] data) 
int put(int row, int col, byte[] data, int offset, int length) 
int put(int row, int col, double... data) 
int put(int row, int col, float[] data) 
int put(int row, int col, int[] data) 
int put(int row, int col, short[] data) 
void release() 
Mat reshape(int cn) 
Mat reshape(int cn, int rows) 
Mat reshape(int cn, int[] newshape) 
Mat row(int y) 
Mat rowRange(int startrow, int endrow) 
Mat rowRange(Range r) 
int rows() 
Mat setTo(Mat value) 
Mat setTo(Mat value, Mat mask) 
Mat setTo(Scalar s) 
Mat setTo(Scalar value, Mat mask) 
Size size() 
int size(int i) 
long step1() 
long step1(int i) 
Mat submat(int rowStart, int rowEnd, int colStart, int colEnd) 
Mat submat(Range rowRange, Range colRange) 
Mat submat(Rect roi) 
Mat t() 
java.lang.String toString() 
long total() 
int type() 
int width() 
static Mat zeros(int rows, int cols, int type) 
static Mat zeros(Size size, int type) 

这里也只是列举一下这个类的方法而已,看着非常之多,但是不难看出其实主要就是几类,一类是创建Mat或者修改已有Mat到指定属性值Mat对象的方法,一类是以获取Mat对象属性值的方法;其实就这两类,比我们常常用于存储信息的Bean对象多了一些第一类的方法而已,至少概念上可以这么理解。

1.2 Mat创建方式

        我对于上面关于Mat的API没有过多介绍,因为本身没有什么难度,下面就结合创建Mat对象简单说明一下,关于创建一个Mat对象有两大类,一个是从无到有,一个是从有到有,从有到有又分为两类,一个是复制,一个修改已有Mat对象的属性,可以简单用下图表示一下:

package com.hfut.operationopencvmain.Mat_Test;

import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.core.Size;

/**
 * author:why
 * created on: 2018/11/27 19:30
 * description:
 */
public class MatUtils {

    /**
     * create a Mat Object by it's create() method;the parameters can be different ,both
     * by Size and cows number and rows number
     *
     * @return
     */
    public static Mat method1() {
        Mat mat = new Mat();
        mat.create(new Size(10, 10), CvType.CV_16UC3);
        //mat.create(10,10,CvType.CV_16UC3);
        return mat;
    }


    /**
     * create a Mat object by it's static methods like eye(),ones() and zeros()
     * it's just like the usage of Matlab
     *
     * @return
     */
    public static Mat method2() {
        Mat mat = new Mat();
        mat = Mat.eye(new Size(10, 10), CvType.CV_16UC3);
        // mat=Mat.ones(new Size(10,10),CvType.CV_16UC3);
        // mat=Mat.zeros(new Size(10,10),CvType.CV_16UC3);
        return mat;
    }


    /**
     * create a Mat object by it's setTo() method ,this is similar to the first method
     *
     * @return
     */
    public static Mat method3() {
        Mat mat = new Mat(new Size(10, 10), CvType.CV_16UC3);
        mat = mat.setTo(new Scalar(0, 0, 0));
        return mat;
    }

    /**
     * create a Mat object by it's clone()  and copyTo() method,this is similar to the Object's clone()
     * actually,if you want a self define Object can be clone,you must implement the Cloneable interface
     * @return
     */
    public static Mat method4() {
        Mat mat = new Mat(new Size(10, 10), CvType.CV_16UC3);
        Mat mat1 = mat.clone();
        //Mat mat2=new Mat();
        // mat.copyTo(mat2);
        return mat1;
    }
}

1.3 几个概念

1.3.1 图像深度和图像通道数

这里借用《OpenCV Android开发实战》书中的表格释义一下:

图像深度
图像深度 Java中对应的数据类型
CV_8U=0 8位byte
CV_8S=1 8位byte
CV_16U=2 16位char
CV_16S=3 16位char
CV_32S=4 32位整形 -int
CV_32F=5 32位-float
CV_64F=6 64位-double

其中U表示无符号,S表示符号整形,F表示浮点型;还有就是一个图像通道的概念,在Android当中,我们在使用Bitmap时,Bitmap.Config API中有几个类型常量:

ALPHA_8
           
ARGB_4444
           
ARGB_8888
           
RGB_565

其中RGB_565就表示RGB三通道16位的含义,其他类似,所以在OpenCV中把图片加载成Mat对象时也有通道的概念,也是对应的1,3,4通道。这样通道和图像深度组合在一起就构成了Mat对象的加载类型,这个主要可在CvType中能查看,下面就是CvType中所有的类型了:

static int CV_16S 
static int CV_16SC1 
static int CV_16SC2 
static int CV_16SC3 
static int CV_16SC4 
static int CV_16U 
static int CV_16UC1 
static int CV_16UC2 
static int CV_16UC3 
static int CV_16UC4 
static int CV_32F 
static int CV_32FC1 
static int CV_32FC2 
static int CV_32FC3 
static int CV_32FC4 
static int CV_32S 
static int CV_32SC1 
static int CV_32SC2 
static int CV_32SC3 
static int CV_32SC4 
static int CV_64F 
static int CV_64FC1 
static int CV_64FC2 
static int CV_64FC3 
static int CV_64FC4 
static int CV_8S 
static int CV_8SC1 
static int CV_8SC2 
static int CV_8SC3 
static int CV_8SC4 
static int CV_8U 
static int CV_8UC1 
static int CV_8UC2 
static int CV_8UC3 
static int CV_8UC4 
static int CV_USRTYPE1

其实它们的组成也很简单,就拿后面经常使用的一种类型来说CV_8UC3(inread方法默认使用类型),其中CV表示计算机视觉,8UC表示8位无符号char,3表示3通道(在OpenCv中3通道的顺序是GBR);其他类似。

2,Android中的Bitmap

关于这部分的类容我不想多做介绍,因为在Android开发过程中,我们对其使用应该是比较熟悉了的。

2.1 创建方式

其创建的方式主要有两类,一类是通过Bitmap工厂,一个是自身的静态方法;但更一层的可以知道,它也是存储图像信息的对象,创建其对象一个是根据已有的图像资源或者Bitmap对象创建,一个是构建信息填充到将要创建的Bitmap对象中,分别举例如下:

(1)根据已有的图像资源或者Bitmap对象创建

BitmapFactory静态方法

decodeFile(String pathName)

Bitmap静态方法

createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)

(2)构建信息填充到将要创建的Bitmap对象中

Bitmap静态方法

createBitmap(int[] colors, int width, int height, Bitmap.Config config)


2.2 Bitmap像素存储类型

这个在上面其实已经介绍过了,就是我们的Bitmap.Config中的枚举常量:

ALPHA_8
           
ARGB_4444
           
ARGB_8888
           
RGB_565

拿其中一个举例,ARGB_4444表示4通道,每一个通道4位,共两个字节,表示一个像素。

3 两者资源管理

(1)Mat对象在确定后续不使用时,需主动调用release()方法释放资源

(2)Bitmap在现有设备使用的OS版本里面是不需要主动释放资源(也可以保证资源的及时释放主动调用recycle()方法),已经被加入了垃圾回收(gc)机制里面

好了,本篇关于Mat和Bitmap的介绍到这里结束了。作为图像信息的载体,它们API本身逻辑非常之简单,总结好就行了。更多类容请往下看:

上一篇:OpenCV之处理图像前的基本准备工作

下一篇:OpenCV之Mat与Bitmap之间的转换

猜你喜欢

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