OpenCV - GUI

Trong các chương trước, chúng ta đã thảo luận về cách đọc và lưu một hình ảnh bằng thư viện OpenCV Java. Ngoài ra, chúng tôi cũng có thể hiển thị các hình ảnh đã tải trong một cửa sổ riêng biệt bằng cách sử dụng các thư viện GUI như AWT / Swings và JavaFX.

Chuyển đổi Mat thành Hình ảnh được đệm

Để đọc một hình ảnh, chúng tôi sử dụng phương pháp imread(). Phương thức này trả về hình ảnh đã đọc ở dạngMatrix. Tuy nhiên, để sử dụng hình ảnh này với các thư viện GUI (AWT / Swings và JavaFX), nó phải được chuyển đổi thành một đối tượng của lớpBufferedImage của gói java.awt.image.BufferedImage.

Sau đây là các bước để chuyển đổi một Mat đối tượng của OpenCV để BufferedImage vật.

Bước 1: Mã hóa Mat thành MatOfByte

Trước hết, bạn cần chuyển ma trận thành ma trận byte. Bạn có thể làm điều đó bằng phương phápimencode() của lớp Imgcodecs. Sau đây là cú pháp của phương thức này.

imencode(ext, image, matOfByte);

Phương thức này chấp nhận các tham số sau:

  • Ext - Một tham số Chuỗi chỉ định định dạng hình ảnh (.jpg, .png, v.v.)

  • image - Một đối tượng Mat của hình ảnh

  • matOfByte - Một đối tượng rỗng của lớp MatOfByte

Mã hóa hình ảnh bằng phương pháp này như hình dưới đây.

//Reading the image 
Mat image = Imgcodecs.imread(file);

//instantiating an empty MatOfByte class 
MatOfByte matOfByte = new MatOfByte();

//Converting the Mat object to MatOfByte 
Imgcodecs.imencode(".jpg", image, matOfByte);

Bước 2: Chuyển đối tượng MatOfByte thành mảng byte

Chuyển đổi MatOfByte đối tượng vào một mảng byte bằng phương pháp toArray().

byte[] byteArray = matOfByte.toArray();

Bước 3: Chuẩn bị đối tượng InputStream

Chuẩn bị đối tượng InputStream bằng cách chuyển mảng byte đã tạo ở bước trước tới hàm tạo của ByteArrayInputStream lớp học.

//Preparing the InputStream object 
InputStream in = new ByteArrayInputStream(byteArray);

Bước 4: Chuẩn bị đối tượng InputStream

Chuyển đối tượng Dòng đầu vào được tạo ở bước trước đó vào read() phương pháp của ImageIOlớp học. Điều này sẽ trả về một đối tượng BufferedImage.

//Preparing the BufferedImage 
BufferedImage bufImage = ImageIO.read(in);

Hiển thị hình ảnh bằng AWT / Swings

Để hiển thị hình ảnh bằng khung AWT / Swings, trước hết, hãy đọc hình ảnh bằng cách sử dụng imread() và chuyển đổi nó thành BufferedImage theo các bước nêu trên.

Sau đó, khởi tạo JFrame và thêm hình ảnh được tạo vào bộ đệm được tạo vào ContentPane của JFrame, như hình dưới đây -

//Instantiate JFrame 
JFrame frame = new JFrame();
 
//Set Content to the JFrame 
frame.getContentPane().add(new JLabel(new ImageIcon(bufImage))); 
frame.pack(); 
frame.setVisible(true);

Example

Mã chương trình sau đây cho biết cách bạn có thể read một hình ảnh và display nó thông qua cửa sổ xoay sử dụng thư viện OpenCV.

import java.awt.image.BufferedImage;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.imgcodecs.Imgcodecs;

public class DisplayingImagesUsingSwings {
   public static void main(String args[]) throws Exception { 
      //Loading the OpenCV core library  
      System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); 
    
