OpenCV - GUI


Advertisements

In the earlier chapters, we have discussed how to read and save an image using OpenCV Java library. In addition to it, we can also display the loaded images in a separate window using GUI libraries such as AWT/Swings and JavaFX.

Converting Mat to Buffered Image

To read an image we use the method imread(). This method returns the image read in the form of Matrix. But, to use this image with GUI libraries (AWT/Swings and JavaFX), it should be converted as an object of the class BufferedImage of the package java.awt.image.BufferedImage.

Following are the steps to convert a Mat object of OpenCV to BufferedImage object.

Step 1: encode the Mat to MatOfByte

First of all, you need to convert the matrix to matrix of byte. You can do it using the method imencode() of the class Imgcodecs. Following is the syntax of this method.

imencode(ext, image, matOfByte);

This method accepts the following parameters −

  • Ext − A String parameter specifying the image format (.jpg, .png, etc.)

  • image − A Mat object of the image

  • matOfByte − An empty object of the class MatOfByte

Encode the image using this method as shown below.

//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);

Step 2: Convert the MatOfByte object to byte array

Convert the MatOfByte object into a byte array using the method toArray().

byte[] byteArray = matOfByte.toArray();

Step 3: Preparing the InputStream object

Prepare the InputStream object by passing the byte array created in the previous step to the constructor of the ByteArrayInputStream class.

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

Step 4: Preparing the InputStream object

Pass the Input Stream object created in the previous step to the read() method of the ImageIO class. This will return a BufferedImage object.

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

Displaying Image using AWT/Swings

To display an image using the AWT/Swings frame, first of all, read an image using the imread() method and convert it into BufferedImage following the above-mentioned steps.

Then, instantiate the JFrame class and add the buffered image created to the ContentPane of the JFrame, as shown below −

//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

The following program code shows how you can read an image and display it through swing window using OpenCV library.

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");     
   } 
}

On executing the above program, you will get the following output −

Image Loaded

In addition to that, you can see a window displaying the image loaded, as follows −

Displaying Image using Swings

Displaying Image using JavaFX

To display an image using JavaFX, first of all, read an image using the imread() method and convert it into BufferedImage. Then, convert the BufferedImage to WritableImage, as shown below.

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

Pass this WritableImage object to the constructor of the ImageView class.

ImageView imageView = new ImageView(writableImage);

Example

The following program code shows how to read an image and display it through JavaFX window using OpenCV library.

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); 
   } 
}

On executing the above program, you will get the following output −

Image Loaded

In addition to that, you can see a window displaying the image loaded, as follows −

Displaying Image using JavaFX
Advertisements