Procesamiento de Video en Tiempo Real Con Java

31 comentarios
Al fin otro post ... han pasado meses desde mi último post y hoy mientras revisada algunos apuntes de la universidad encontré un programa que hice en mis ratos libres acerca del procesamiento de video. Antes de escribir este pequeño código tenía un montón de dudas acerca del procesamiento de video. Y de eso trata este post, de dar solución a esas dudas que obviamente no son solo mías sino seguro de muchos novatos en programación.



Bueno, luego de esta pequeña introducción empezemos a hablar acerca del procesamiento de video resolviendo las dudas que yo tenía.

Mi primera duda era: ¿Qué hace diferente al procesamiento de imágenes del procesamiento de video? ... Y esta duda me surgió porque yo tenía la implementación de algunos algoritmos de procesamiento de imágenes y pensaba que quizás podría aplicarlos en alguna cosa interesante. La respuesta a esta pregunta es que es casi lo mismo, es más, me animaría a decir que el procesamiento de video no es más que el procesamiento secuencial de imágenes dentro de un intervalo de tiempo.
Y es que para lograr procesar video solo basta acceder a sus frames e ir procesando imágen por imágen al mismo tiempo que es capturado para poder dar la sensación de movimiento y que es tiempo real.

First doubt has been solved!! xD

Mi segunda duda era: ¿Y qué herramientas puedo utilizar para poder procesar el video? ... Evidentemente hay muchas, pero yo personalmente prefiero Java que son su framework JMF(Java Media Framework) (que evidentemente no es la gran cosa, así que no pidamos maravillas) nos provee la API necesaria para poder acceder a los dispositivos de captura de video y también manipular los datos de un achivo multimedia.

Tercera duda: Bien, ya instalé el Java Media Framework, ahora ¿Cómo instancio un dispositivo de captura de video? ... Bueno, como siempre digo: Un poco de líneas de código dice más que mil papers

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package view;

import java.awt.BorderLayout;
import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.Player;
import javax.media.Processor;
import javax.swing.JFrame;

/**
*
* @author Rolando
*/
public class InstanciarCamara extends JFrame {

//Atributos necesarios para acceder a una cámara web
private static Player player;
private MediaLocator localizador;
private Processor p;
private CaptureDeviceInfo dispositivo = null;
private static String source = "vfw:Microsoft WDM Image Capture (Win32):0";

public InstanciarCamara() {
setLayout(new BorderLayout());
setSize(500, 400);
setLocationRelativeTo(null);    //Centrar Ventana
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Demo Cámara Web");
player = null;
localizador = null;
dispositivo = CaptureDeviceManager.getDevice(source);
localizador = dispositivo.getLocator();
iniciarCaptura();
}

private void iniciarCaptura() {
try {
player = Manager.createRealizedPlayer(localizador);
player.start();
if (player.getVisualComponent() != null) {
add(player.getVisualComponent(), BorderLayout.CENTER);
}
} catch (Exception e) {
System.err.println(e.toString());
}
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
InstanciarCamara.setDefaultLookAndFeelDecorated(true);
InstanciarCamara camara = new InstanciarCamara();
camara.setVisible(true);
}

}


Con eso ya podemos acceder a una cámara web por ejemplo.

Cuarta duda: Bien, ya puedo acceder a un dispositivo de captura, pero ¿Cómo accedo a los frames para poder procesarlos? Y es aquí donde el java media framework otra vez, gracias a su API, nos provee unos métodos que nos ayudarán a realizar esta tarea. A ver, veamos estas palabras reflejadas en otro poco de código.

Primero necesitaremos un panel para poder cargar la imágen procesada. Este panel solo reescribirá el método paint. A continuación el código.

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

/*
* Lienzo.java
*
* Created on 14/05/2009, 02:11:36 PM
*/

package com.test;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

/**
*
* @author Rolando
*/
public class Lienzo extends javax.swing.JPanel {

private BufferedImage imagen;

/** Creates new form Lienzo */
public Lienzo() {
imagen = null;
}

public void setImage(BufferedImage imagen) {
this.imagen = imagen;
repaint();
}         

@Override
public void paint( Graphics g ) {
super.paint( g );
if( imagen != null ) {
g.drawImage(imagen, 0, 0, getWidth(), getHeight(), this);
g.setColor(Color.BLACK);
g.drawString("http://rolandopalermo.blogspot.com", 10, 20);
}
}                 

}


Y ahora para ver como se capturan los frames del video proveniente de una cámara web les dejo un pequeño proyecto de netbeans.



Photobucket


Espero les sea de utilidad y cualquier pregunta, no duden en consultarme.

