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: