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) 

成员方法:

MatadjustROI(int dtop, int dbottom, int dleft, int dright) 
voidassignTo(Mat m) 
voidassignTo(Mat m, int type) 
intchannels() 
intcheckVector(int elemChannels) 
intcheckVector(int elemChannels, int depth) 
intcheckVector(int elemChannels, int depth, boolean requireContinuous) 
Matclone() 
Matcol(int x) 
MatcolRange(int startcol, int endcol) 
MatcolRange(Range r) 
intcols() 
voidconvertTo(Mat m, int rtype) 
voidconvertTo(Mat m, int rtype, double alpha) 
voidconvertTo(Mat m, int rtype, double alpha, double beta) 
voidcopyTo(Mat m) 
voidcopyTo(Mat m, Mat mask) 
voidcreate(int rows, int cols, int type) 
voidcreate(Size size, int type) 
Matcross(Mat m) 
longdataAddr() 
intdepth() 
Matdiag() 
Matdiag(int d) 
static Matdiag(Mat d) 
intdims() 
doubledot(Mat m) 
java.lang.Stringdump() 
longelemSize() 
longelemSize1() 
booleanempty() 
static Mateye(int rows, int cols, int type) 
static Mateye(Size size, int type) 
double[]get(int row, int col) 
intget(int row, int col, byte[] data) 
intget(int row, int col, double[] data) 
intget(int row, int col, float[] data) 
intget(int row, int col, int[] data) 
intget(int row, int col, short[] data) 
longgetNativeObjAddr() 
intheight() 
Matinv() 
Matinv(int method) 
booleanisContinuous() 
booleanisSubmatrix() 
voidlocateROI(Size wholeSize, Point ofs) 
Matmul(Mat m) 
Matmul(Mat m, double scale) 
static Matones(int rows, int cols, int type) 
static Matones(Size size, int type) 
voidpush_back(Mat m) 
intput(int row, int col, byte[] data) 
intput(int row, int col, byte[] data, int offset, int length) 
intput(int row, int col, double... data) 
intput(int row, int col, float[] data) 
intput(int row, int col, int[] data) 
intput(int row, int col, short[] data) 
voidrelease() 
Matreshape(int cn) 
Matreshape(int cn, int rows) 
Matreshape(int cn, int[] newshape) 
Matrow(int y) 
MatrowRange(int startrow, int endrow) 
MatrowRange(Range r) 
introws() 
MatsetTo(Mat value) 
MatsetTo(Mat value, Mat mask) 
MatsetTo(Scalar s) 
MatsetTo(Scalar value, Mat mask) 
Sizesize() 
intsize(int i) 
longstep1() 
longstep1(int i) 
Matsubmat(int rowStart, int rowEnd, int colStart, int colEnd) 
Matsubmat(Range rowRange, Range colRange) 
Matsubmat(Rect roi) 
Matt() 
java.lang.StringtoString() 
longtotal() 
inttype() 
intwidth() 
static Matzeros(int rows, int cols, int type) 
static Matzeros(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=08位byte
CV_8S=18位byte
CV_16U=216位char
CV_16S=316位char
CV_32S=432位整形 -int
CV_32F=532位-float
CV_64F=664位-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 intCV_16S 
static intCV_16SC1 
static intCV_16SC2 
static intCV_16SC3 
static intCV_16SC4 
static intCV_16U 
static intCV_16UC1 
static intCV_16UC2 
static intCV_16UC3 
static intCV_16UC4 
static intCV_32F 
static intCV_32FC1 
static intCV_32FC2 
static intCV_32FC3 
static intCV_32FC4 
static intCV_32S 
static intCV_32SC1 
static intCV_32SC2 
static intCV_32SC3 
static intCV_32SC4 
static intCV_64F 
static intCV_64FC1 
static intCV_64FC2 
static intCV_64FC3 
static intCV_64FC4 
static intCV_8S 
static intCV_8SC1 
static intCV_8SC2 
static intCV_8SC3 
static intCV_8SC4 
static intCV_8U 
static intCV_8UC1 
static intCV_8UC2 
static intCV_8UC3 
static intCV_8UC4 
static intCV_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之间的转换

注:欢迎扫码关注

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值