Java 整合 OpenCV4.4 之 学习OpenCV矩阵对象基础知识教程 (二)

一、OpenCV 矩阵 基础学习

我们有多种方法可以获得现实世界的数字图像:数码相机、扫描仪、计算机体层摄影或磁共振成像就是其中的几种。在每种情况下我们(人类)看到了什么是图像。但是,转换图像到我们的数字设备时我们的记录是图像的每个点的数值。OpenCV 是一个计算机视觉库,其主要的工作是处理和操作,进一步了解这些信息。因此,你需要学习和开始熟悉它的第一件事是理解OpenCV 是如何存储和处理图像。

 

早期的 OpenCV 中,使用 IplImage 和 CvMat 数据结构来表示图像。IplImage和 CvMat 都是 C 语言的结构。使用这两个结构的问题是内存需要手动管理,开发者必须清楚的知道何时需要申请内存,何时需要释放内存。这个开发者带来了一定的负担,开发者应该将更多精力用于算法设计,因此在新版本的 OpenCV 中引入了 Mat 类。
新加入的 Mat 类能够自动管理内存。使用 Mat 类,你不再需要花费大量精力在内存管理上。而且你的代码会变得很简洁,代码行数会变少。但 C++接口唯一的不足是当前一些嵌入式开发系统可能只支持 C 语言,如果你的开发平台支持C++,完全没有必要再用 IplImage 和 CvMat。在新版本的 OpenCV 中,开发者依然可以使用 IplImage 和 CvMat,但是一些新增加的函数只 供了 Mat 接口。

二、Mat(矩阵)对象

Mat(矩阵)对象是OpenCV框架的核心,掌握它你可以更加得心应手地使用OpenCV。

Mat 矩阵常用的方法:

1,Mat::t,//转置矩阵
2,Mat::inv, //反转矩阵
3,Mat::mul,//执行两个矩阵按元素相乘或这两个矩阵的除法
4,Mat::cross, //计算3元素向量的一个叉乘积
5,Mat::dot, //计算两向量的点乘
6,Mat::zeros, //返回指定的大小和类型的零数组
7,Mat::ones, //返回一个指定的大小和类型的全为1的数组
8,Mat::eye, //返回一个恒等指定大小和类型矩阵
如: Mat A = Mat::eye(4, 4, CV_32F)*0.1; / / 创建4 x 4 的对角矩阵并在对角线上以0.1的比率缩小。
9,Mat::create, //分配新的阵列数据
10,Mat::resize, //更改矩阵的行数
11,Mat::total,//返回数组元素的总数
12,Mat::isContinuous,//返回矩阵是否连续
13,Mat::elemSize, //返回矩阵元素大小 (以字节为单位)
14,Mat::elemSize1, //以字节为单位返回每个矩阵元素通道的大小
15,Mat::type,//返回一个矩阵元素的类型
16,Mat::depth, //返回一个矩阵元素的深度
17,Mat::channels, //返回矩阵通道的数目
18,Mat::step1, // 返回矩阵归一化迈出的一步
19,Mat::size,//为矩阵的大小
20,Mat::empty, //如果数组有没有 elemens,则返回 true
21,Mat::ptr, //返回指定矩阵行的指针
22,Mat::at, //返回对指定数组元素的引用
23,Mat::begin, //返回矩阵迭代器,并将其设置为第一矩阵元
24,Mat::end, //返回矩阵迭代器,并将其设置为 最后元素之后(after-last)的矩阵元

三、Mat对象构造函数

常用的构造函数有:

Mat::Mat()
无参数构造方法;
Mat::Mat(int rows, int cols, int type)
创建行数为 rows,列数为 col,类型为 type 的图像;
Mat::Mat(Size size, int type)
创建大小为 size,类型为 type 的图像;
Mat::Mat(int rows, int cols, int type, const Scalar& s)
创建行数为 rows,列数为 col,类型为 type 的图像,并将所有元素初始化为值 s;
Mat::Mat(Size size, int type, const Scalar& s)
创建大小为 size,类型为 type 的图像,并将所有元素初始化为值 s;
Mat::Mat(const Mat& m)
将 m 赋值给新创建的对象,此处不会对图像数据进行复制,m 和新对象共用图像数据;
Mat::Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP)
创建行数为 rows,列数为 col,类型为 type 的图像,此构造函数不创建图像数据所需内存,而是直接使用 data 所指内存,图像的行步长由 step指定。
Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP)
创建大小为 size,类型为 type 的图像,此构造函数不创建图像数据所需内存,而是直接使用 data 所指内存,图像的行步长由 step 指定。
Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)
创建的新图像为 m 的一部分,具体的范围由 rowRange 和 colRange 指定,此构造函数也不进行图像数据的复制操作,新图像与 m 共用图像数据;
Mat::Mat(const Mat& m, const Rect& roi)
创建的新图像为 m 的一部分,具体的范围 roi 指定,此构造函数也不进行图像数据的复制操作,新图像与 m 共用图像数据。
这些构造函数中,很多都涉及到类型 type。type 可以是 CV_8UC1,CV_16SC1,...,CV_64FC4 等。里面的 8U 表示 8 位无符号整数,16S 表示 16 位有符号整数,64F表示 64 位浮点数(即 double 类型);C 后面的数表示通道数,例如 C1 表示一个通道的图像,C4 表示 4 个通道的图像,以此类推。

四、单通道矩阵

一、矩阵:

  1、一维矩阵:矩阵里的元素的坐标是x

  2、二维矩阵:矩阵里的元素的坐标是(x,y)

  3、三维矩阵:矩阵里的元素的坐标是(x,y,z)

二、通道:

  1、单通道:每个坐标点有1个值,即矩阵的一个元素(一个像素点)由1个值构成

  2、双通道:每个坐标点有2个值,即矩阵的一个元素(一个像素点)由2个值构成

要创建一个每个“点”只有一个通道的简单矩阵,通常用到Mat类中以下三个静态函数中的一个:zeros,eye,ones。

通过表可以更清楚地看到这三个函数的用途。

Java 整合 OpenCV4.4 之 学习OpenCV矩阵对象基础知识教程 (二)_第1张图片

五、通过例子实现3个静态函数

前三个Mat 例子简单地显示了加载每个像素为单通道的Mat对象的三种方法,以及第四个 mat3 加载每个像素包含三个通道的Mat对象的一种方法。

 public static void main(String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        
        Mat mat = Mat.eye(3,3,CvType.CV_8UC1);
        out.println("mat = ");
        out.println(mat.dump());

        Mat mat1 = Mat.zeros(3,3,CvType.CV_8UC1);
        out.println("mat1 = ");
        out.println(mat1.dump());

        Mat mat2 = Mat.ones(3,3,CvType.CV_8UC1);
        out.println("mat2 = ");
        out.println(mat2.dump());
        
        // 每个像素包含三个通道
        Mat mat3 = Mat.zeros(1,1,CvType.CV_8UC3);
        out.println("mat3 = ");
        out.println(mat3.dump());
    }

}

Java 整合 OpenCV4.4 之 学习OpenCV矩阵对象基础知识教程 (二)_第2张图片

在许多情况下,你可能并不会从头创建矩阵,而是从文件中加载图像。

如有不当之处请多多指教,如对你有所帮助,请留言或点赞予以支持,谢谢!

你可能感兴趣的:(OpenCV,1024程序员节)