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.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("圖片已儲存成功~");
   } 
}

在執行上述程式時,將得到以下輸出 -

圖片已儲存成功~

如果開啟指定的路徑,可以看到儲存的影象如下 -