Захват изображения с веб-камеры в Java?
Как я могу непрерывно захватывать изображения с веб-камеры?
Я хочу поэкспериментировать с распознаванием объектов (возможно, используя Java Media Framework).
Я думал о создании двух потоков
одна нить:
- Узел 1: захват живого изображения
- Узел 2: сохранить изображение как "1.jpg"
- Узел 3: подождите 5 секунд
- Узел 4: повторить...
другая тема:
- Узел 1: дождитесь захвата изображения
- Узел 2: с помощью "1.jpg" получаем цвета из каждого пикселя
- Узел 3: сохранить данные в массивах
- Узел 4: повторить...
16 ответов
Эта реализация JavaCV работает отлично.
Код:
import org.bytedeco.javacv.*;
import static org.bytedeco.javacpp.opencv_core.IplImage;
import static org.bytedeco.javacpp.opencv_core.cvFlip;
import static org.bytedeco.javacpp.opencv_imgcodecs.cvSaveImage;
/**
* Created by gtiwari on 1/3/2017.
*/
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() {
FrameGrabber grabber = new VideoInputFrameGrabber(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((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
Вы можете изменить коды и иметь возможность сохранять изображения через регулярные промежутки времени и делать остальную часть обработки, которую вы хотите.
Некоторое время назад я создал универсальную библиотеку 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-файлы.
JMyron очень прост в использовании. http://webcamxtra.sourceforge.net/
myron = new JMyron();
myron.start(imgw, imgh);
myron.update();
int[] img = myron.image();
Этот вид отклоняется от ответа 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;
}
}
Вы также можете попробовать библиотеку Java Webcam SDK. Демо-апплет SDK доступен по ссылке.
Вы можете попробовать 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();
}
}
}
Я использовал API веб-камеры Capture... вы можете скачать с этого 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"));
}
}
}
Я использовал JMF в приложении для видеоконференций, и он хорошо работал на двух ноутбуках: один со встроенной веб-камерой, а другой со старой веб-камерой USB. Это требует, чтобы JMF был установлен и настроен заранее, но как только вы закончите, вы можете получить доступ к оборудованию через код Java довольно легко.
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();
}
}
Java обычно не любит доступ к аппаратному обеспечению, поэтому вам понадобится какая-то программа-драйвер, как сказал goldenmean. Я сделал это на своем ноутбуке, найдя программу командной строки, которая делает снимок. Тогда это то же самое, что объяснил Goldenmean; вы запускаете программу командной строки из вашей java-программы в процедуре takepicture(), а остальная часть вашего кода выполняется так же.
За исключением части о считывании значений пикселей в массив, вам может быть лучше сохранить файл в BMP, который уже почти соответствует этому формату, а затем использовать стандартные библиотеки изображений Java на нем.
Использование программы командной строки добавляет зависимость к вашей программе и делает ее менее переносимой, но так ли была веб-камера, верно?
Для обработки есть довольно приятный интерфейс, который является своего рода pidgin java, разработанным для графики. Он используется в некоторых работах по распознаванию изображений, таких как эта ссылка.
В зависимости от того, что вам нужно, вы можете загрузить библиотеку видео, которая используется там в java, или, если вы просто играете с ней, вы можете получить, используя саму обработку.
Я полагаю, что прикладное программное обеспечение веб-камеры, которое поставляется вместе с веб-камерой, или ваше собственное программное обеспечение веб-камеры Windows, может быть запущено в пакетном сценарии (сценарии windows / dos) после включения веб-камеры (т. Е. Если требуется внешнее питание). поставка). В сценарии bacth вы можете добавить соответствующую задержку для захвата после определенного периода времени. И продолжайте выполнять команду захвата в цикле.
Я думаю, это должно быть возможно
-ОБЪЯВЛЕНИЕ
Это может сделать FMJ, а также вспомогательная библиотека, которую он использует, LTI-CIVIL. Оба находятся на Sourceforge.
Рекомендуем использовать FMJ для мультимедийного Java-приложения.
Попробуйте использовать JMyron Как использовать веб- камеру с помощью Java. Я думаю, что использование JMyron - это самый простой способ получить доступ к веб-камере с помощью Java. Я пытался использовать его с 64-разрядным процессором, но он выдал ошибку. Хотя на 32-битном процессоре все работало нормально.