¿Capturando una imagen de una cámara web en Java?


85

¿Cómo puedo capturar imágenes continuamente desde una cámara web?

Quiero experimentar con el reconocimiento de objetos (tal vez usando Java Media Framework).

Estaba pensando en crear dos hilos

un hilo:

  • Nodo 1: capturar imagen en vivo
  • Nodo 2: guardar imagen como "1.jpg"
  • Nodo 3: espera 5 segundos
  • Nodo 4: repetir ...

otro hilo:

  • Nodo 1: espere hasta que se capture la imagen
  • Nodo 2: usando el "1.jpg" obtén colores de cada pixe
  • Nodo 3: guardar datos en matrices
  • Nodo 4: repetir ...

2
Aquí está su respuesta: programa Java Swing para capturar imágenes de la cámara web tutorial Modifíquelo ligeramente y listo ..
Aman

Respuestas:


49

Esta implementación de JavaCV funciona bien.

Código:

import org.bytedeco.javacv.*;
import org.bytedeco.opencv.opencv_core.IplImage;

import java.io.File;

import static org.bytedeco.opencv.global.opencv_core.cvFlip;
import static org.bytedeco.opencv.helper.opencv_imgcodecs.cvSaveImage;

public class Test implements Runnable {
    final int INTERVAL = 100;///you may use interval
    CanvasFrame canvas = new CanvasFrame("Web Cam");

    public Test() {
        canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
    }

    public void run() {

        new File("images").mkdir();

        FrameGrabber grabber = new OpenCVFrameGrabber(0); // 1 for next camera
        OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
        IplImage img;
        int i = 0;
        try {
            grabber.start();

            while (true) {
                Frame frame = grabber.grab();

                img = converter.convert(frame);

                //the grabbed frame will be flipped, re-flip to make it right
                cvFlip(img, img, 1);// l-r = 90_degrees_steps_anti_clockwise

                //save
                cvSaveImage("images" + File.separator + (i++) + "-aa.jpg", img);

                canvas.showImage(converter.convert(img));

                Thread.sleep(INTERVAL);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Test gs = new Test();
        Thread th = new Thread(gs);
        th.start();
    }
}

También hay una publicación sobre la configuración de JavaCV

Puede modificar los códigos y poder guardar las imágenes a intervalos regulares y hacer el resto del procesamiento que desee.


4
+1 ¡Eres genial! Estaba buscando una buena alternativa de código abierto y compatible a JMF para capturas de cámara web tanto en Windows como en Linux. ¡Esto funciona de maravilla! Gracias :)
maple_shaft

2
No me funciona, dice Exception in thread "main" java.lang.UnsatisfiedLinkError: C: \ Users \ steve \ AppData \ Local \ Temp \ javacpp213892357885346 \ jniopencv_core.dll: No se pueden encontrar bibliotecas dependientes
Stepan Yakovenko

Esto funcionará, pero la calidad del video no es tan buena como debería ser. Vea mi respuesta para una mejor calidad de salida de video.
syb0rg

Gracias por la sugerencia. ¿Me interesa cómo configurarlo en Windows? ¿Necesito el zip extraído de 3Gb? De lo contrario, mi programa, usando JavaCV en Linux, funciona bien.
Ilian Zapryanov

@StepanYakovenko necesita OpenCV instalado.
Matthieu

33

Hace algún tiempo, creé una biblioteca genérica de Java que se puede usar para tomar fotografías con una cámara web de PC. La API es muy simple, no está sobrecargada, puede funcionar de forma independiente, pero también admite controladores de cámara web adicionales como OpenIMAJ, JMF, FMJ, LTI-CIVIL, etc., y algunas cámaras IP.

El enlace al proyecto es https://github.com/sarxos/webcam-capture

Código de ejemplo (tomar una foto y guardar en test.jpg):

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

También está disponible en Maven Central Repository o como un ZIP separado que incluye todas las dependencias requeridas y JAR de terceros.


1
Para empezar, vale la pena echarle un vistazo. El código funcionó muy bien para mí, espero que tú también :)
mrswadge

