dimanche 27 avril 2014

Capture d'image de la webcam en java ? -Débordement de pile


How can I continuously capture images from a webcam?


I want to experiment with object recognition (by maybe using java media framework).


I was thinking of creating two threads


one thread:



  • Node 1: capture live image

  • Node 2: save image as "1.jpg"

  • Node 3: wait 5 seconds

  • Node 4: repeat...


other thread:



  • Node 1: wait until image is captured

  • Node 2: using the "1.jpg" get colors from every pixle

  • Node 3: save data in arrays

  • Node 4: repeat...




This JavaCV implementation works fine.


Code:


import static com.googlecode.javacv.cpp.opencv_core.cvFlip;
import static com.googlecode.javacv.cpp.opencv_highgui.cvSaveImage;

import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.FrameGrabber;
import com.googlecode.javacv.VideoInputFrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
public class GrabberShow implements Runnable {
//final int INTERVAL=1000;///you may use interval
IplImage image;
CanvasFrame canvas = new CanvasFrame("Web Cam");
public GrabberShow() {
canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
}
@Override
public void run() {
FrameGrabber grabber = new VideoInputFrameGrabber(0);
int i=0;
try {
grabber.start();
IplImage img;
while (true) {
img = grabber.grab();
if (img != null) {
cvFlip(img, img, 1);// l-r = 90_degrees_steps_anti_clockwise
cvSaveImage((i++)+"-capture.jpg", img);
// show image on window
canvas.showImage(img);
}
//Thread.sleep(INTERVAL);
}
} catch (Exception e) {
}
}
}

There is also post on configuration for JavaCV


You can modify the codes and be able to save the images in regular interval and do rest of the processing you want.




JMyron is very simple for use. http://webcamxtra.sourceforge.net/


myron = new JMyron();
myron.start(imgw, imgh);
myron.update();
int[] img = myron.image();



Some time ago I've created generic Java library which can be used to take pictures with a PC webcam. The API is very simple, not overfeatured, can work standalone, but also supports additional webcam drivers like OpenIMAJ, JMF, FMJ, LTI-CIVIL, etc, and some IP cameras.


Link to the project is https://github.com/sarxos/webcam-capture


Example code (take picture and save in test.jpg):


Webcam webcam = Webcam.getDefault();
webcam.open()
BufferedImage image = webcam.getImage();
ImageIO.write(image, "JPG", new File("test.jpg"));

It is also available in Maven Central Repository or as a separate ZIP which includes all required dependencies and 3rd party JARs.




Here is a similar question with some - yet unaccepted - answers. One of them mentions FMJ as a java alternative to JMF.




This kind of goes off of gt_ebuddy's answer using JavaCV, but my video output is at a much higher quality then his answer. I've also added some other random improvements (such as closing down the program when ESC and CTRL+C are pressed, and making sure to close down the resources the program uses properly).


import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.KeyStroke;

import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.IplImage;

public class HighRes extends JComponent implements Runnable {
private static final long serialVersionUID = 1L;

private static CanvasFrame frame = new CanvasFrame("Web Cam");
private static boolean running = false;
private static int frameWidth = 800;
private static int frameHeight = 600;
private static OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
private static BufferedImage bufImg;

public HighRes()
{
// setup key bindings
ActionMap actionMap = frame.getRootPane().getActionMap();
InputMap inputMap = frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);

for (Keys direction : Keys.values())
{
actionMap.put(direction.getText(), new KeyBinding(direction.getText()));
inputMap.put(direction.getKeyStroke(), direction.getText());
}

frame.getRootPane().setActionMap(actionMap);
frame.getRootPane().setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap);

// setup window listener for close action
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
stop();
}
});
}

public static void main(String... args)
{
HighRes webcam = new HighRes();
webcam.start();
}

@Override
public void run()
{
try
{

grabber.setImageWidth(frameWidth);
grabber.setImageHeight(frameHeight);
grabber.start();
while (running)
{

final IplImage cvimg = grabber.grab();
if (cvimg != null)
{

// cvFlip(cvimg, cvimg, 1); // mirror

// show image on window
bufImg = cvimg.getBufferedImage();
frame.showImage(bufImg);
}
}
grabber.stop();
grabber.release();
frame.dispose();
}
catch (Exception e)
{
e.printStackTrace();
}
}

public void start()
{
new Thread(this).start();
running = true;
}

