samsung - ¿Cuál es el mejor método para capturar imágenes de un dispositivo de video en vivo para que las use una aplicación basada en Java?
programa para capturar fotos de un video (6)
Estoy investigando un problema de procesamiento de imágenes para la detección en tiempo real de ciertos escenarios. Mi objetivo es que el video en vivo llegue como marcos Motion JPEG en mi código Java de alguna manera .
Estoy familiarizado con Java Media Framework y, lamentablemente, creo que podemos considerar que es una API efectivamente eliminada. También estoy familiarizado con las cajas de Axis y, aunque realmente me gusta su solución, agradecería cualquier comentario crítico sobre mis puntos de interés específicos.
Así es como defino "lo mejor" para el propósito de esta discusión:
- Latencia: si estoy controlando la cámara con este flujo de video, me gustaría mantener mi latencia de ida y vuelta en menos de 100 milisegundos si es posible. Eso se mide como el tiempo entre mi entrada de control y el momento en que veo el cambio visible. EDITAR algo más tarde: otra cosa a tener en cuenta es que el control de la cámara probablemente sea una combinación de manual y automático (activadores de eventos). Necesitamos ver esas imágenes de inmediato, incluso si el feed de alta calidad está archivado por separado.
- La fuente gratuita / abierta es mejor que no gratuita.
- Parámetros de códec ajustables: necesito poder sintonizar el códec para ciertas situaciones. Algunas veces, una transmisión de alta velocidad y baja resolución es realmente más fácil de procesar.
- "Integración" con Java: ¿cuán problemático es enganchar esta solución a mi código? ¿Estoy enviando paquetes por un socket? Golpear URLs? ¿Instalando combinaciones de Direct3D / JNI?
- Windows / Linux / ambos? - Preferiría una solución agnóstica del sistema operativo porque tengo que entregar varios tipos de SO, pero puede haber una solución que sea óptima para uno pero no para el otro.
NOTA: conozco otros códecs de captura de imágenes / video y ese no es el enfoque de esta pregunta. Específicamente, no estoy interesado en la transmisión de API (por ejemplo, MPEG4) debido a la pérdida de precisión de cuadro. Sin embargo, si hay una solución a mi pregunta que entregue otro flujo de datos con precisión de fotograma, por favor repita.
Seguimiento de esta pregunta: en este punto, estoy muy inclinado a comprar dispositivos como los codificadores de video Axis en lugar de intentar capturar el video directamente en el software o en la PC. Sin embargo, si alguien tiene alternativas, me encantaría escucharlas.
¿Alguna vez has visto Processing.org ? Básicamente es un marco simplificado de aplicaciones para el desarrollo de aplicaciones "artísticas" y plataformas de computación física, pero está basado en Java y puedes profundizar en la Java "real" que se encuentra debajo.
La razón por la que me vino a la mente es que hay varias libraries videos para procesamiento que son básicamente componentes de Java (al menos creo que lo son; el sitio tiene toda la información técnica que pueda necesitar). Hay un tutorial sobre el uso de las bibliotecas y herramientas de procesamiento en Eclipse IDE. También hay numerosos examples de captura y procesamiento de video.
Incluso si no puede usar las bibliotecas directamente, el procesamiento es un excelente lenguaje / entorno para la elaboración de algoritmos. Aquí hay varios ejemplos excelentes de captura de imágenes y video y procesamiento en tiempo real.
A continuación se muestra una implementación muy simple utilizando Marvin Framework . Usando Marvin, puedes agregar fácilmente el procesamiento de video en tiempo real.
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);
}
}
}
Otro example aplicando múltiples algoritmos para el procesamiento de video en tiempo real.
En cuanto a la muerte de JMF, ¿conoce la implementación de FMJ ? No sé si califica como la "mejor" solución, pero probablemente valga la pena agregarla a la discusión.
Esta es mi implementación de JavaCV con salida de video de alta resolución y sin una caída notable en la velocidad de fotogramas que otras soluciones (solo cuando mi cámara se vuelve a enfocar noto una ligera caída, aunque solo por un momento).
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;
}
}
Esta implementación JavaCV funciona bien.
CÓDIGO:
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();
}
}
También hay publicaciones sobre cómo ver videos en vivo desde la Cámara. Y configuración para JavaCV:
Creo que esto cumplirá con tus requisitos.
FMJ definitivamente puede capturar video y convertirlo en marcos MJPEG.