Camera is a very important piece of equipment in computer vision. My first tutorial will be a webcam program based on OpenCV.
1. We need an efficient piece of code that convert OpenCV image, a Mat, to a BufferedImage.
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{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
}
2. Here is a simple class that captures video:
import java.awt.image.BufferedImage;
import org.opencv.core.Core;
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();
cap.open(0);
}
BufferedImage getOneFrame() {
cap.read(mat2Img.mat);
return mat2Img.getImage(mat2Img.mat);
}
}
3. Now we need a JFrame to display the video:
package org.ski;
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) { }
}
}
}
}
Works perfect, first trial! Wow! bravo and merci!
ReplyDeleteHey,
ReplyDeletethe problem is that highgui is not supported anymore under java.
Do you have any suggestions?
Thanks
use Imgcodecs.imwrite
Delete"org.opencv.videoio.VideoCapture" worked for me.
DeleteWhen I run this code "as is" I am getting red and blue channels swapped.
ReplyDeleteYou can use this to swap red and blue channels:
DeleteImgproc.cvtColor(mat,mat,Imgproc.COLOR_RGB2BGR);
thank you
DeleteThis code is very helpful, but where should this line go to swap red and blue back?
DeleteYou need to place it in the getSpace() method in your Mat2Image class.
DeletePerfect. the best tutorial -code on internet.
ReplyDeleteMany thanks
your code is really help me sir. i wanna ask you how many frames per second that we got from this code.
ReplyDeletei've tried to analyzed it for this code which means for create an image file:
public void paint(Graphics g){
g = contentPane.getGraphics();
g.drawImage(videoCap.getOneFrame(), 0, 0, this);
}
and it takes 3FPS. i used webcam camera with resolution 640x480 it should take 7FPS. but i got 3 FPS. can you help me ?
thanks
It's so perfect! Thank you so much!! XD
ReplyDeleteI'm sorry, I'm new at this, aren't we supposed to have a main to run the code?
ReplyDeleteplease help
MyFrame.java has a main function.
DeleteHi,
ReplyDeleteIs it possible to use three cameras with this code? I tried with three cameras, it works if they are displayed in different windows but it does not work to be displayed in the same Jframe.
Do you know if is it possible to have 3 videos streamed in the same window in different JPnalels?
Thanks in advance.
Спасибо за код и комментарии! мне тоже помогло смещение каналов синего и красного. Теперь мне интересно как добавить распознавание лиц и автомобильных номеров к этому примеру.
ReplyDeleteThanks, this is a very useful introduction to OpenCV Java.
ReplyDeleteI hope that you can find time to write some more blogs.
This comment has been removed by the author.
ReplyDeletecan i detect color in live stream and how?
ReplyDeleteHow many classes should I create in netbeans to run this?
ReplyDeleteThank you.
ReplyDeletesir, I need java code for Capturing image and save it as file. I am waiting for your reply sir. thank you
ReplyDeleteThis comment has been removed by the author.
ReplyDeletehow can i change Jframe to a Jpanel?
ReplyDeleteto get output directly relating to your camera. Now you can control your camera with the Gphoto2 command line tool but first see if your camera it is recognized by the command 8mp Hikvision
ReplyDeleteReplace:
ReplyDeleteVideoCap(){
cap = new VideoCapture();
cap.open(0);
}
with:
VideoCap(){
cap = new VideoCapture("http://admin:admin@192.168.1.8/cgi/mjpg/mjpeg.cgi");
}
If you want to read from an ip camera, replace with a url.
To find out your specific manufacturer url google for it.
I use Trendnet: https://www.ispyconnect.com/man.aspx?n=Trend+Net#
Thank you for sharing your code. It is a nice stepup into Opencv and Java.
ReplyDeleteThank you very much sir. You're a genious...!!!
ReplyDeleteThank you
ReplyDeleteCode is working fine.. nice job
ReplyDeleteThe author has composed this blog in an extremely informal way.
ReplyDeleteuse-droidcam-wireless-webcam
sir i want to save the captured video in local storage space.
ReplyDelete