Chụp ảnh từ webcam trong java?


85

Làm cách nào để tôi có thể liên tục chụp ảnh từ webcam?

Tôi muốn thử nghiệm với nhận dạng đối tượng (có thể bằng cách sử dụng khuôn khổ phương tiện java).

Tôi đã nghĩ đến việc tạo hai chuỗi

một chủ đề:

  • Nút 1: chụp ảnh trực tiếp
  • Nút 2: lưu hình ảnh thành "1.jpg"
  • Nút 3: đợi 5 giây
  • Nút 4: lặp lại ...

chủ đề khác:

  • Nút 1: đợi cho đến khi hình ảnh được chụp
  • Nút 2: sử dụng "1.jpg" lấy màu từ mọi pixle
  • Nút 3: lưu dữ liệu trong mảng
  • Nút 4: lặp lại ...

2
Đây là câu trả lời của bạn - Chương trình Java Swing để chụp ảnh từ hướng dẫn webcam Sửa đổi một chút và bạn đã hoàn tất ..
Aman

Câu trả lời:


49

Việc triển khai JavaCV này hoạt động tốt.

Mã:

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

Ngoài ra còn có bài đăng về cấu hình cho JavaCV

Bạn có thể sửa đổi mã và có thể lưu hình ảnh trong khoảng thời gian đều đặn và thực hiện phần còn lại của quá trình xử lý bạn muốn.


4
+1 Bạn thật tuyệt! Tôi đang tìm kiếm một mã nguồn mở tốt và được hỗ trợ thay thế cho JMF để chụp webcam trong cả Windows và Linux. Công việc này như một cái duyên vậy! Cảm ơn bạn :)
maple_shaft

2
Không hoạt động với tôi, nó thông báo Ngoại lệ trong chuỗi "main" java.lang.UnsatisfiedLinkError: C: \ Users \ steve \ AppData \ Local \ Temp \ javacpp213892357885346 \ jniopencv_core.dll: Không thể tìm thấy các thư viện phụ thuộc
Stepan Yakovenko

Điều này sẽ hoạt động, nhưng chất lượng video không tốt như mong muốn. Xem câu trả lời của tôi để có chất lượng đầu ra video tốt hơn.
syb0rg

Cảm ơn vì đã góp ý. Tôi quan tâm làm thế nào để thiết lập nó trên Windows? Tôi có cần zip giải nén 3Gb không? Nếu không, chương trình của tôi, sử dụng JavaCV trên Linux hoạt động tốt.
Ilian Zapryanov 13/12/13

@StepanYakovenko bạn cần cài đặt OpenCV.
Matthieu

33

Cách đây một thời gian, tôi đã tạo thư viện Java chung có thể được sử dụng để chụp ảnh bằng webcam PC. API rất đơn giản, không bị quá tải, có thể hoạt động độc lập, nhưng cũng hỗ trợ các trình điều khiển webcam bổ sung như OpenIMAJ, JMF, FMJ, LTI-CIVIL, v.v. và một số camera IP.

Liên kết đến dự án là https://github.com/sarxos/webcam-capture

Mã mẫu (chụp ảnh và lưu trong test.jpg):

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

Nó cũng có sẵn trong Maven Central Repository hoặc dưới dạng ZIP riêng bao gồm tất cả các phụ thuộc bắt buộc và JAR của bên thứ ba.


1
Để dễ dàng bắt đầu, điều này rất đáng xem. Mã này làm việc rất lớn đối với tôi, hy vọng bạn cũng :)
mrswadge

@Bartosz Firyn: xin chào, tôi đang làm việc với API của bạn. người làm việc tuyệt vời! nhưng bây giờ tôi muốn biết rằng phóng to máy ảnh có được hỗ trợ hay không? làm thế nào để thu phóng máy ảnh bằng cách sử dụng API này?
Java Man

@JavaMan, không có hỗ trợ phóng to thu nhỏ.
Bartosz Firyn

2
@JavaMan, bạn có thể vẽ trên bảng hiển thị chế độ xem từ máy ảnh (WebcamPanel) bằng cách đặt phiên bản Họa sĩ tùy chỉnh của bạn hoặc trực tiếp trên hình ảnh đến từ máy ảnh bằng cách sử dụng tính năng WebcamImageTransformer. Để biết thêm chi tiết, vui lòng mở vé trên trang dự án Webcam Capture trên Github vì tôi không muốn giải thích chi tiết điều này ở đây trên Stack Overflow (quá nhiều để viết và quá ít ký tự để sử dụng trong nhận xét). Dự án có thể được tìm thấy tại đây github.com/sarxos/webcam-capture
Bartosz Firyn

1
@Elyas Hadizadeh, trong trường hợp có vấn đề, bạn luôn có thể tạo phiếu phát hành mới tại github.com/sarxos/webcam-capture , nơi bạn cũng có thể tìm tài liệu và ví dụ. Cũng xin lưu ý rằng đây là khuôn khổ cho những người khá quen thuộc với Java. Trong trường hợp bạn là người mới Java thì cũng có người sẵn sàng giúp đỡ, nhưng bạn phải tự học những kiến ​​thức cơ bản.
Bartosz Firyn