public void stop()
{
running = false;
}

private class KeyBinding extends AbstractAction {

private static final long serialVersionUID = 1L;

public KeyBinding(String text)
{
super(text);
putValue(ACTION_COMMAND_KEY, text);
}

@Override
public void actionPerformed(ActionEvent e)
{
String action = e.getActionCommand();
if (action.equals(Keys.ESCAPE.toString()) || action.equals(Keys.CTRLC.toString())) stop();
else System.out.println("Key Binding: " + action);
}
}
}

enum Keys
{
ESCAPE("Escape", KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)),
CTRLC("Control-C", KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_DOWN_MASK)),
UP("Up", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)),
DOWN("Down", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)),
LEFT("Left", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)),
RIGHT("Right", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));

private String text;
private KeyStroke keyStroke;

Keys(String text, KeyStroke keyStroke)
{
this.text = text;
this.keyStroke = keyStroke;
}

public String getText()
{
return text;
}

public KeyStroke getKeyStroke()
{
return keyStroke;
}

@Override
public String toString()
{
return text;
}
}



You can try Java Webcam SDK library also. SDK demo applet is available at link.




I have used JMF on a videoconference application and it worked well on two laptops: one with integrated webcam and another with an old USB webcam. It requires JMF being installed and configured before-hand, but once you're done you can access the hardware via Java code fairly easily.




You can try Marvin Framework. It provides an interface to work with cameras. Moreover, it also provides a set of real-time video processing features, like object tracking and filtering.


Take a look!


Marvin Framework: http://www.marvinproject.org


Real-time Video Processing Demo: http://www.youtube.com/watch?v=D5mBt0kRYvk




I believe the web-cam application software which comes along with the web-cam, or you native windows webcam software can be run in a batch script(windows/dos script) after turning the web cam on(i.e. if it needs an external power supply). In the bacth script , u can add appropriate delay to capture after certain time period. And keep executing the capture command in loop.


I guess this should be possible


-AD




Java usually doesn't like accessing hardware, so you will need a driver program of some sort, as goldenmean said. I've done this on my laptop by finding a command line program that snaps a picture. Then it's the same as goldenmean explained; you run the command line program from your java program in the takepicture() routine, and the rest of your code runs the same.


Except for the part about reading pixel values into an array, you might be better served by saving the file to BMP, which is nearly that format already, then using the standard java image libraries on it.


Using a command line program adds a dependency to your program and makes it less portable, but so was the webcam, right?




There's a pretty nice interface for this in processing, which is kind of a pidgin java designed for graphics. It gets used in some image recognition work, such as that link.


Depending on what you need out of it, you might be able to load the video library that's used there in java, or if you're just playing around with it you might be able to get by using processing itself.




FMJ can do this, as can the supporting library it uses, LTI-CIVIL. Both are on sourceforge.




Recommand using FMJ for multimedia relatived java app.




http://grack.com/downloads/school/enel619.10/report/java%5Fmedia%5Fframework.html


Using the Player with Swing


The Player can be easily used in a Swing application as well. The following code creates a Swing-based TV capture program with the video output displayed in the entire window:


import javax.media.*;
import javax.swing.*;
import java.awt.*;
import java.net.*;
import java.awt.event.*;
import javax.swing.event.*;

public class JMFTest extends JFrame {
Player _player;
JMFTest() {
addWindowListener( new WindowAdapter() {
public void windowClosing( WindowEvent e ) {
_player.stop();
_player.deallocate();
_player.close();
System.exit( 0 );
}
});
setExtent( 0, 0, 320, 260 );
JPanel panel = (JPanel)getContentPane();
panel.setLayout( new BorderLayout() );
String mediaFile = "vfw://1";
try {
MediaLocator mlr = new MediaLocator( mediaFile );
_player = Manager.createRealizedPlayer( mlr );
if (_player.getVisualComponent() != null)
panel.add("Center", _player.getVisualComponent());
if (_player.getControlPanelComponent() != null)
panel.add("South", _player.getControlPanelComponent());
}
catch (Exception e) {
System.err.println( "Got exception " + e );
}
}

public static void main(String[] args) {
JMFTest jmfTest = new JMFTest();
jmfTest.show();
}
}



Try using JMyron How To Use Webcam Using Java. I think using JMyron is the easiest way to access a webcam using java. I tried to use it with a 64-bit processor, but it gave me an error. It worked just fine on a 32-bit processor, though.



