Bild von der Webcam in Java aufnehmen?


85

Wie kann ich kontinuierlich Bilder von einer Webcam aufnehmen?

Ich möchte mit der Objekterkennung experimentieren (indem ich möglicherweise das Java Media Framework verwende).

Ich dachte daran, zwei Threads zu erstellen

ein Thread:

  • Knoten 1: Livebild aufnehmen
  • Knoten 2: Bild als "1.jpg" speichern
  • Knoten 3: Warten Sie 5 Sekunden
  • Knoten 4: Wiederholen ...

anderer Thread:

  • Knoten 1: Warten Sie, bis das Bild aufgenommen wurde
  • Knoten 2: Mit "1.jpg" erhalten Sie Farben von jedem Pixel
  • Knoten 3: Daten in Arrays speichern
  • Knoten 4: Wiederholen ...

2
Hier ist Ihre Antwort - Java Swing-Programm zum Aufnehmen von Bildern aus dem Webcam-Tutorial Ändern Sie es leicht und Sie sind fertig.
Aman

Antworten:


47

Diese JavaCV-Implementierung funktioniert einwandfrei.

Code:

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

Es gibt auch Post-On-Konfiguration für JavaCV

Sie können die Codes ändern und die Bilder in regelmäßigen Abständen speichern und den Rest der gewünschten Verarbeitung durchführen.


4
+1 Du rockst! Ich suchte nach einer guten Open Source und unterstützten Alternative zu JMF für Webcam-Captures unter Windows und Linux. Das funktioniert wie ein Zauber! Vielen Dank :)
maple_shaft

2
Funktioniert bei mir nicht, es heißt Ausnahme im Thread "main" java.lang.UnsatisfiedLinkError: C: \ Benutzer \ steve \ AppData \ Local \ Temp \ javacpp213892357885346 \ jniopencv_core.dll: Abhängige Bibliotheken können nicht gefunden werden
Stepan Yakovenko

Dies wird funktionieren, aber die Videoqualität ist nicht so gut, wie sie sein sollte. Siehe meine Antwort für eine bessere Videoausgabequalität.
Syb0rg

Vielen Dank für den Vorschlag. Ich bin interessiert, wie man es unter Windows einstellt? Benötige ich den mit 3 GB extrahierten Reißverschluss? Ansonsten funktioniert mein Programm mit JavaCV unter Linux einwandfrei.
Ilian Zapryanov

@StepanYakovenko Sie müssen OpenCV installiert haben.
Matthieu

33

Vor einiger Zeit habe ich eine generische Java-Bibliothek erstellt, mit der Bilder mit einer PC-Webcam aufgenommen werden können. Die API ist sehr einfach, nicht überfunktioniert, kann eigenständig arbeiten, unterstützt aber auch zusätzliche Webcam-Treiber wie OpenIMAJ, JMF, FMJ, LTI-CIVIL usw. und einige IP-Kameras.

Der Link zum Projekt lautet https://github.com/sarxos/webcam-capture

Beispielcode (Bild aufnehmen und in test.jpg speichern):

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

Es ist auch im Maven Central Repository oder als separate ZIP-Datei verfügbar, die alle erforderlichen Abhängigkeiten und JARs von Drittanbietern enthält.


1
Zur Erleichterung des Einstiegs ist dies einen Blick wert. Der Code hat
super

@ Bartosz Firyn: Hallo, ich arbeite mit Ihrer API. Super Arbeit Mann! Aber jetzt möchte ich wissen, ob das Zoomen in der Kamera unterstützt wird oder nicht? Wie zoome ich eine Kamera mit dieser API?
Java Man

@ JavaMan, es gibt keine native Unterstützung für das Zoomen.
Bartosz Firyn

2
@JavaMan können Sie entweder auf dem Bedienfeld zeichnen, auf dem die Ansicht von der Kamera (WebcamPanel) angezeigt wird, indem Sie Ihre benutzerdefinierte Painter-Instanz festlegen, oder direkt auf dem Bild, das von der Kamera stammt, indem Sie die WebcamImageTransformer-Funktion verwenden. Für weitere Informationen öffnen Sie bitte das Ticket auf der Webcam Capture-Projektseite von Github, da ich dies hier im Stapelüberlauf nicht ausführlich erläutern möchte (zu viel zum Schreiben und zu wenige Zeichen zum Verwenden in Kommentaren). Das Projekt kann hier gefunden werden github.com/sarxos/webcam-capture
Bartosz Firyn

1
@Elyas Hadizadeh, bei Problemen können Sie unter github.com/sarxos/webcam-capture jederzeit ein neues Issue-Ticket erstellen. Dort finden Sie auch Dokumentation und Beispiele. Bitte beachten Sie auch, dass dies ein Rahmen für Personen ist, die mit Java eher vertraut sind. Wenn Sie Java-Neuling sind, gibt es auch Leute, die bereit sind zu helfen, aber Sie müssen die Grundlagen selbst lernen.
Bartosz Firyn


5

