Захват изображения с веб-камеры в 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 in thread "main" java.lang.UnsatisfiedLinkError: C: \ Users \ steve \ AppData \ Local \ Temp \ javacpp213892357885346 \ jniopencv_core.dll: Не удается найти зависимые библиотеки
Степан Яковенко

Это будет работать, но качество видео не такое хорошее, как должно быть. См. Мой ответ по поводу лучшего качества вывода видео.
syb0rg

Спасибо за предложение. Интересно, как на винде установить? Нужен ли мне извлеченный zip-файл размером 3 Гб? В противном случае моя программа, использующая JavaCV в Linux, работает нормально.
Илиан Запрянов

@StepanYakovenko вам нужно установить OpenCV.
Matthieu

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, встроенной поддержки масштабирования нет.
Бартош Фирин 01

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

1
@Elyas Hadizadeh, в случае возникновения проблем вы всегда можете создать новый запрос на выпуск на github.com/sarxos/webcam-capture, где вы также можете найти документацию и примеры. Также имейте в виду, что это фреймворк для людей, хорошо знакомых с Java. Если вы новичок в Java, найдутся люди, готовые помочь, но вы должны изучить основы самостоятельно.
Бартош Фирин


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

Player также можно легко использовать в приложении 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

Я использовал API захвата веб-камеры ... вы можете скачать с этого 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 вы можете добавить соответствующую задержку для захвата через определенный период времени. И продолжайте выполнять команду захвата в цикле.

Я думаю это должно быть возможно

-ОБЪЯВЛЕНИЕ


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.