OpenCV存储图像
要拍摄图像,我们可使用相机和扫描仪等设备。 这些设备记录图像的数值(例如:像素值)。 OpenCV是一个处理数字图像的库,因此需要存储这些图像进行处理。
OpenCV库的Mat
类用于存储图像的值。它代表一个n
维数组,用于存储灰度或彩色图像,体素体积,矢量场,点云,张量,直方图等图像数据。
这个类包含两个数据部分:头部(header
)和一个指针(pointer
)
- 头部 - 包含大小,用于存储的方法和矩阵地址(大小不变)等信息。
- 指针 - 存储图像的像素值(保持不变)。
Mat类
OpenCV Java库在包org.opencv.core
中为这个类提供了相同的名字(Mat
)。
构造函数
OpenCV Java库的Mat类有各种构造函数,使用它们可以构造Mat
对象。
编号 | 构造函数 | 描述 |
---|---|---|
1 | Mat() |
这是大多数情况下使用没有参数的默认构造函数。使用这个构造函数来创建一个空矩阵,并将其传递给其他OpenCV方法。 |
2 | Mat(int rows, int cols, int type) |
这个构造函数接受三个整数类型的参数,表示二维数组的行数和列数,以及数组的类型(用于存储数据)。 |
3 | Mat(int rows, int cols, int type, Scalar s) |
包括前一个的参数,此构造函数还接受Scalar 类的一个对象作为参数。 |
4 | Mat(Size size, int type) |
这个构造函数接受两个参数,一个表示矩阵大小的对象和一个表示用于存储数据的数组类型的整数。 |
5 | Mat(Size size, int type, Scalar s) |
包括前一个的参数,此构造函数还接受Scalar 类的一个对象作为参数。 |
6 | Mat(long addr) |
只用一个long 类型作为参数 |
7 | Mat(Mat m, Range rowRange) |
此构造函数接受另一个矩阵的对象,并且该类的对象表示要创建新矩阵的行的范围。 |
8 | Mat(Mat m, Range rowRange, Range colRange) |
包括前一个的参数,这个构造函数还接受类的一个对象。表示列范围的范围。 |
9 | Mat(Mat m, Rect roi) |
这个构造函数接受两个对象,一个表示另一个矩阵,另一个表示兴趣区域。 |
注 -
- 数组类型。 使用
CV_8UC1
,...
,CV_64FC4
创建1-4个通道矩阵,或使用CV_8UC(n)
,...
,CV_64FC(n)
创建多通道(最多CV_CN_MAX
通道)矩阵。 - 矩阵的类型由属于包
org.opencv.core
的CvType
类的各个字段表示。
方法和描述
以下是Mat
类提供的一些方法。
编号 | 方法 | 描述 |
---|---|---|
1 | Mat col(int x) |
此方法接受表示列索引的整数参数,检索并返回该列。 |
2 | Mat row(int y) |
此方法接受一个表示行索引的整数参数,检索并返回该行。 |
3 | int cols() |
此方法返回矩阵中的列数。 |
4 | int rows() |
此方法返回矩阵中的行数。 |
5 | Mat setTo(Mat value) |
此方法接受Mat 类型的对象,并将数组元素设置为指定的值。 |
6 | Mat setTo(Scalar s) |
此方法接受标量类型的对象,并将数组元素设置为指定的值。 |
创建和显示矩阵
在本节中,我们将讨论第一个OpenCV示例。将看到如何创建和显示一个简单的OpenCV矩阵。
下面给出了在OpenCV中创建和显示矩阵的步骤。
第1步:加载OpenCV本机库
在使用OpenCV库编写Java代码时,您需要做的第一步是使用loadLibrary()加载OpenCV本地库。 加载OpenCV本机库,如下所示。
//Loading the core library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
第2步:实例化Mat类
使用前面提到的任何函数来实例化Mat
类。
//Creating a matrix
Mat matrix = new Mat(5, 5, CvType.CV_8UC1, new Scalar(0));
第3步:使用方法填充矩阵
可以通过将索引值传递给方法row()/ col()
来检索矩阵的特定行/列。
而且,可以使用setTo()
方法的任何变体来为这些值设置值。
//Retrieving the row with index 0
Mat row0 = matrix.row(0);
//setting values of all elements in the row with index 0
row0.setTo(new Scalar(1));
//Retrieving the row with index 3
Mat col3 = matrix.col(3);
//setting values of all elements in the row with index 3
col3.setTo(new Scalar(3));
示例
可以使用以下程序代码使用OpenCV库创建和显示Java中的简单矩阵。
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.CvType;
import org.opencv.core.Scalar;
class DisplayingMatrix {
public static void main(String[] args) {
//Loading the core library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//Creating a matrix
Mat matrix = new Mat(5, 5, CvType.CV_8UC1, new Scalar(0));
//Retrieving the row with index 0
Mat row0 = matrix.row(0);
//setting values of all elements in the row with index 0
row0.setTo(new Scalar(1));
//Retrieving the row with index 3
Mat col3 = matrix.col(3);
//setting values of all elements in the row with index 3
col3.setTo(new Scalar(3));
//Printing the matrix
System.out.println("OpenCV Mat data:\n" + matrix.dump());
}
}
在执行上述程序时,将得到以下输出 -
OpenCV Mat data:
[ 1, 1, 1, 3, 1;
0, 0, 0, 3, 0;
0, 0, 0, 3, 0;
0, 0, 0, 3, 0;
0, 0, 0, 3, 0]
使用JavaSE API加载图像
java.awt.image.BufferedImage
包中的BufferedImage
类用于存储图像,而javax.imageio
的ImageIO
类提供读取和写入图像的方法。
示例
可以使用以下程序代码使用JavaSE库加载和保存图像。
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class FirstApp {
public static void main( String[] args ) throws IOException {
//Input File
File input = new File("F:/worksp/opencv/images/qingshuiwan.jpg");
//Reading the image
BufferedImage image = ImageIO.read(input);
//Saving the image with a different name
File ouptut = new File("F:/worksp/opencv/images/qswan.jpg");
ImageIO.write(image, "jpg", ouptut);
System.out.println("图片已保存成功~");
}
}
在执行上述程序时,将得到以下输出 -
图片已保存成功~
如果打开指定的路径,可以看到保存的图像如下 -