OpenCV - 存储图像

为了捕获图像,我们使用相机和扫描仪等设备。这些设备记录图像的数值(例如:像素值)。OpenCV 是一个处理数字图像的库,因此我们需要存储这些图像以供处理。

OpenCV 库的 Mat 类用于存储图像的值。它表示一个 n 维数组,用于存储灰度或彩色图像、体素体积、矢量场、点云、张量、直方图等的图像数据。

此类由两个数据部分组成:headerpointer

  • Header −包含大小、存储方法、矩阵地址(大小恒定)等信息。

  • 指针 −存储图像的像素值(不断变化)。

Mat 类

OpenCV Java 库在 org.opencv.core 包中提供了具有相同名称(Mat)的此类。

构造函数

OpenCV Java 库的 Mat 类具有各种构造函数,您可以使用它们构造 Mat 对象。

S.No 构造函数和说明
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)

7

Mat(Mat m, Range rowRange)

此构造函数接受另一个矩阵的对象和 Range 类的对象,该类表示要创建新矩阵所要采用的行的范围。

8

Mat(Mat m, Range rowRange, Range colRange)

除了前一个构造函数的参数外,此构造函数还接受该类的对象。 Range 表示列范围。

9

Mat(Mat m, Rect roi)

此构造函数接受两个对象,一个表示另一个矩阵,另一个表示感兴趣的R区域。

注意

  • 数组类型。使用 CV_8UC1、...、CV_64FC4 创建 1-4 通道矩阵,或使用 CV_8UC(n)、...、CV_64FC(n) 创建多通道(最多 CV_CN_MAX 个通道)矩阵。

  • 矩阵的类型由属于 org.opencv.core 包的 CvType 类的各个字段表示。

方法和说明

以下是 Mat 类提供的一些方法。

S.No 方法和说明
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)

此方法接受 Scalar 类型的对象并将数组元素设置为指定值。

创建和显示矩阵

在本节中,我们将讨论第一个 OpenCV 示例。我们将了解如何创建和显示一个简单的 OpenCV 矩阵。

下面给出了在 OpenCV 中创建和显示矩阵要遵循的步骤。

步骤 1:加载 OpenCV 本机库

在使用 OpenCV 库编写 Java 代码时,您需要执行的第一步是使用 loadLibrary() 加载 OpenCV 的本机库。按如下所示加载 OpenCV 本机库。

//加载核心库
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

步骤 2:实例化 Mat 类

使用本章前面提到的任何函数实例化 Mat 类。

//创建矩阵
Mat matrix = new Mat(5, 5, CvType.CV_8UC1, new Scalar(0));

步骤 3:使用方法填充矩阵

您可以通过将索引值传递给方法 row()/col() 来检索矩阵的特定行/列。

并且,您可以使用 setTo() 方法的任何变体为这些值设置值。

//检索索引为 0 的行
Mat row0 = matrix.row(0);

//设置索引为 0 的行中所有元素的值
row0.setTo(new Scalar(1));

//检索索引为 3 的行
Mat col3 = matrix.col(3);

//设置索引为 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) {     
    //加载核心库
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    
    //创建矩阵
    Mat matrix = new Mat(5, 5, CvType.CV_8UC1, new Scalar(0));
    
    //检索索引为 0 的行
    Mat row0 = matrix.row(0);
    
    //设置索引为 0 的行中所有元素的值
    row0.setTo(new Scalar(1));
    
    //检索索引为 3 的行
    Mat col3 = matrix.col(3);
    
    //设置索引为 3 的行中所有元素的值
    col3.setTo(new Scalar(3));

	//打印矩阵
      System.out.println("OpenCV Mat data:
" + 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 类用于存储图像,而 import javax.imageio 包中的 ImageIO 类提供读取和写入图像的方法。

示例

您可以使用以下程序代码通过 JavaSE 库加载和保存图像。

import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import javax.imageio.ImageIO;
  
public class LoadingImage_JSE_library {
   public static void main( String[] args ) throws IOException {
        //输入文件
        File input = new File("C:/EXAMPLES/OpenCV/sample.jpg");
        
        //读取图像
        BufferedImage image = ImageIO.read(input);
        
        //使用不同名称保存图像
        File ouptut = new File("C:/OpenCV/sample.jpg");
        ImageIO.write(image, "jpg", ouptut);
        
        System.out.println("image Saved");
   } 
}

执行上述程序后,你将获得以下输出 −

image Saved

如果打开指定路径,可以如下图观察保存的图像 −

Loading Image using JavaSE API