@Bartosz Firyn: hola, estoy trabajando con tu API. ¡Hombre de trabajo increíble! pero ahora quiero saber si el zoom en la cámara es compatible o no. ¿Cómo hacer zoom en la cámara usando esta API?
Java Man

@JavaMan, no hay soporte nativo para hacer zoom.
Bartosz Firyn

2
@JavaMan, puede dibujar en el panel que muestra la vista desde la cámara (WebcamPanel) configurando su instancia de Painter personalizada, o directamente en la imagen que proviene de la cámara usando la función WebcamImageTransformer. Para obtener más detalles, abra el ticket en la página del proyecto Webcam Capture en Github, ya que no quiero explicar esto en detalle aquí en Stack Overflow (demasiado para escribir y muy pocos caracteres para usar en los comentarios). El proyecto se puede encontrar aquí github.com/sarxos/webcam-capture
Bartosz Firyn

1
@Elyas Hadizadeh, en caso de problemas, siempre puede crear un nuevo ticket de emisión en github.com/sarxos/webcam-capture, donde también puede encontrar documentación y ejemplos. También tenga en cuenta que este es un marco para personas bastante familiarizadas con Java. En caso de que sea un principiante en Java, también hay personas dispuestas a ayudar, pero debe aprender los conceptos básicos por su cuenta.
Bartosz Firyn


5

Aquí hay una pregunta similar con algunas respuestas, pero no aceptadas. Uno de ellos menciona FMJ como una alternativa de Java a JMF.


5

Este tipo de respuesta se desprende de gt_ebuddy usando JavaCV, pero mi salida de video es de una calidad mucho mayor que su respuesta. También he añadido algunas otras mejoras al azar (como el cierre del programa cuando ESCy CTRL+Cson presionados, y asegurándose de que el cierre de los recursos que el programa utiliza correctamente).

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;
    }
}


3

He usado JMF en una aplicación de videoconferencia y funcionó bien en dos computadoras portátiles: una con cámara web integrada y otra con una vieja cámara web USB. Requiere que JMF esté instalado y configurado de antemano, pero una vez que haya terminado, puede acceder al hardware a través del código Java con bastante facilidad.


3

Puedes probar Marvin Framework . Proporciona una interfaz para trabajar con cámaras. Además, también proporciona un conjunto de funciones de procesamiento de video en tiempo real, como rastreo y filtrado de objetos.

¡Echar un vistazo!

Demostración de procesamiento de video en tiempo real:
http://www.youtube.com/watch?v=D5mBt0kRYvk

Puede utilizar la fuente a continuación. Simplemente guarde un marco usando MarvinImageIO.saveImage () cada 5 segundos.

Demostración de video de cámara web:

public class SimpleVideoTest extends JFrame implements Runnable{

    private MarvinVideoInterface    videoAdapter;
    private MarvinImage             image;
    private MarvinImagePanel        videoPanel;

    public SimpleVideoTest(){
        super("Simple Video Test");
        videoAdapter = new MarvinJavaCVAdapter();
        videoAdapter.connect(0);
        videoPanel = new MarvinImagePanel();
        add(videoPanel);
        new Thread(this).start();
        setSize(800,600);
        setVisible(true);
    }
    @Override
    public void run() {
        while(true){
            // Request a video frame and set into the VideoPanel
            image = videoAdapter.getFrame();
            videoPanel.setImage(image);
        }
    }
    public static void main(String[] args) {
        SimpleVideoTest t = new SimpleVideoTest();
        t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Para aquellos que solo quieren tomar una sola foto:

WebcamPicture.java

public class WebcamPicture {
    public static void main(String[] args) {
        try{
            MarvinVideoInterface videoAdapter = new MarvinJavaCVAdapter();
            videoAdapter.connect(0);
            MarvinImage image = videoAdapter.getFrame();
            MarvinImageIO.saveImage(image, "./res/webcam_picture.jpg");
        } catch(MarvinVideoInterfaceException e){
            e.printStackTrace();
        }
    }
}

2

http://grack.com/downloads/school/enel619.10/report/java_media_framework.html

Uso del reproductor con swing

El reproductor también se puede utilizar fácilmente en una aplicación Swing. El siguiente código crea un programa de captura de TV basado en Swing con la salida de video que se muestra en toda la ventana:

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();
    }
}

2

Usé Webcam Capture API ... puedes descargarlo desde este http://webcam-capture.sarxos.pl/

        webcam = Webcam.getDefault();
        webcam.open();

        if (webcam.isOpen()) { //if web cam open 
            BufferedImage image = webcam.getImage();
            JLabel imageLbl = new JLabel();
            imageLbl.setSize(640, 480);             //show captured image
            imageLbl.setIcon(new ImageIcon(image));

            int showConfirmDialog = JOptionPane.showConfirmDialog(null, imageLbl, "Image Viewer", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, new ImageIcon(""));

            if (showConfirmDialog == JOptionPane.YES_OPTION) {
                JFileChooser chooser = new JFileChooser();
                chooser.setDialogTitle("Save Image");
                chooser.setFileFilter(new FileNameExtensionFilter("IMAGES ONLY", "png", "jpeg", "jpg")); //this file extentions are shown
                int showSaveDialog = chooser.showSaveDialog(this);
                if (showSaveDialog == 0) {                  //if pressed 'Save' button
                    String filePath = chooser.getCurrentDirectory().toString().replace("\\", "/");
                    String fileName = chooser.getSelectedFile().getName(); //get user entered file name to save
                    ImageIO.write(image, "PNG", new File(filePath + "/" + fileName + ".png"));

                }
            }
        }

Debe proporcionar alguna explicación junto con el código
fen1x

1
Gracias. es ligero y en cambio javacv este funciona para mí.
Lucke

1

A Java generalmente no le gusta acceder al hardware, por lo que necesitará un programa controlador de algún tipo, como dijo goldenmean. Hice esto en mi computadora portátil al encontrar un programa de línea de comandos que toma una foto. Entonces es lo mismo que explica goldenmean; ejecuta el programa de línea de comando desde su programa java en la rutina takepicture (), y el resto de su código se ejecuta de la misma manera.

Excepto por la parte sobre la lectura de valores de píxeles en una matriz, es mejor que guarde el archivo en BMP, que ya es casi ese formato, y luego use las bibliotecas de imágenes estándar de Java en él.

El uso de un programa de línea de comandos agrega una dependencia a su programa y lo hace menos portátil, pero también lo era la cámara web, ¿verdad?


1

Recomiende el uso de FMJ para la aplicación Java relativa a multimedia.


0

Creo que el software de aplicación de la cámara web que viene con la cámara web, o el software nativo de la cámara web de Windows, se puede ejecutar en un script por lotes (script de Windows / DOS) después de encender la cámara web (es decir, si necesita una fuente de alimentación externa). suministro). En el script bacth, puede agregar un retraso apropiado para capturar después de cierto período de tiempo. Y siga ejecutando el comando de captura en bucle.

Supongo que esto debería ser posible

-ANUNCIO


0

Hay una interfaz bastante agradable para esto en el procesamiento , que es una especie de pidgin java diseñado para gráficos. Se utiliza en algunos trabajos de reconocimiento de imágenes, como ese enlace.

Dependiendo de lo que necesite de él, es posible que pueda cargar la biblioteca de videos que se usa allí en Java, o si solo está jugando con ella, es posible que pueda obtener utilizando el procesamiento en sí.


0

FMJ puede hacer esto, al igual que la biblioteca de apoyo que utiliza, LTI-CIVIL. Ambos están en sourceforge.


0

Intente usar JMyron Cómo usar la cámara web con Java . Creo que usar JMyron es la forma más fácil de acceder a una cámara web usando Java. Intenté usarlo con un procesador de 64 bits, pero me dio un error. Sin embargo, funcionó bien en un procesador de 32 bits.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.