Belajar OpenCV bagian 1 – Setting OpenCV di Java

By | July 30, 2024
3,065 Views

Setting OpenCV di Java – Yup OpenCV 4.5.0 telah direlease, saya lebih suka menggunakan library OpenCV sebagai library digital image processing sejak dulu sampai sekarang karena dukungan yang sangat luas serta banyak tersedia wrapper untuk bahasa Python, Java, android bahkan Julia!

Pada postingan kali ini saya sengaja tidak membahas python ataupun julia, tapi lebih kepada penggunaan bahasa Java. Topik nya mulai dari instalasi serta menggunakan OpenCV di Java.

Sebagai informasi umum, berikut saya jabarkan versi yang digunakan, mulai dari opencv saja dulu, sedangkan untuk cara install JDK dan JRE java, bisa kalian pelajari disini https://softscients.com/2020/03/23/buku-belajar-bahasa-pemrograman-java-untuk-pemula/. Kalian pastikan sudah melakukan set path java juga yaitu dengan versi yang digunakan

  • Java Versi JDK dan JRE
    • java version “1.8.0_251”
    • Java(TM) SE Runtime Environment (build 1.8.0_251-b08)
    • Java HotSpot(TM) 64-Bit Server VM (build 25.251-b08, mixed mode)
  • Oiya saya menggunakan Netbeans sebagai editor nya
    • Product Version: Apache NetBeans IDE 12.0
  • Versi OpenCV Versi OpenCV yang digunakan yaitu 4.5.0 yang diinstall di C:/OpenCV. Bila kalian install akan terdapat 2 file penting yaitu *.dll (dynamic link library) dan *.jar (java archive)
    • C:\OpenCV\build\java\x64\opencv_java440.dll
    • C:\OpenCV\build\java\opencv-440.jar

Mencoba Project OpenCV di Netbeans

Setelah kalian memastikan semua diatas, kita akan membuat Project Netbeans berbasis Ant (bukan maven). Langkah-langkah nya yaitu pilih saja Java with Ant -> Java Application

Misalkan saya berikan project netbeans dengan nama Latihan OpenCV

Dilanjutkan add path library *.jar  dengan cara berikut

Jangan lupa kita juga harus setting Virtual Machine agar loading *.dll melalui cara berikut

 

Pilih Run -> VM Options

Perintah untuk VM Options:  yaitu

-Djava.library.path="C:\opencv\build\java\x64"

 

Melalui tahapan diatas, kalian sudah bisa menggunakan OpenCV sebagai library computer vision di Java

See also  OpenCV di Java SVM Bagian 4

Mencoba OpenCV di Java

Yuk kita buat kode berikut untuk mencoba OpenCV di java

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;

public class HelloCV {
        public static void main(String[] args) throws IOException{
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
            Mat mat = Mat.eye(3, 3, CvType.CV_8UC1);
            System.out.println("mat = " + mat.dump()); 
        }
}

Kode diatas bertujuan untuk membuat matrix/array identitas berukuran 3×3, berikut hasil ditampilkan untuk kode diatas

mat = [  1,   0,   0;
   0,   1,   0;
   0,   0,   1]

Hal penting pada kode diatas yaitu terdapat Java Native Interface (JNI) System.loadLibrary(Core.NATIVE_LIBRARY_NAME); merupakan implementasi JNI untuk meload *.dll (dynamic link library) OpenCV pada saat Java berjalan di Virtual Memory.

Tentu kita tidak hanya terbatas mencoba kode diatas, kita lanjutkan saja Bagaimana menampilkan gambar menggunakan opencv di Java

Menampilkan Gambar menggunakan OpenCV di Java

Untuk melakukan hal diatas, di java sudah disediakan library component GUI yaitu Swing, namun proses nya agak sedikit panjang karena butuh proses encoding. Saya akan membuat sebuah main class dengan nama ImageShow. Beberapa class yang kita butuhkan perlu kita load yaitu

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.imgcodecs.Imgcodecs;

Konvert Mat to Buffered Image

