要拍攝圖像,我們可使用相機和掃描器等設備。 這些設備記錄圖像的數值(例如:像素值)。 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("圖片已保存成功~");
}
}
在執行上述程式時,將得到以下輸出 -
圖片已保存成功~
如果打開指定的路徑,可以看到保存的圖像如下 -