How can I continuously capture images from a webcam?


I want to experiment with object recognition (by maybe using java media framework).


I was thinking of creating two threads


one thread:



  • Node 1: capture live image

  • Node 2: save image as "1.jpg"

  • Node 3: wait 5 seconds

  • Node 4: repeat...


other thread:



  • Node 1: wait until image is captured

  • Node 2: using the "1.jpg" get colors from every pixle

  • Node 3: save data in arrays

  • Node 4: repeat...



This JavaCV implementation works fine.


Code:


import static com.googlecode.javacv.cpp.opencv_core.cvFlip;
import static com.googlecode.javacv.cpp.opencv_highgui.cvSaveImage;

import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.FrameGrabber;
import com.googlecode.javacv.VideoInputFrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
public class GrabberShow implements Runnable {
//final int INTERVAL=1000;///you may use interval
IplImage image;
CanvasFrame canvas = new CanvasFrame("Web Cam");
public GrabberShow() {
canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
}
@Override
public void run() {
FrameGrabber grabber = new VideoInputFrameGrabber(0);
int i=0;
try {
grabber.start();
IplImage img;
while (true) {
img = grabber.grab();
if (img != null) {
cvFlip(img, img, 1);// l-r = 90_degrees_steps_anti_clockwise
cvSaveImage((i++)+"-capture.jpg", img);
// show image on window
canvas.showImage(img);
}
//Thread.sleep(INTERVAL);
}
} catch (Exception e) {
}
}
}

There is also post on configuration for JavaCV


You can modify the codes and be able to save the images in regular interval and do rest of the processing you want.



JMyron is very simple for use. http://webcamxtra.sourceforge.net/


myron = new JMyron();
myron.start(imgw, imgh);
myron.update();
int[] img = myron.image();


Some time ago I've created generic Java library which can be used to take pictures with a PC webcam. The API is very simple, not overfeatured, can work standalone, but also supports additional webcam drivers like OpenIMAJ, JMF, FMJ, LTI-CIVIL, etc, and some IP cameras.


Link to the project is https://github.com/sarxos/webcam-capture


Example code (take picture and save in test.jpg):


Webcam webcam = Webcam.getDefault();
webcam.open()
BufferedImage image = webcam.getImage();
ImageIO.write(image, "JPG", new File("test.jpg"));

It is also available in Maven Central Repository or as a separate ZIP which includes all required dependencies and 3rd party JARs.



Here is a similar question with some - yet unaccepted - answers. One of them mentions FMJ as a java alternative to JMF.



This kind of goes off of gt_ebuddy's answer using JavaCV, but my video output is at a much higher quality then his answer. I've also added some other random improvements (such as closing down the program when ESC and CTRL+C are pressed, and making sure to close down the resources the program uses properly).


import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.KeyStroke;

import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.IplImage;

public class HighRes extends JComponent implements Runnable {
private static final long serialVersionUID = 1L;

private static CanvasFrame frame = new CanvasFrame("Web Cam");
private static boolean running = false;
private static int frameWidth = 800;
private static int frameHeight = 600;
private static OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
private static BufferedImage bufImg;

public HighRes()
{
// setup key bindings
ActionMap actionMap = frame.getRootPane().getActionMap();
InputMap inputMap = frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);

for (Keys direction : Keys.values())
{
actionMap.put(direction.getText(), new KeyBinding(direction.getText()));
inputMap.put(direction.getKeyStroke(), direction.getText());
}

frame.getRootPane().setActionMap(actionMap);
frame.getRootPane().setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap);

// setup window listener for close action
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
stop();
}
});
}

public static void main(String... args)
{
HighRes webcam = new HighRes();
webcam.start();
}

@Override
public void run()
{
try
{

grabber.setImageWidth(frameWidth);
grabber.setImageHeight(frameHeight);
grabber.start();
while (running)
{

final IplImage cvimg = grabber.grab();
if (cvimg != null)
{

// cvFlip(cvimg, cvimg, 1); // mirror

// show image on window
bufImg = cvimg.getBufferedImage();
frame.showImage(bufImg);
}
}
grabber.stop();
grabber.release();
frame.dispose();
}
catch (Exception e)
{
e.printStackTrace();
}
}

public void start()
{
new Thread(this).start();
running = true;
}

public void stop()
{
running = false;
}