Untuk membaca gambar kita menggunakan metode imread (). Metode ini mengembalikan gambar yang dibaca dalam bentuk Matriks. Namun, untuk menggunakan image ini dengan library GUI (AWT / Swings dan JavaFX), image tersebut harus diubah sebagai objek kelas BufferedImage dari paket java.awt.image.BufferedImage.

Berikut adalah langkah-langkah untuk mengubah objek Mat dari OpenCV ke objek BufferedImage.

1. Encode Mat ke  MatOfByte

Pertama-tama, kalian perlu mengubah matriks menjadi matriks byte yaitu dengan menggunakan metode imencode () dari kelas Imgcodecs. Berikut adalah sintaks dari metode ini.

Imgcodecs imageCodecs = new Imgcodecs();
Mat matrix = imageCodecs.imread("E:/cat.png");

Encode gambar menggunakan metode ini seperti yang ditunjukkan di bawah ini.

MatOfByte mat = new MatOfByte();       
Imgcodecs.imencode(".png", matrix, mat); 

2. Konvert MatOfByte ke byte array

Ubah objek MatOfByte menjadi array byte menggunakan metode toArray().

byte[] byteArray = mat.toArray();

3. Memanggil class InputStream object

Siapkan objek InputStream dengan meneruskan array byte yang dibuat pada langkah sebelumnya ke konstruktor kelas ByteArrayInputStream. Meneruskan objek Input Stream yang dibuat pada langkah sebelumnya ke metode read () kelas ImageIO. Ini akan mengembalikan objek BufferedImage. Kalian sudah tahu kan class BufferedImage yang merupakan core Image di Java, kalian bisa baca disini https://softscients.com/2020/03/27/buku-pengolahan-citra-digital-dengan-java/

InputStream in = new ByteArrayInputStream(byteArray); 
BufferedImage buf = ImageIO.read(in);

Tentu jika sudah didapatkan objek class BufferedImage, kita bisa menampilkan pada sebuah icon di JLabel

See also  Belajar OpenCV di Java KMean Bagian 3

4. Menampilkan Gambar menggunakan AWT / Swings

Untuk menampilkan gambar, kita cukup mengubah icon JLabel yang ditempelkan di JFrame, berikut kode lengkapnya

JFrame fr = new JFrame(); 
fr.getContentPane().add(new JLabel(new ImageIcon(buf))); 
fr.pack(); 
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fr.setVisible(true);

Bagaimana menurut kalian, agak ribet tapi ya begitulah tetap menyenangkan! karena kita bisa menggunakan ratusan function Image processing milik OpenCV lho!

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
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;

/**
 *
 * @author www.softscients.com
 */
public class ImageShow {

    /**
     * @param args the command line arguments
     * @throws java.io.IOException
     */
    public static void main(String[] args) throws IOException {
        // TODO code application logic here
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
            Imgcodecs imageCodecs = new Imgcodecs();
            Mat matrix = Imgcodecs.imread("E://cat.png");
            
            MatOfByte mat = new MatOfByte();       
            Imgcodecs.imencode(".png", matrix, mat); 

            byte[] byteArray = mat.toArray(); 
            
            InputStream in = new ByteArrayInputStream(byteArray); 
            BufferedImage buf = ImageIO.read(in); 
            
            JFrame fr = new JFrame(); 
            fr.getContentPane().add(new JLabel(new ImageIcon(buf))); 
            fr.pack(); 
            fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            fr.setVisible(true);
      

    }
    
}

 

Lebih jauh mengenal method imread

method imread() mempunyai sebuah flag di OpenCV, yaitu kita bisa memperlakukan gambar tersebut dibaca sebagai truecolor ataupun grayscale.

imread(filename, int flags)

Setiap flag mempunyai arti sendiri-sendiri yaitu dimulai dari angka 1 sampai dengan 7

  1. IMREAD_COLOR: Gambar yang dimuat akan diubah menjadi gambar berwarna 3-channel BGR (Blue Green Red).
  2. IMREAD_GRAYSCALE: gambar yang dimuat akan diubah menjadi gambar grayscale saluran tunggal.
  3. IMREAD_LOAD_GDAL: untuk format raster dan geospatial GDAL
  4. IMREAD_ANYCOLOR
  5. IMREAD_REDUCED_COLOR_2
  6. IMREAD_REDUCED_COLOR_4
  7. IMREAD_REDUCED_COLOR_8
  8. IMREAD_REDUCED_GRAYSCALE_2
  9. IMREAD_REDUCED_GRAYSCALE_4
  10. IMREAD_REDUCED_GRAYSCALE_8
  11. IMREAD_UNCHANGED