31 comentarios:

  • 23 de agosto de 2010 17:21

    Exelente trabajao, te quisiera molestar que me ayudes con un cliente servidor, que el servidor capture el video y la envie a los clientes. Te agradeceria mucho.

  • 23 de agosto de 2010 20:01

    Claro amigo, lo que tienes que utilizar es Java Media Framework y el protocolo RTP Real-time Transport Protocol (Protocolo de Transporte de Tiempo real). Con eso podrás hacer lo que quieres, que supongo es un programa para videoconferencia o videovigilancia.

  • 23 de agosto de 2010 20:30

    Gracias por responder, la verdad es un proyecto de la Universidad, es un Aula Virtual y lo unico que me queda es compartir video con los alumnos, he conseguigo muchos codigos de java con JMF pero ninguno que me guie de como transmitir de cliente a servidor. Te agradeceria tu ayuda.

  • 23 de agosto de 2010 20:42

    Claro amigo, pero has buscado ejemplos sobre RTP? http://java.sys-con.com/node/45832

  • 23 de agosto de 2010 21:00

    Asi es, ya habia visitado el link que colocaste pero es para un servicio web, el proyecto lo estoy realisando en netbeans para una aplicacion de escritorio asi como lo que programaste. Lo que necesito es exactamente igual a esto http://www.youtube.com/watch?v=thvxozuYy8w&feature=related

  • 23 de agosto de 2010 21:22

    Nunca lo había hecho así pero es cuestión de crear una clase Imagen, serializarla y enviarla como cualquier objeto.

  • 23 de agosto de 2010 21:37

    Ok, voy a seguir buscando, de todas formas gracias por tu ayuda. Y que buen Blog.

  • 24 de agosto de 2010 09:10

    Uffffffff, me salvaste la vida, muchas gracias por todo, te deje un comentario en el link que adjuntaste. Muuuuuuuuuuuuuuuuchas gracias.

  • 19 de septiembre de 2010 14:27
    Anónimo :

    amigo que buena ayuda, sucede que al correr el programa en netbeans me arroja el siguiente error

    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException

    at com.blogspot.rolandopalermo.Acceder2Frames.(Acceder2Frames.java:53)

    com.blogspot.rolandopalermo.Acceder2Frames$4.run(Acceder2Frames.java:185)

    java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)

    realmente es muy importante para mi es la base de una aplicacion que necesito desarrollar te agradesco inmensamente de antemano la ayuda que me puedas brindar. junior230481@gmail.com

  • 22 de octubre de 2010 12:48
    Anónimo :

    ¿como se puede hacer para que el video se vea binarizado?
    Es que yo consigo coger una foto de la camara y binarizarla, pero no que ver un video en tiempo real.
    Muchas gracias de antemano

  • 25 de octubre de 2010 03:12

    yo tambien estaria interesado en saber el método para mostrar el video binarizado, que he estado buscando por todos lados y no encuentro nada.

  • 25 de octubre de 2010 10:35

    Buen día a todos. Se refieren a que se vea así como en el video que muestro?

  • 25 de octubre de 2010 10:54

    si, es que estoy intentando hacer un programa que calcule una serie de parametros sobre la imagen binarizada, y necesito que la imagen se muestre en tiempo real, y poder contar por ejemplo los puntos negros que salen en la imagen en cada momento.
    Pero de momento solo con que me muestres como poner la imagen binarizada creo que seria suficiente, ya lo otro lo haria con bucles for.

  • 25 de octubre de 2010 11:02

    Pues eso se logra con un timer amigo. Si tienes tu algoritmo para binarizar una imágen en java, ese mismo puedes usar dentro del evento del timer. Así cada 1 milisegundo tienes la imágen binarizada.
    Saludos.

  • 25 de octubre de 2010 11:11

    tengo un bucle do while, que me hace todo eso, pero solo me repinta la imagen cuando termina de realizar todos los bucles, y solo pinta una imagen.

  • 25 de octubre de 2010 11:15

    Es que eso no se hace con un bucle do while, sino con un timer.

  • 25 de octubre de 2010 11:23

    ok, pues ese era mi fallo, muchas gracias, voy a probar a ver si me aclaro y te cuento.

  • 25 de octubre de 2010 11:30

    Ya lo tengo funcionando, muchisimas gracias por la atención prestada y por la ayuda, y lo siento si mis preguntas has sido demasiado tontas.
    Da gusto tratar con gente como tú.

  • 3 de noviembre de 2010 23:05
    Anónimo :

    hola tengo un proble no quere correr el proyecto que descarge del procesamiento de imagenes me sale estos errores

    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at com.blogspot.rolandopalermo.Acceder2Frames.(Acceder2Frames.java:53)
    at com.blogspot.rolandopalermo.Acceder2Frames$4.run(Acceder2Frames.java:185)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

    podes ayudarme soy un novato en netbean my correo es vsblackmetal@yahoo.es porfa

  • 3 de noviembre de 2010 23:09

    Intenta esto:
    1. Usa el JMF Studio para detectar dispositivos de captura de video.
    2. Cambia "vfw:Microsoft WDM Image Capture (Win32):0" por "vfw://0"

  • 6 de diciembre de 2010 11:15
    Anónimo :

    te amo mi amorrr!!!! :$ perdona esto no tiene nada q ver con la pagina,pero queria q lo sepas y q nunca se t olvide ni un segundo vale??? t adorooo mumi!

  • 30 de diciembre de 2010 16:08

    hola,

    Excelente trabajo! quisiera saber si con JMF se puede hacer lo siguiente:

    necesito capturar video desde un dispositivo, el video (conjunto de frames) necesito poder meterlos en una matriz de n x m (resolucion de imagen), y a cada matriz (foto o frame) poder analizar el color de cada pixel.

    Se traduce a lo siguiente, imagina estoy capturando un video de cualquier cosa, si me posiciono con el cursor sobrl alguna region del video mientras lo reproduzco en tiempo real, necesito que me diga que color tiene el pixel que en el que estoy posicionado en todo instante de tiempo.

    Sería genial si me puedes ayudar con esto.

    de antemano muchas gracias

    atte César.

  • 25 de abril de 2011 09:53
    Matias :

    Hola muy bueno el blog, estoy trabajando en un proyecto y me interesaria saber si es posible capturar el video en tiempo real desde una camara digital NIKON conectada por usb a la pc...

    DESDE YA MUCHAS GRACIAS.

  • 26 de abril de 2011 11:59
    Matias :

    Muchas gracias por tu respuesta! La duda que tengo es que cargando la libreria javax.media me dice que es deprecated, hay alguna nueva que la sustituya?

    y otra duda que tengo es comoseteo para que capture el video desde la camara que esta conectada por usb, por que para una camara web comun ya lo tengo echo (para las web cam de un notebook por ejemplo), pero me complica el tema del usb...

    Desde ya muchas gracias!

  • 2 de mayo de 2011 09:51
    Matias :

    Rolando:

    Quisiera pedirte tu ayuda para que me des una pista de como capturar imagen desde una camara digital nikon p300 a la pc, puedo capturar en un programa java la imagen tomada desde una web cam, pero no desde la nikon.

    Agredeceria muchisimo tu ayuda!

  • 14 de mayo de 2011 00:55

    ayudaaaaaaaaaaaaa!!!!!
    cuando quiero cargar el video de mi webcam en un panel me genera el sigueinte error noc si sea por los thread que estoi utilizando en el chat de java
    xq kiero implementarlo para hacer un video chat alguna ayuda me serviria de antemano gracias!!!!!!
    aki esta el error que me genera
    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at ClienteChat.jmfVideo.Componente(jmfVideo.java:31)
    at ClienteChat.Clientes.jButton1ActionPerformed(Clientes.java:340)
    at ClienteChat.Clientes.access$300(Clientes.java:27)
    at ClienteChat.Clientes$5.actionPerformed(Clientes.java:200)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
    at java.awt.Component.processMouseEvent(Component.java:6289)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
    at java.awt.Component.processEvent(Component.java:6054)
    at java.awt.Container.processEvent(Container.java:2041)
    at java.awt.Component.dispatchEventImpl(Component.java:4652)
    at java.awt.Container.dispatchEventImpl(Container.java:2099)
    at java.awt.Component.dispatchEvent(Component.java:4482)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
    at java.awt.Container.dispatchEventImpl(Container.java:2085)
    at java.awt.Window.dispatchEventImpl(Window.java:2478)
    at java.awt.Component.dispatchEvent(Component.java:4482)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:644)
    at java.awt.EventQueue.access$000(EventQueue.java:85)
    at java.awt.EventQueue$1.run(EventQueue.java:603)
    at java.awt.EventQueue$1.run(EventQueue.java:601)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
    at java.awt.EventQueue$2.run(EventQueue.java:617)
    at java.awt.EventQueue$2.run(EventQueue.java:615)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:614)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

  • 18 de mayo de 2011 16:58
    J-D :

    hey q ondas esta bueno el post pero quiero saber como hacer para que corra en windows7....agradeceria tu pronta respuesta

  • 29 de mayo de 2011 10:42
    Anónimo :

    hola rolando está muy bueno el post tengo que hacer un procesamiento de imagenes a unos microorganismos para mi estudio me gustaria saber si tienes algoritmos computacionales para ver como extraigo caracteriaticas de las imagenes... pleaseeeee!!!!!

  • 22 de agosto de 2011 13:20
    Anónimo :

    primero que todo lo felicito por el post. nos ha sido de mucha ayuda.
    y como estoy nuevo en el esto de la programacion. como puedo hacer que este codigo que coloco pueda detectar el color rojo cuando se lo pase por la camara.

    de antemano muchas gracias

Publicar un comentario