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
Contents
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
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
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
- IMREAD_COLOR: Gambar yang dimuat akan diubah menjadi gambar berwarna 3-channel BGR (Blue Green Red).
- IMREAD_GRAYSCALE: gambar yang dimuat akan diubah menjadi gambar grayscale saluran tunggal.
- IMREAD_LOAD_GDAL: untuk format raster dan geospatial GDAL
- IMREAD_ANYCOLOR
- IMREAD_REDUCED_COLOR_2
- IMREAD_REDUCED_COLOR_4
- IMREAD_REDUCED_COLOR_8
- IMREAD_REDUCED_GRAYSCALE_2
- IMREAD_REDUCED_GRAYSCALE_4
- IMREAD_REDUCED_GRAYSCALE_8
- 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,
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
-
Imgproc.GaussianBlur(src, dst, new Size(45, 45), 0);
-
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
- dst − Mat 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