Daha öncelerde opencv kurulumuna ve eclipse üzerinde nasıl tanıtıldığına bakmıştık (https://mesutpiskin.com/blog/opencv-egitim-serisi.html) ,şimdi sistemdeki kameralar üzerinden görüntü alma işleminin nasıl yapıldığına göz atacağız.Opencv 3.0 sürümünü kullanırsanız 3.0 ile bazı paketler ve sınıflar değişikliğe uğradı için problemler ile karşılaşabilirsiniz bu yüzden bu örnek için 2.x sürümlerini kullanmanızı öneririm.
3 Adet sınıfımız olacak bir tanesi kameraya bağlanmak bir tanesi resimleri yakalamak diğeri ise frame sınıfı webcam görüntüsünü form üzerinde görüntülemek için.
Mat2Image sınıfımız:
import java.awt.image.BufferedImage; import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class Mat2Image { Mat mat = new Mat(); BufferedImage img; byte[] dat; public Mat2Image() { } public Mat2Image(Mat mat) { getSpace(mat); } public void getSpace(Mat mat) { this.mat = mat; int w = mat.cols(), h = mat.rows(); if (dat == null || dat.length != w * h * 3) dat = new byte[w * h * 3]; if (img == null || img.getWidth() != w || img.getHeight() != h || img.getType() != BufferedImage.TYPE_3BYTE_BGR) img = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR); } BufferedImage getImage(Mat mat){ getSpace(mat); mat.get(0, 0, dat); img.getRaster().setDataElements(0, 0, mat.cols(), mat.rows(), dat); return img; } static{ //Open cv native library System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } }
VideoCap sınıfı web kameraları yakalayacağımız sınıf
import java.awt.image.BufferedImage; import org.opencv.core.Core; import org.opencv.highgui.Highgui; import org.opencv.highgui.VideoCapture; public class VideoCap { static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } VideoCapture cap; Mat2Image mat2Img = new Mat2Image(); VideoCap(){ cap = new VideoCapture(); //Bazı kameralarda sorun çıkartabileceği için boyutları oldukça küçük olarak ayarladım kameranıza göre hd olarak değiştirebilirsiniz cap.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, 50); cap.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, 50); /*0 yaparsanız varsayılan kamera çalışır birden fazla kamera var ise 1 , 2 ,3 şeklinde numaları devam edektir. linux kullanıyorsanız lsusb ile bağlı usb kameraları görüntüleyebilirsiniz.*/ cap.open(0); } BufferedImage getOneFrame() { cap.read(mat2Img.mat); return mat2Img.getImage(mat2Img.mat); } }
JFrame den kalıtılmış sınıfımızda frame üzerinde kamera görüntüsünü oynatacağız.
import java.awt.EventQueue; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; public class MyFrame extends JFrame { private JPanel contentPane; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { MyFrame frame = new MyFrame(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public MyFrame() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 650, 490); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); new MyThread().start(); } VideoCap videoCap = new VideoCap(); public void paint(Graphics g){ g = contentPane.getGraphics(); g.drawImage(videoCap.getOneFrame(), 0, 0, this); } class MyThread extends Thread{ @Override public void run() { for (;;){ repaint(); try { Thread.sleep(30); } catch (InterruptedException e) { } } } } }
Harici usb kamera ile görüntüyü yakalıyoruz.