How to access camera with OpenCV and Java
This blog post is about plain Java, not Android
Complete Gradle example project at Github
I had hard time to test my OpenCV algorithm on desktop, because the existing tutorials were not good enough and I wasn’t able to see under the hood of my algorithm. So here is how I were able to show the frames on my Mac desktop.
Transform Mat to BufferedImage
This class can transfor OpenCV Mat to BufferedImage
package com.rapidprogrammer.javaopencv3swing;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
public class Mat2Image {
static{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
Mat mat = new Mat();
BufferedImage img;
public Mat2Image() {
}
public Mat2Image(Mat mat) {
getSpace(mat);
}
public void getSpace(Mat mat) {
int type = 0;
if (mat.channels() == 1) {
type = BufferedImage.TYPE_BYTE_GRAY;
} else if (mat.channels() == 3) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
this.mat = mat;
int w = mat.cols();
int h = mat.rows();
if (img == null || img.getWidth() != w || img.getHeight() != h || img.getType() != type)
img = new BufferedImage(w, h, type);
}
BufferedImage getImage(Mat mat){
getSpace(mat);
WritableRaster raster = img.getRaster();
DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
byte[] data = dataBuffer.getData();
mat.get(0, 0, data);
return img;
}
}
JFrame to show the camera feed with OpenCV
This class contains the main for the application.
package com.rapidprogrammer.javaopencv3swing;
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;
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();
}
}
});
}
public MyFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(0, 0, 1280, 720);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(0, 0, 0, 0));
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) { }
}
}
}
}
Simple Java class to open OpenCV VideoCapture
package com.rapidprogrammer.javaopencv3swing;
import org.opencv.core.Core;
import org.opencv.videoio.VideoCapture;
import java.awt.image.BufferedImage;
public class VideoCap {
static{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
VideoCapture cap;
Mat2Image mat2Img = new Mat2Image();
VideoCap(){
cap = new VideoCapture();
cap.open(0);
}
BufferedImage getOneFrame() {
cap.read(mat2Img.mat);
return mat2Img.getImage(mat2Img.mat);
}
}
Gradle configuration
apply plugin: 'java'
apply plugin: 'application'
// Modify the OpenCV folder is needed
def myOpenCV = '/usr/local/opt/opencv3/share/OpenCV/java/'
dependencies {
// OpenCV
// If you don't have OpenCV jar in the same folder, set the folder here
compile fileTree(dir: myOpenCV, include: ['*.jar'])
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
def myMainClass = 'com.rapidprogrammer.javaopencv3swing.MyFrame'
// Set the main class to gradle run
mainClassName = myMainClass
// Pass the path to gradle run
run {
systemProperty "java.library.path", myOpenCV
}
How to run this OpenCV Gradle project
./gradlew run
Run tasks comes from application-plugin and it requires the main class is defined mainClassName = 'com.example.main'
.
Remember to set the OpenCV library paths to match your OpenCV installation.
Complete Gradle example project at Github