Захоплення зображення з веб-камери в Java?


85

Як я можу постійно робити знімки з веб-камери?

Я хочу поекспериментувати з розпізнаванням об’єктів (можливо, використовуючи java media framework).

Я думав створити дві нитки

одна нитка:

  • Вузол 1: захоплення зображення в реальному часі
  • Вузол 2: збережіть зображення як "1.jpg"
  • Вузол 3: зачекайте 5 секунд
  • Вузол 4: повторити ...

інша нитка:

  • Вузол 1: зачекайте, поки зображення буде захоплено
  • Вузол 2: за допомогою "1.jpg" отримуйте кольори з кожної пікселі
  • Вузол 3: збереження даних у масивах
  • Вузол 4: повторити ...

2
Ось ваша відповідь - Програма Java Swing для захоплення зображень із підручника веб-камери Трохи модифікуйте її, і все готово.
Аман,

Відповіді:


49

Ця реалізація JavaCV чудово працює.

Код:

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

Також є повідомлення про конфігурацію для JavaCV

Ви можете змінювати коди і мати можливість регулярно зберігати зображення та виконувати решту обробки, яку ви хочете.


4
+1 Ви рок! Я шукав хорошого відкритого коду та підтримувану альтернативу JMF для захоплення веб-камери як у Windows, так і в Linux. Це працює як шарм! Дякую :)
maple_shaft

2
Чи не працює для мене, це говорить Exception в потоці "головний" java.lang.UnsatisfiedLinkError: C: \ Users \ Стів \ AppData \ Local \ Temp \ javacpp213892357885346 \ jniopencv_core.dll: Неможливо знайти залежні бібліотеки
Степан Яковенко

Це спрацює, але якість відео не настільки хороша, як повинна бути. Дивіться мою відповідь для кращої якості виводу відео.
syb0rg

Дякую за пропозицію. Мене цікавить, як встановити його на Windows? Мені потрібен 3Gb витягнутий zip? В іншому випадку моя програма, використовуючи JavaCV на Linux, працює нормально.
Іліан Запрянов

@StepanYakovenko вам потрібно встановити OpenCV.
Матьє

33

Деякий час тому я створив загальну бібліотеку Java, яку можна використовувати для фотографування за допомогою веб-камери на ПК. API дуже простий, не надто вдалий, може працювати автономно, але також підтримує додаткові драйвери веб-камери, такі як OpenIMAJ, JMF, FMJ, LTI-CIVIL тощо, а також деякі IP-камери.

Посилання на проект - https://github.com/sarxos/webcam-capture

Приклад коду (сфотографуйте та збережіть у test.jpg):

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

Він також доступний у Центральному сховищі Maven або як окремий ZIP, який включає всі необхідні залежності та сторонні JAR-файли.


1
Для зручності початку це варто подивитися. Код для мене чудово працював, сподіваюся, ви теж :)
mrswadge

@Bartosz Firyn: привіт, я працюю з вашим API. чудова робота! але зараз я хочу знати, якщо масштабування камери підтримується чи ні? як збільшити камеру за допомогою цього API?
Java Man

@JavaMan, вбудованої підтримки масштабування немає.
Bartosz Firyn

2
@JavaMan, ви можете малювати або на панелі, що відображає вигляд із камери (WebcamPanel), встановивши власний екземпляр Painter, або безпосередньо на зображенні, яке надходить із камери, за допомогою функції WebcamImageTransformer. Щоб отримати докладнішу інформацію, відкрийте квиток на сторінці проекту Webcam Capture на Github, оскільки я не хочу детально пояснювати це тут, у Stack Overflow (занадто багато для написання та занадто мало символів для використання в коментарях). Проект можна знайти тут github.com/sarxos/webcam-capture
Bartosz Firyn

1
@Elyas Hadizadeh, у разі виникнення проблем ви завжди можете створити новий квиток на github.com/sarxos/webcam-capture, де ви також можете знайти документацію та приклади. Будь ласка, майте на увазі, що це рамка для людей, які досить знайомі з Java. Якщо ви новачок Java, є також бажаючі допомогти, але вам доведеться вивчити основи самостійно.
Bartosz Firyn