Hier ist eine ähnliche Frage mit einigen - aber nicht akzeptierten - Antworten. Einer von ihnen erwähnt FMJ als Java-Alternative zu JMF.


5

Diese Art von geht von gt_ebuddys Antwort mit JavaCV aus, aber meine Videoausgabe hat eine viel höhere Qualität als seine Antwort. Ich habe auch einige andere zufällige Verbesserungen hinzugefügt (z. B. das Programm schließen, wenn ESCund CTRL+Cgedrückt werden, und sicherstellen, dass die vom Programm verwendeten Ressourcen ordnungsgemäß geschlossen werden).

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

Ich habe JMF für eine Videokonferenzanwendung verwendet und es funktionierte gut auf zwei Laptops: einem mit integrierter Webcam und einem mit einer alten USB-Webcam. Es erfordert, dass JMF vorher installiert und konfiguriert wird, aber wenn Sie fertig sind, können Sie ziemlich einfach über Java-Code auf die Hardware zugreifen.


3

Sie können Marvin Framework ausprobieren . Es bietet eine Schnittstelle für die Arbeit mit Kameras. Darüber hinaus bietet es eine Reihe von Echtzeit-Videoverarbeitungsfunktionen wie Objektverfolgung und Filterung.

Schau mal!

Demo zur Echtzeit-Videoverarbeitung:
http://www.youtube.com/watch?v=D5mBt0kRYvk

Sie können die folgende Quelle verwenden. Speichern Sie einfach alle 5 Sekunden einen Frame mit MarvinImageIO.saveImage () .

Webcam-Video-Demo:

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

Für diejenigen, die nur ein einziges Bild machen möchten:

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

Verwenden des Players mit Swing

Der Player kann auch problemlos in einer Swing-Anwendung verwendet werden. Der folgende Code erstellt ein Swing-basiertes TV-Aufnahmeprogramm, bei dem die Videoausgabe im gesamten Fenster angezeigt wird:

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

Ich habe die Webcam Capture-API verwendet ... Sie können sie von dieser http://webcam-capture.sarxos.pl/ herunterladen.

        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"));

                }
            }
        }

Sie sollten eine Erklärung zusammen mit dem Code geben
fen1x

1
Vielen Dank. es ist leicht und stattdessen funktioniert javacv für mich.
Lucke

1

Java greift normalerweise nicht gerne auf Hardware zu, daher benötigen Sie ein Treiberprogramm, wie goldenmean sagte. Ich habe dies auf meinem Laptop getan, indem ich ein Befehlszeilenprogramm gefunden habe, das ein Bild aufnimmt. Dann ist es das gleiche wie goldenmean erklärt; Sie führen das Befehlszeilenprogramm von Ihrem Java-Programm in der Routine takepicture () aus, und der Rest Ihres Codes wird genauso ausgeführt.

Mit Ausnahme des Teils zum Lesen von Pixelwerten in ein Array ist es möglicherweise besser, die Datei in BMP zu speichern, das bereits fast dieses Format aufweist, und dann die Standard-Java-Bildbibliotheken zu verwenden.

Die Verwendung eines Befehlszeilenprogramms fügt Ihrem Programm eine Abhängigkeit hinzu und macht es weniger portabel. Aber war die Webcam auch richtig?


1

Empfehlen Sie die Verwendung von FMJ für eine multimediale Java-App.


0

Ich glaube, dass die Web-Cam-Anwendungssoftware, die mit der Web-Cam geliefert wird, oder Ihre native Windows-Webcam-Software nach dem Einschalten der Web-Cam in einem Batch-Skript (Windows / Dos-Skript) ausgeführt werden kann (dh wenn sie eine externe Stromversorgung benötigt) liefern). Im Bacth-Skript können Sie eine angemessene Verzögerung für die Erfassung nach einem bestimmten Zeitraum hinzufügen. Führen Sie den Erfassungsbefehl weiterhin in einer Schleife aus.

Ich denke das sollte möglich sein

-ANZEIGE


0

Es gibt eine ziemlich schöne Oberfläche dafür in der Verarbeitung , die eine Art Pidgin Java ist, das für Grafiken entwickelt wurde. Es wird in einigen Bilderkennungsarbeiten wie diesem Link verwendet.

Je nachdem, was Sie davon benötigen, können Sie möglicherweise die dort in Java verwendete Videobibliothek laden, oder wenn Sie nur damit herumspielen, können Sie möglicherweise die Verarbeitung selbst verwenden.


0

FMJ kann dies ebenso wie die von ihm verwendete unterstützende Bibliothek LTI-CIVIL. Beide sind auf Quellschmiede.


0

Versuchen Sie es mit JMyron. So verwenden Sie Webcam mit Java . Ich denke, JMyron ist der einfachste Weg, mit Java auf eine Webcam zuzugreifen. Ich habe versucht, es mit einem 64-Bit-Prozessor zu verwenden, aber es gab mir einen Fehler. Auf einem 32-Bit-Prozessor funktionierte es jedoch einwandfrei.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.