private class KeyBinding extends AbstractAction {

private static final long serialVersionUID = 1L;

public KeyBinding(String text)
{
super(text);
putValue(ACTION_COMMAND_KEY, text);
}

@Override
public void actionPerformed(ActionEvent e)
{
String action = e.getActionCommand();
if (action.equals(Keys.ESCAPE.toString()) || action.equals(Keys.CTRLC.toString())) stop();
else System.out.println("Key Binding: " + action);
}
}
}

enum Keys
{
ESCAPE("Escape", KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)),
CTRLC("Control-C", KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_DOWN_MASK)),
UP("Up", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)),
DOWN("Down", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)),
LEFT("Left", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)),
RIGHT("Right", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));

private String text;
private KeyStroke keyStroke;

Keys(String text, KeyStroke keyStroke)
{
this.text = text;
this.keyStroke = keyStroke;
}

public String getText()
{
return text;
}

public KeyStroke getKeyStroke()
{
return keyStroke;
}

@Override
public String toString()
{
return text;
}
}


You can try Java Webcam SDK library also. SDK demo applet is available at link.



I have used JMF on a videoconference application and it worked well on two laptops: one with integrated webcam and another with an old USB webcam. It requires JMF being installed and configured before-hand, but once you're done you can access the hardware via Java code fairly easily.



You can try Marvin Framework. It provides an interface to work with cameras. Moreover, it also provides a set of real-time video processing features, like object tracking and filtering.


Take a look!


Marvin Framework: http://www.marvinproject.org


Real-time Video Processing Demo: http://www.youtube.com/watch?v=D5mBt0kRYvk



I believe the web-cam application software which comes along with the web-cam, or you native windows webcam software can be run in a batch script(windows/dos script) after turning the web cam on(i.e. if it needs an external power supply). In the bacth script , u can add appropriate delay to capture after certain time period. And keep executing the capture command in loop.


I guess this should be possible


-AD



Java usually doesn't like accessing hardware, so you will need a driver program of some sort, as goldenmean said. I've done this on my laptop by finding a command line program that snaps a picture. Then it's the same as goldenmean explained; you run the command line program from your java program in the takepicture() routine, and the rest of your code runs the same.


Except for the part about reading pixel values into an array, you might be better served by saving the file to BMP, which is nearly that format already, then using the standard java image libraries on it.


Using a command line program adds a dependency to your program and makes it less portable, but so was the webcam, right?



There's a pretty nice interface for this in processing, which is kind of a pidgin java designed for graphics. It gets used in some image recognition work, such as that link.


Depending on what you need out of it, you might be able to load the video library that's used there in java, or if you're just playing around with it you might be able to get by using processing itself.



FMJ can do this, as can the supporting library it uses, LTI-CIVIL. Both are on sourceforge.



Recommand using FMJ for multimedia relatived java app.



http://grack.com/downloads/school/enel619.10/report/java%5Fmedia%5Fframework.html


Using the Player with Swing


The Player can be easily used in a Swing application as well. The following code creates a Swing-based TV capture program with the video output displayed in the entire window:


import javax.media.*;
import javax.swing.*;
import java.awt.*;
import java.net.*;
import java.awt.event.*;
import javax.swing.event.*;

public class JMFTest extends JFrame {
Player _player;
JMFTest() {
addWindowListener( new WindowAdapter() {
public void windowClosing( WindowEvent e ) {
_player.stop();
_player.deallocate();
_player.close();
System.exit( 0 );
}
});
setExtent( 0, 0, 320, 260 );
JPanel panel = (JPanel)getContentPane();
panel.setLayout( new BorderLayout() );
String mediaFile = "vfw://1";
try {
MediaLocator mlr = new MediaLocator( mediaFile );
_player = Manager.createRealizedPlayer( mlr );
if (_player.getVisualComponent() != null)
panel.add("Center", _player.getVisualComponent());
if (_player.getControlPanelComponent() != null)
panel.add("South", _player.getControlPanelComponent());
}
catch (Exception e) {
System.err.println( "Got exception " + e );
}
}

public static void main(String[] args) {
JMFTest jmfTest = new JMFTest();
jmfTest.show();
}
}


Try using JMyron How To Use Webcam Using Java. I think using JMyron is the easiest way to access a webcam using java. I tried to use it with a 64-bit processor, but it gave me an error. It worked just fine on a 32-bit processor, though.


Related Posts:

0 commentaires:

Enregistrer un commentaire