5

Ось подібне запитання з деякими - поки не прийнятими - відповідями. Один з них згадує FMJ як Java-альтернативу JMF.


5

Цей випадок відповідає відповіді gt_ebuddy за допомогою JavaCV, але мій вихід відео набагато вищий, ніж його відповідь. Я також додав деякі інші випадкові поліпшення (наприклад, закриття програми при ESCі CTRL+Cпресують, і переконавшись , що закрити ресурси програма використовує належним чином).

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

Я використовував JMF у додатку для відеоконференцій, і він добре працював на двох ноутбуках: один із вбудованою веб-камерою та інший зі старою веб-камерою USB. Це вимагає попереднього встановлення та налаштування JMF, але як тільки ви закінчите, ви зможете досить легко отримати доступ до обладнання через код Java.


3

Ви можете спробувати Marvin Framework . Він надає інтерфейс для роботи з камерами. Крім того, він також надає набір функцій обробки відео в режимі реального часу, таких як відстеження та фільтрація об'єктів.

Поглянь!

Демо-версія обробки відео в режимі реального часу:
http://www.youtube.com/watch?v=D5mBt0kRYvk

Ви можете використовувати джерело нижче. Просто збережіть кадр за допомогою MarvinImageIO.saveImage () кожні 5 секунд.

Демонстрація відео з веб-камери:

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

Для тих, хто просто хоче зробити єдиний знімок:

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

Використання програвача з гойдалками

Програвач можна легко використовувати і в додатку Swing. Наступний код створює програму зйомки телевізора на основі Swing із відеовиходом, що відображається у всьому вікні:

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

Я використовував веб-камеру Capture API ... u можна завантажити з цього 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"));

                }
            }
        }

Ви повинні надати деякі пояснення разом із кодом
fen1x

1
Дякую. це світло, і натомість javacv цей працює для мене.
Lucke

1

Java зазвичай не любить отримувати доступ до апаратного забезпечення, тому вам знадобиться якась програма-драйвер, як сказав goldenmean. Я зробив це на своєму ноутбуці, знайшовши програму командного рядка, яка знімає зображення. Тоді це те саме, що пояснили goldenmean; ви запускаєте програму командного рядка з вашої програми Java за процедурою takepicture (), а решта коду виконує те саме.

За винятком частини про зчитування значень пікселів у масиві, вам може бути краще, збереживши файл у BMP, який уже майже такий формат, а потім використовуючи на ньому стандартні бібліотеки зображень Java.

Використання програми командного рядка додає залежність до вашої програми і робить її менш портативною, але веб-камера так само, правда?


1

Рекомендувати використовувати FMJ для мультимедійних програм відносно Java.


0

Я вважаю, що програмне забезпечення веб-камери, яке постачається разом із веб-камерою, або ви, власне програмне забезпечення веб-камери Windows, можна запускати в пакетному сценарії (скрипт windows / dos) після увімкнення веб-камери (тобто, якщо воно потребує зовнішнього живлення постачання). У сценарії bacth u можна додати відповідну затримку для зйомки через певний проміжок часу. І продовжуйте виконувати команду захоплення в циклі.

Я думаю, це повинно бути можливим

-АД


0

Існує досить приємний інтерфейс для цього в обробці , який є свого роду Pidgin Java, призначений для графіки. Він використовується в деяких роботах з розпізнавання зображень, таких як посилання.

Залежно від того, що вам потрібно з цього, ви можете завантажити відеотеку, яка використовується там у Java, або якщо ви просто граєтесь з нею, можливо, зможете отримати, використовуючи саму обробку.


0

FMJ може це зробити, як і допоміжна бібліотека, яку вона використовує, LTI-CIVIL. Обидва знаходяться на sourceforge.


0

Спробуйте скористатися JMyron Як користуватися веб- камерою за допомогою Java . Я думаю, що використання JMyron - це найпростіший спосіб отримати доступ до веб-камери за допомогою Java. Я намагався використовувати його з 64-розрядним процесором, але це дало мені помилку. Однак він чудово працював на 32-розрядному процесорі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.