      //Reading the Image from the file and storing it in to a Matrix object 
      String file = "C:/EXAMPLES/OpenCV/sample.jpg"; 
      Mat image = Imgcodecs.imread(file); 
    
      //Encoding the image 
      MatOfByte matOfByte = new MatOfByte();       
      Imgcodecs.imencode(".jpg", image, matOfByte); 

      //Storing the encoded Mat in a byte array 
      byte[] byteArray = matOfByte.toArray(); 

      //Preparing the Buffered Image 
      InputStream in = new ByteArrayInputStream(byteArray); 
      BufferedImage bufImage = ImageIO.read(in); 

      //Instantiate JFrame 
      JFrame frame = new JFrame(); 

      //Set Content to the JFrame 
      frame.getContentPane().add(new JLabel(new ImageIcon(bufImage))); 
      frame.pack(); 
      frame.setVisible(true);
      
      System.out.println("Image Loaded");     
   } 
}

Khi thực hiện chương trình trên, bạn sẽ nhận được kết quả sau:

Image Loaded

Ngoài ra, bạn có thể thấy một cửa sổ hiển thị hình ảnh đã tải, như sau:

Hiển thị hình ảnh bằng JavaFX

Để hiển thị một hình ảnh bằng JavaFX, trước hết, hãy đọc một hình ảnh bằng cách sử dụng imread() và chuyển đổi nó thành BufferedImage. Sau đó, chuyển đổi BufferedImage thành WlikeImage, như hình dưới đây.

WritableImage writableImage = SwingFXUtils.toFXImage(bufImage, null);

Vượt qua WritableImage phản đối hàm tạo của ImageView lớp học.

ImageView imageView = new ImageView(writableImage);

Example

Đoạn mã chương trình sau đây cho biết cách read một hình ảnh và display nó thông qua cửa sổ JavaFX sử dụng thư viện OpenCV.

import java.awt.image.BufferedImage;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.stage.Stage;

import javax.imageio.ImageIO;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.imgcodecs.Imgcodecs;

public class DisplayingImagesJavaFX extends Application {
   @Override 
   public void start(Stage stage) throws IOException {   
      WritableImage writableImage = loadImage(); 
  
      //Setting the image view 
      ImageView imageView = new ImageView(writableImage); 
        
      //Setting the position of the image 
      imageView.setX(50); 
      imageView.setY(25); 
        
      //setting the fit height and width of the image view 
      imageView.setFitHeight(400); 
      imageView.setFitWidth(500);
      
      //Setting the preserve ratio of the image view
      imageView.setPreserveRatio(true);
      
      //Creating a Group object  
      Group root = new Group(imageView);
      
      //Creating a scene object
      Scene scene = new Scene(root, 600, 400);
      
      //Setting title to the Stage 
      stage.setTitle("Loading an image");
      
      //Adding scene to the stage
      stage.setScene(scene);

      //Displaying the contents of the stage
      stage.show();
   } 
   public WritableImage loadImage() throws IOException {
      //Loading the OpenCV core library  
      System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
      
      //Reading the Image from the file and storing it in to a Matrix object
      String file ="C:/EXAMPLES/OpenCV/sample.jpg";
      Mat image = Imgcodecs.imread(file);
      
      //Encoding the image
      MatOfByte matOfByte = new MatOfByte();
      Imgcodecs.imencode(".jpg", image, matOfByte);

      //Storing the encoded Mat in a byte array
      byte[] byteArray = matOfByte.toArray();
      
      //Displaying the image
      InputStream in = new ByteArrayInputStream(byteArray); 
      BufferedImage bufImage = ImageIO.read(in);

      System.out.println("Image Loaded");
      WritableImage writableImage = SwingFXUtils.toFXImage(bufImage, null);
      return writableImage; 
   }
   public static void main(String args[]) {
      launch(args); 
   } 
}

Khi thực hiện chương trình trên, bạn sẽ nhận được kết quả sau:

Image Loaded

Ngoài ra, bạn có thể thấy một cửa sổ hiển thị hình ảnh đã tải, như sau: