Capturando imagem da webcam em java?


85

Como posso capturar continuamente imagens de uma webcam?

Quero experimentar o reconhecimento de objetos (talvez usando a estrutura de mídia java).

Eu estava pensando em criar dois tópicos

um tópico:

  • Nó 1: captura de imagem ao vivo
  • Nó 2: salvar imagem como "1.jpg"
  • Nó 3: aguarde 5 segundos
  • Nó 4: repetir ...

outro tópico:

  • Nó 1: aguarde até que a imagem seja capturada
  • Nó 2: usando "1.jpg" obter cores de cada pixle
  • Nó 3: salvar dados em matrizes
  • Nó 4: repetir ...

2
Aqui está sua resposta-- Programa Java Swing para capturar imagens do tutorial da webcam Modifique ligeiramente e pronto ..
Aman

Respostas:


49

Esta implementação JavaCV funciona bem.

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

Também há post sobre configuração para JavaCV

Você pode modificar os códigos e ser capaz de salvar as imagens em intervalos regulares e fazer o resto do processamento que desejar.


4
+1 Você é demais! Eu estava procurando um bom código aberto e uma alternativa compatível com o JMF para capturas de webcam no Windows e no Linux. Isso funciona como um encanto! Obrigado :)
maple_shaft

2
Não funciona para mim, diz Exceção no tópico "main" java.lang.UnsatisfiedLinkError: C: \ Users \ steve \ AppData \ Local \ Temp \ javacpp213892357885346 \ jniopencv_core.dll: Não é possível encontrar bibliotecas dependentes
Stepan Yakovenko

Isso funcionará, mas a qualidade do vídeo não é tão boa quanto deveria. Veja minha resposta para melhor qualidade de saída de vídeo.
syb0rg

Obrigado pela sugestão. Estou interessado em como configurá-lo no Windows? Eu preciso do zip extraído do 3Gb? Caso contrário, meu programa, usando JavaCV no Linux, funciona bem.
Ilian Zapryanov

@StepanYakovenko você precisa do OpenCV instalado.
Matthieu

33

Há algum tempo, criei uma biblioteca Java genérica que pode ser usada para tirar fotos com uma webcam de PC. A API é muito simples, não tem recursos excessivos, pode funcionar de forma independente, mas também oferece suporte a drivers de webcam adicionais, como OpenIMAJ, JMF, FMJ, LTI-CIVIL, etc, e algumas câmeras IP.

O link para o projeto é https://github.com/sarxos/webcam-capture

Código de exemplo (tire uma foto e salve em test.jpg):

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

Ele também está disponível no Repositório Central Maven ou como um ZIP separado que inclui todas as dependências necessárias e JARs de terceiros.


1
Para facilitar os primeiros passos, vale a pena dar uma olhada. O código funcionou muito bem para mim, espero que você também :)
mrswadge

@Bartosz Firyn: olá, estou trabalhando com sua API. trabalho incrível cara! mas agora eu quero saber se zoom na câmera é compatível ou não? como dar zoom na câmera usando esta API?
Java Man

@JavaMan, não há suporte nativo para zoom.
Bartosz Firyn 01 de

2
@JavaMan, você pode desenhar no painel que exibe a visualização da câmera (WebcamPanel) definindo sua instância personalizada do Painter ou diretamente na imagem que vem da câmera usando o recurso WebcamImageTransformer. Para mais detalhes, abra o tíquete na página do projeto Captura de Webcam no Github, pois não quero explicar isso em detalhes aqui no Stack Overflow (muito para escrever e poucos caracteres para usar nos comentários). O projeto pode ser encontrado aqui github.com/sarxos/webcam-capture
Bartosz Firyn

1
@Elyas Hadizadeh, em caso de problemas você sempre pode criar um novo tíquete de problema em github.com/sarxos/webcam-capture onde você também pode encontrar documentação e exemplos. Lembre-se também de que este é um framework para pessoas bastante familiarizadas com Java. Caso você seja um novato em Java, também há pessoas dispostas a ajudar, mas você precisa aprender o básico por conta própria.
Bartosz Firyn


5

Aqui está uma pergunta semelhante com algumas - ainda não aceitas - respostas. Um deles menciona o FMJ como alternativa em java ao JMF.


5

Este tipo de resposta de gt_ebuddy usando JavaCV, mas minha saída de vídeo está com uma qualidade muito superior à resposta dele. Também adicionei algumas outras melhorias aleatórias (como fechar o programa quando ESCe CTRL+Csão pressionados e certificar-se de fechar os recursos que o programa usa corretamente).

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

Usei o JMF em um aplicativo de videoconferência e funcionou bem em dois laptops: um com webcam integrada e outro com uma webcam USB antiga. Ele requer que o JMF seja instalado e configurado com antecedência, mas quando terminar, você pode acessar o hardware via código Java com bastante facilidade.


3

Você pode experimentar o Marvin Framework . Ele fornece uma interface para trabalhar com câmeras. Além disso, ele também fornece um conjunto de recursos de processamento de vídeo em tempo real, como rastreamento e filtragem de objetos.

Dê uma olhada!

Demonstração de processamento de vídeo em tempo real:
http://www.youtube.com/watch?v=D5mBt0kRYvk

Você pode usar a fonte abaixo. Basta salvar um quadro usando MarvinImageIO.saveImage () a cada 5 segundos.

Demonstração de vídeo da webcam:

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 quem quer tirar apenas uma 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

Usando o Player com Swing

O Player também pode ser facilmente usado em um aplicativo Swing. O código a seguir cria um programa de captura de TV baseado em Swing com a saída de vídeo exibida em toda a janela:

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

Eu usei a API de captura de webcam ... você pode baixar deste 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"));

                }
            }
        }

Você deve fornecer alguma explicação junto com o código
fen1x

1
obrigado. é leve e, em vez disso, javacv, este funciona para mim.
Lucke,

1

Java geralmente não gosta de acessar hardware, então você precisará de algum tipo de programa de driver, como disse goldenmean. Fiz isso no meu laptop, encontrando um programa de linha de comando que tira uma foto. Então é o mesmo que Goldenmean explicou; você executa o programa de linha de comando a partir de seu programa java na rotina takepicture () e o resto do código é executado da mesma forma.

Exceto pela parte sobre a leitura de valores de pixel em uma matriz, você pode se beneficiar melhor salvando o arquivo em BMP, que já é quase esse formato, e então usando as bibliotecas de imagens java padrão nele.

Usar um programa de linha de comando adiciona uma dependência ao seu programa e o torna menos portátil, mas a webcam também era, certo?


1

Recomenda usando FMJ para aplicativo java relativado de multimídia.


0

Acredito que o software aplicativo da webcam que vem junto com a webcam, ou seu software nativo da webcam do Windows, pode ser executado em um script em lote (script do windows / dos) após ligar a webcam (ou seja, se precisar de energia externa fornecem). No script bacth, você pode adicionar um atraso apropriado para capturar após um determinado período de tempo. E continue executando o comando de captura em loop.

Eu acho que isso deveria ser possível

-DE ANÚNCIOS


0

Há uma interface muito boa para isso no processamento , que é uma espécie de pidgin java projetado para gráficos. Ele é usado em alguns trabalhos de reconhecimento de imagem, como aquele link.

Dependendo do que você precisa, pode ser capaz de carregar a biblioteca de vídeo que é usada lá em java ou, se estiver apenas brincando com ela, pode conseguir usando o próprio processamento.


0

A FMJ pode fazer isso, assim como a biblioteca de suporte que usa, LTI-CIVIL. Ambos estão no sourceforge.


0

Tente usar JMyron. Como usar a webcam usando Java . Acho que usar JMyron é a maneira mais fácil de acessar uma webcam usando java. Tentei usá-lo com um processador de 64 bits, mas ocorreu um erro. No entanto, funcionou muito bem em um processador de 32 bits.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.