内容提要:
图像深度
:表示每个通道灰度值所占的大小
,大小即占几个位,是什么数据类型
;图像类型
:基于图像深度表述的信息
,多了一个尾缀Cx
,表示图像的通道数
是x
个;
1. Mat对象
-
Mat
是OpenCV中用来存储图像信息的内存对象
; - 当通过
Imgcodecs.imread()
方法从文件读入一个图像文件时,imread方法就会返回Mat
对象实例; - 或者通过
Utils.bitmatToMat()
方法由Bitmap对象转换得到Mat
对象实例。
下图形象地展示了一张图像中的各个像素点数据是如何存储的,
因为图像本身的像素点比较多,下图显示的图像像素数据只是图片左上角20×20大小的部分数据:

1.1 加载图片与读取基本信息
-
从Android系统中选择一张图像
时,可以使用如下代码将图像文件加载为Mat对象:
Mat src = Imgcodecs.imread(fileUri.getPath());
- OpenCV通过imread来加载图像,
默认加载
的是三通道顺序为BGR
的彩色图像;
还可以通过以下代码来指定加载为彩色图像:(比上一句多了第二个参数)
Mat src = Imgcodecs.imread(fileUri.getPath(), Imgcodecs.IMREAD_COLOR)
如上这句代码,
第一个参数表示文件路径;
第二个参数表示加载图像类型
,最常见的类型有如下几种:
- IMREAD_UNCHANGED= -1,表示
不改变加载图像类型
,可能包含透明通道
。 - IMREAD_GRAYSCALE= 0,表示加载图像为
灰度图像
。 - IMREAD_COLOR= 1,表示加载图像为
彩色图像
。
使用如下代码从Mat对象
中得到图像的宽、高、维度、通道数、深度、类型信息
:
int width = src.cols();
int height = src.rows();
int dims = src.dims();
int channels = src.channels();
int depth = src.depth();
int type = src.type();
其中要特别关注通道数、图像深度与图像类型、OpenCV加载的Mat类型图像对象
。
-
常见的通道数目
有1、3、4
,分别对应于单通道、三通道、四通道
,其中四通道
中通常会有透明通道的数据
; -
图像深度
表示每个通道灰度值所占的大小
,图像深度与类型密切相关;
OpenCV中常见的几种图像深度
: -
U
表示无符号整型
; -
S
表示符号整型
; -
F
表示浮点数
;
这些类型在CvType
中可以自己查看。OpenCV中常见的图像类型
如下:
当调用imread
函数时,
如果只使用文件路径参数读入加载一张图像,则默认值
是三通道
的CV_8UC3
,图像深度
为CV_8U
,
其中:
-
CV
表示计算机视觉; -
8
表示八位; -
UC
表示无符号char; -
3
表示三个通道。
在如上的七行类型表中,每个类型都可以做类似的解读;
也可以看出CV_8U就是图像深度
,所以图像类型与深度之间是有直接关系
的。
1.2 Mat创建与初始化
- 综上,Mat对象中包含了图像的各种基本信息与图像像素数据;
-
Mat
是由头部
与数据部分
组成的,其中头部还包含一个指向数据的指针
。 - 在OpenCV4Android的接口封装中,因为Java层面没有
指针对象
,因此全部用数组
来替代; - 但是,当我们需要把
Mat对象
传到JNI层
的时候,
可以通过getNativeObjAddr()
方法来实现Mat对象从Java层
到C++层
的指针传递
;

-
创建Mat对象的方法
有很多种,如下几种最常见:
1)通过create
方法创建:
Mat m1 = new Mat();
m1.create(new Size(3, 3), CvType.CV_8UC3);
Mat m2 = new Mat();
m2.create(3, 3, CvType.CV_8UC3);
上述代码创建两个Mat对象——m1
与m2
,它们的大小都是3×3、类型都是三通道8位的无符号字符型。
2)通过ones、eye、zeros
方法初始化创建:
Mat m3 = Mat.eye(3, 3,CvType.CV_8UC3);
Mat m4 = Mat.eye(new Size(3, 3),CvType.CV_8UC3);
Mat m5 = Mat.zeros(new Size(3, 3), CvType.CV_8UC3);
Mat m6 = Mat.ones(new Size(3, 3), CvType.CV_8UC3);
上述代码创建了<