Kita coba saja, mengenai gambar cat.png diatas yang aslinya berwarna truecolor akan sengaja diload menjadi grayscale saja

Mat matrix = Imgcodecs.imread("E://cat.png",Imgcodecs.IMREAD_GRAYSCALE);

maka gambar tersebut akan diload menjadi grayscale

Mencoba Operasi Bluring

Jika kalian sudah pernah belajar mengenai teknik convolution seperti efek sharpening, bluring, maka di OpenCV sangat mudah, kita hanya cukup menggunakan perintah / function

Imgproc.blur(src, dst, size, point, Core.BORDER_DEFAULT);

Kita bisa mengubah size dan point nya,

See also  Perbaikan Deskewing Image

Karena image nya berukuran besar, saya akan beri tanda flags Imgcodecs.IMREAD_REDUCED_COLOR_2 agar ukurannya menjadi 1/2 nya

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
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.core.Point;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

/**
 *
 * @author www.softscients.com
 */
public class ImageShow {

    /**
     * @param args the command line arguments
     * @throws java.io.IOException
     */
    public static void main(String[] args) throws IOException {
        // TODO code application logic here
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
            Imgcodecs imageCodecs = new Imgcodecs();
            Mat matrix = Imgcodecs.imread("E://cat.png",Imgcodecs.IMREAD_REDUCED_COLOR_2);
            Mat blur = new Mat();
            
            Size size = new Size(10,10);
            Point point = new Point(5,5);
      
            Imgproc.blur(matrix,blur, size, point, Core.BORDER_DEFAULT);
            
            MatOfByte mat = new MatOfByte();       
            Imgcodecs.imencode(".png", blur, mat); 

            byte[] byteArray = mat.toArray(); 
            
            InputStream in = new ByteArrayInputStream(byteArray); 
            BufferedImage buf = ImageIO.read(in); 
            
            JFrame fr = new JFrame(); 
            fr.getContentPane().add(new JLabel(new ImageIcon(buf))); 
            fr.pack(); 
            fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            fr.setVisible(true);
      

    }
    
}

Kalian bisa coba-coba dengan efek yang lainnya yaitu

  1. Imgproc.GaussianBlur(src, dst, new Size(45, 45), 0);

  2. Imgproc.medianBlur(src, dst, 15);

Fungsi Thresholding

OpenCV juga menyediakan operasi thresholding

Imgproc.threshold(Mat src, Mat dst, double thresh, double maxval, int type);

Dengan keterangan sebagai berikut

  • src −  Mat object sebagai input citra
  • dstMat object sebagai target citra
  • thresh − nilai bulat positif, berkisar 0 sampai 255 tergantung dengan type konversi
  • maxval − nilai maksimal, bisa diset dengan 255
  • type − tipe dari citra RGB to Grayscale.

Contoh penggunaanya yaitu

import java.io.IOException;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs; 
import org.opencv.imgproc.Imgproc; 
public class Hello {
        public static void main(String[] args) throws IOException{
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);            
            String input = "E:/cat.png";             
            // To Read the image 
            Mat source = Imgcodecs.imread(input); 
            // Creating the empty destination matrix 
            Mat destination = new Mat();       
            // Converting the image to gray scale and  
            // saving it in the dst matrix 
            Imgproc.cvtColor(source, destination, Imgproc.COLOR_RGB2GRAY);            
            Imgproc.threshold(destination, destination, 128,256, Imgproc.THRESH_BINARY);
            // Writing the image 
            Imgcodecs.imwrite("E:/cat2.png", destination); 
            System.out.println("Done"); 
            
        }

}

Untuk demonya, saya sengaja menggunakan JSlider untuk mempermudah melihat hasilnya secara dinamis, berikut ketika nilai T = 95

Ketika nilai T=158