当前位置: 首页 > 教程 > OpenCV >

OpenCV存储图像

精华
小牛编辑
130浏览
2023-03-14

要拍摄图像,我们可使用相机和扫描仪等设备。 这些设备记录图像的数值(例如:像素值)。 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.coreCvType类的各个字段表示。

方法和描述

以下是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.imageioImageIO类提供读取和写入图像的方法。

示例

可以使用以下程序代码使用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("图片已保存成功~");
   } 
}

在执行上述程序时,将得到以下输出 -

图片已保存成功~

如果打开指定的路径,可以看到保存的图像如下 -