5

Đây là một câu hỏi tương tự với một số câu trả lời - chưa được chấp nhận -. Một trong số họ đề cập đến FMJ như một giải pháp thay thế java cho JMF.


5

Kiểu này không giống với câu trả lời của gt_ebuddy bằng cách sử dụng JavaCV, nhưng đầu ra video của tôi có chất lượng cao hơn nhiều so với câu trả lời của anh ấy. Tôi cũng đã thêm một số cải tiến ngẫu nhiên khác (chẳng hạn như đóng chương trình khi ESCCTRL+Cđược nhấn và đảm bảo đóng các tài nguyên mà chương trình sử dụng đúng cách).

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

Tôi đã sử dụng JMF trên một ứng dụng hội nghị truyền hình và nó hoạt động tốt trên hai máy tính xách tay: một máy có webcam tích hợp và một máy khác có webcam USB cũ. Nó yêu cầu JMF được cài đặt và cấu hình trước đó, nhưng sau khi hoàn tất, bạn có thể truy cập phần cứng thông qua mã Java khá dễ dàng.


3

Bạn có thể thử Marvin Framework . Nó cung cấp một giao diện để làm việc với máy ảnh. Hơn nữa, nó cũng cung cấp một tập hợp các tính năng xử lý video thời gian thực, như theo dõi và lọc đối tượng.

Hãy xem!

Bản trình diễn xử lý video theo thời gian thực:
http://www.youtube.com/watch?v=D5mBt0kRYvk

Bạn có thể sử dụng nguồn bên dưới. Chỉ cần lưu một khung hình bằng MarvinImageIO.saveImage () cứ sau 5 giây.

Bản demo video 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);
    }
}

Đối với những người chỉ muốn chụp một bức ảnh:

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

Sử dụng máy nghe nhạc bằng Swing

Người chơi cũng có thể dễ dàng sử dụng trong ứng dụng Swing. Đoạn mã sau tạo chương trình quay TV dựa trên Swing với đầu ra video được hiển thị trong toàn bộ cửa sổ:

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

Tôi đã sử dụng API Webcam Capture ... bạn có thể tải xuống từ http://webcam-capture.sarxos.pl/ này

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

                }
            }
        }

Bạn nên cung cấp một số giải thích cùng với mã
fen1x 10/09/17

1
cảm ơn. nó nhẹ và thay vào đó javacv cái này phù hợp với tôi.
Lucke

1

Java thường không thích truy cập phần cứng, vì vậy bạn sẽ cần một chương trình điều khiển nào đó, như goldenmean đã nói. Tôi đã thực hiện việc này trên máy tính xách tay của mình bằng cách tìm một chương trình dòng lệnh chụp ảnh. Sau đó, nó giống như goldenmean đã giải thích; bạn chạy chương trình dòng lệnh từ chương trình java của mình trong quy trình takepicture () và phần còn lại của mã của bạn cũng chạy như vậy.

Ngoại trừ phần về việc đọc giá trị pixel vào một mảng, bạn có thể được phục vụ tốt hơn bằng cách lưu tệp vào BMP, gần như định dạng đó rồi, sau đó sử dụng các thư viện hình ảnh java tiêu chuẩn trên đó.

Việc sử dụng một chương trình dòng lệnh sẽ thêm phần phụ thuộc vào chương trình của bạn và làm cho nó ít di động hơn, nhưng webcam cũng vậy, phải không?


1

Recommand bằng cách sử dụng FMJ cho ứng dụng java tương đối đa phương tiện.


0

Tôi tin rằng phần mềm ứng dụng web-cam đi kèm với web-cam hoặc phần mềm webcam Windows gốc của bạn có thể được chạy trong một tập lệnh hàng loạt (tập lệnh windows / dos) sau khi bật web cam (tức là nếu nó cần nguồn bên ngoài cung cấp). Trong tập lệnh bacth, u có thể thêm độ trễ thích hợp để nắm bắt sau một khoảng thời gian nhất định. Và tiếp tục thực hiện lệnh bắt trong vòng lặp.

Tôi đoán điều này sẽ có thể

-AD


0

Có một giao diện khá đẹp cho việc xử lý này , đây là một loại java pidgin được thiết kế cho đồ họa. Nó được sử dụng trong một số công việc nhận dạng hình ảnh, chẳng hạn như liên kết đó.

Tùy thuộc vào những gì bạn cần từ nó, bạn có thể tải thư viện video được sử dụng ở đó trong java hoặc nếu bạn chỉ chơi với nó, bạn có thể có được bằng cách sử dụng chính quá trình xử lý.


0

FMJ có thể làm điều này, cũng như thư viện hỗ trợ mà nó sử dụng, LTI-CIVIL. Cả hai đều trên sourceforge.


0

Hãy thử sử dụng JMyron Cách sử dụng Webcam bằng Java . Tôi nghĩ rằng sử dụng JMyron là cách dễ nhất để truy cập webcam bằng java. Tôi đã cố gắng sử dụng nó với bộ xử lý 64 bit, nhưng nó đã báo lỗi. Tuy nhiên, nó hoạt động tốt trên bộ xử lý 32-bit.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.