计算机视觉 OpenCV Android | Mat与Bitmap对象(创建、初始化、使用与转换 | 附大量demo)...

本文详细介绍了OpenCV中Mat对象的使用,包括加载图片、创建与初始化、保存图像。同时,讲解了Android中的Bitmap对象,如何加载图像和读写像素。重点讨论了Mat与Bitmap之间的转换,以及内存管理和显示问题,涉及到通道数、通道顺序和透明通道的处理。此外,还涵盖了基础形状的绘制与填充。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内容提要:
图像深度:表示每个通道灰度值所占的大小,大小即占几个位,是什么数据类型
图像类型:基于图像深度表述的信息,多了一个尾缀Cx,表示图像的通道数x个;

1. Mat对象
  • Mat是OpenCV中用来存储图像信息的内存对象
  • 当通过Imgcodecs.imread()方法从文件读入一个图像文件时,imread方法就会返回Mat对象实例;
  • 或者通过Utils.bitmatToMat()方法由Bitmap对象转换得到Mat对象实例。

下图形象地展示了一张图像中的各个像素点数据是如何存储的,
因为图像本身的像素点比较多,下图显示的图像像素数据只是图片左上角20×20大小的部分数据:

9125154-35c01dfe7723d9c4.png



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中常见的几种图像深度
    9125154-13606692da9845c2.png
  • U表示无符号整型
  • S表示符号整型
  • F表示浮点数
    这些类型在CvType中可以自己查看。OpenCV中常见的图像类型如下:
    9125154-897b8cecbdb4a533.png
    9125154-5da82e1147f49f65.png

当调用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在内存中的结构:
9125154-1871aeca1d7d2af8.png
  • 创建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对象——m1m2,它们的大小都是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);

上述代码创建了<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凌川江雪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值