Каков наилучший способ захвата изображений с живого видеоустройства для использования приложением на основе Java?
Я смотрю на проблему обработки изображений для полу-реального обнаружения определенных сценариев. Моя цель - сделать так, чтобы живое видео получалось как кадры Motion JPEG в моем Java -коде.
Я знаком с Java Media Framework и, к сожалению, думаю, мы можем считать это фактически мертвым API. Я также знаком с блоками Axis и, хотя мне действительно нравится их решение, я был бы признателен за любые критические отзывы о моих конкретных точках интереса.
Вот как я определяю "лучший" для целей этого обсуждения:
- Задержка - если я управляю камерой с помощью этого видеопотока, я бы хотел, чтобы задержка в обоих направлениях составляла менее 100 миллисекунд, если это возможно. Это измеряется как время между моим входом управления и временем, когда я вижу видимые изменения. РЕДАКТИРУЙТЕ спустя некоторое время: еще одна вещь, которую нужно иметь в виду, - то, что управление камерой, вероятно, будет комбинацией ручного и автоматического (триггеры событий). Мы должны сразу увидеть эти фотографии, даже если высококачественный канал архивируется отдельно.
- Стоимость - бесплатно / с открытым исходным кодом лучше, чем не бесплатно.
- Настраиваемые параметры кодека - мне нужно иметь возможность настроить кодек для определенных ситуаций. Иногда высокоскоростной поток с низким разрешением на самом деле легче обрабатывать.
- "Интеграция" с Java - насколько сложно подключить это решение к моему коду? Я отправляю пакеты через сокет? Переходя по URL? Установка комбинаций Direct3D / JNI?
- Windows / Linux / оба? - Я бы предпочел решение, не зависящее от операционной системы, потому что мне приходится предлагать несколько версий ОС, но может быть решение, оптимальное для одного, а не для другого.
ПРИМЕЧАНИЕ. Мне известны другие кодеки для захвата изображений и видео, и этот вопрос не является предметом обсуждения. Меня не интересуют потоковые API (например, MPEG4) из-за потери точности кадра. Однако, если есть решение моего вопроса, которое обеспечивает другой поток данных с точностью до кадра, пожалуйста, включите.
В продолжение этого вопроса: на данный момент, я настоятельно склонен покупать устройства, такие как видеокодеры Axis, а не пытаться захватить видео в программном обеспечении или на ПК напрямую. Однако, если у кого-то есть альтернативы, я бы хотел их услышать.
6 ответов
Эта реализация JavaCV работает отлично.
КОД:
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import static com.googlecode.javacv.cpp.opencv_highgui.*;
public class CaptureImage {
private static void captureFrame() {
// 0-default camera, 1 - next...so on
final OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
try {
grabber.start();
IplImage img = grabber.grab();
if (img != null) {
cvSaveImage("capture.jpg", img);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
captureFrame();
}
}
Также есть запись о просмотре живого видео с камеры. И настройка для JavaCV:
Я думаю, что это будет соответствовать вашим требованиям.
FMJ может определенно захватывать видео и превращать его в кадры MJPEG.
Что касается тупости JMF, знаете ли вы о внедрении FMJ? Я не знаю, считается ли это "лучшим" решением, но, вероятно, стоит добавить к обсуждению.
Ниже показана очень простая реализация с использованием Marvin Framework. С помощью Marvin вы можете легко добавить обработку видео в реальном времени.
import javax.swing.JFrame;
import marvin.gui.MarvinImagePanel;
import marvin.image.MarvinImage;
import marvin.video.MarvinJavaCVAdapter;
import marvin.video.MarvinVideoInterface;
public class SimpleVideoTest extends JFrame implements Runnable{
private MarvinVideoInterface videoAdapter;
private MarvinImage image;
private MarvinImagePanel videoPanel;
public SimpleVideoTest(){
super("Simple Video Test");
// Create the VideoAdapter and connect to the camera
videoAdapter = new MarvinJavaCVAdapter();
videoAdapter.connect(0);
// Create VideoPanel
videoPanel = new MarvinImagePanel();
add(videoPanel);
// Start the thread for requesting the video frames
new Thread(this).start();
setSize(800,600);
setVisible(true);
}
public static void main(String[] args) {
SimpleVideoTest t = new SimpleVideoTest();
t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void run() {
while(true){
// Request a video frame and set into the VideoPanel
image = videoAdapter.getFrame();
videoPanel.setImage(image);
}
}
}
Другой пример применения нескольких алгоритмов для обработки видео в реальном времени.
Это моя реализация JavaCV с видеовыходом с высоким разрешением и без заметного падения частоты кадров по сравнению с другими решениями (только когда перефокусируется моя веб-камера, я замечаю небольшое падение, хотя и на мгновение).
import java.awt.image.BufferedImage;
import java.io.File;
import javax.swing.JFrame;
import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.OpenCVFrameRecorder;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
public class Webcam implements Runnable {
IplImage image;
static CanvasFrame frame = new CanvasFrame("Web Cam");
public static boolean running = false;
public Webcam()
{
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void run()
{
try
{
grabber.setImageWidth(800);
grabber.setImageHeight(600);
grabber.start();
while (running)
{
IplImage cvimg = grabber.grab();
BufferedImage image;
if (cvimg != null)
{
// opencv_core.cvFlip(cvimg, cvimg, 1); // mirror
// show image on window
image = cvimg.getBufferedImage();
frame.showImage(image);
}
}
grabber.stop();
frame.dispose();
} catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String... args)
{
Webcam webcam = new Webcam();
webcam.start();
}
public void start()
{
new Thread(this).start();
running = true;
}
public void stop()
{
running = false;
}
}
Вы когда-нибудь смотрели на http://processing.org/? По сути, это упрощенная прикладная среда для разработки "художественных" приложений и физических вычислительных платформ, но она основана на Java, и вы можете перейти к "настоящей" Java под ней.
Причина, по которой это пришло в голову, состоит в том, что есть несколько библиотек видео для Processing, которые в основном являются компонентами Java (по крайней мере, я так думаю - на сайте есть вся техническая информация, которая может вам понадобиться). В Eclipse IDE есть руководство по использованию библиотек обработки и инструментов. Есть также многочисленные примеры захвата и обработки видео.
Даже если вы не можете использовать библиотеки напрямую, Processing - отличный язык / среда для разработки алгоритмов. Там есть несколько отличных примеров захвата изображения и видео и обработки в реальном времени.