Creación de una cámara de seguridad con Java

    ¿No te encuentras seguro en tu casa? ¿Necesitas que alguien vele por tu seguridad para poder dormir bien? ¡Estás de suerte amigo! ¡JSecurityCam solucionará tus problemas y además de forma gratuita! ...
    Pues siento decirte que si eso es lo que buscas, en este artículo no lo vas a encontrar. Sí, crearemos una cámara de seguridad, pero, ni mucho menos nos podrá servir para detectar ladrones y avisar a la policía en cuanto aparezcan por tu casa. En el artículo Presentación de JSecurityCam se puede ver el  programa que vamos a crear en este vídeo. Haremos uso de las clases WebCam y CanvasCam creadas en el anterior videotutorial del curso sobre el uso de la webcam en Java.
    Una muy buena utilidad de este programa es que te permite gastar bromas a tus amigos. Puedes dejar el programa abierto con el volumen del ordenador muy alto. En el momento que algún amigo o familiar entre en el cuarto sonaría la alarma con gran intensidad. Si se tratan de altavoces potentes puedes llegar a hacer que salte del susto ;)



Posibles mejoras del programa:
  • Un check box que permita activar o desactivar el sonido.
  • Guardar las imágenes que se capturan en los momentos en los que se detecta movimiento.
  • Un JSlider que permita ajustar el margen de diferencia máximo que puede existir entre el RGB de dos píxels análogos. De esta manera evitaríamos "inventarnos" ese número y lo podríamos cambiar en tiempo de ejecución sin modificar el código fuente.

El archivo de audio lo podéis encontrar aquí.

Código de la clase JSecurityCam:
// JSecurityCam.java -----------------------------------------------------------

package jwebcam;

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.swing.JFrame;
import javax.swing.JToggleButton;


/**
 *
 * @author <a href="http://programmingheroes.blogspot.com">ProgramminHeroes</a>
 */
public class JSecurityCam extends JFrame implements ItemListener, Runnable {

    public volatile boolean watching = false;
    
    private CanvasCam canvasCam;
    private JToggleButton button;
    
    private BufferedImage img;
    
    private Thread watch;
    
    private AudioClip alarm;
    
    public JSecurityCam() {
        super("JSecurityCam");
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent ev) {
                canvasCam.stop();
                System.exit(0);
            }
        });
        
        canvasCam = new CanvasCam();
        button = new JToggleButton("Iniciar vigilancia");
        button.setFont(button.getFont().deriveFont(50F));
        button.addItemListener(this);
        
        this.setLayout(new BorderLayout());
        this.add(canvasCam, BorderLayout.CENTER);
        this.add(button, BorderLayout.SOUTH);
        this.pack();
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
        
        canvasCam.start();
    } // fin de JSecurityCam();
    
    
    
    /**
     * @param args Argumentos de la línea de comandos
     */
    public static void main(String[] args) {
        new JSecurityCam();
    } // fin de main(String[]);

    @Override
    public void itemStateChanged(ItemEvent e) {
        if (button.isSelected()) {
            img = canvasCam.getCurrentImage();
            if (img != null) {
                button.setText("Detener vigilancia");
                watch = new Thread(this);
                watch.start();
            } else {
                button.setSelected(false);
            }
        } else {
            watching = false;
            if (watch != null) {
                watch = null;
            }
            button.setText("Iniciar vigilancia");
        }
    }

    public boolean similarImgs(BufferedImage img1, BufferedImage img2) {
        for (int i=1; i<img1.getWidth(); i+=4) {
            for (int j=0; j<img1.getHeight(); j+=4) {
                if (Math.abs(img1.getRGB(i, j)-img2.getRGB(i, j)) > 6000000) {
                    return false;
                }
            }
        }
        return true;
    }
    
    public void alarm() {
        try {
            System.out.println("¡¡¡¡ALARMA!!!!");
            URL url = getClass().getClassLoader().getResource("alarm.wav");
            if (alarm == null) {
                alarm = Applet.newAudioClip(url);
                alarm.loop();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public void run() {
        BufferedImage currentImg = null;
        int n = 0;
        watching = true;
        while (watching) {
            long t = System.currentTimeMillis();
            currentImg = canvasCam.getCurrentImage();
            if (!similarImgs(img, currentImg)) {
                alarm();
            }
            if (++n > 100) {
                img = currentImg;
                n = 0;
            }
            t = System.currentTimeMillis()-t;
            
            try {
                if (100-t > 0)
                    Thread.sleep(100-t);
            } catch (InterruptedException ex) {}
        }
        img = null;
        if (alarm != null) {
            alarm.stop();
            alarm = null;
        }
    }

} // fin de la clase JSecurityCam

// fin de JSecurityCam.java ----------------------------------------------------

18 comentarios :

  1. xumas.me dice k no se ha encontrado un webcam :(

    ResponderEliminar
    Respuestas
    1. ¿Que no la encuentra dices? Intenta utilizar el JMFRegistry para añadir la webcam a la lista de dispositivos disponibles desde JMF
      También puedes probar el JMFStudio, así averiguaras si realmente Java puede acceder a tu webcam.

      Eliminar
  2. y la libreria CanvasCam ? me sale error :s

    ResponderEliminar
    Respuestas
    1. http://programmingheroes.blogspot.com.es/2012/08/la-clase-webcam.html
      Este programa hace uso de otras clases que hemos creado en tutoriales anteriores
      Un saludo :)

      Eliminar
  3. Que tal hasta este momento no logro cargar mi camara web instale el JMstudio pero no me detecta por ninguna forma mi camara web ya instale el jdk 1.6 para x86 y 64 bit pero nada te agradeceria y en este ultimo programa me sale error en img = canvasCam.getCurrentImage(); y currentImg = canvasCam.getCurrentImage() si me ayudas te lo agradeceria mucho

    ResponderEliminar
    Respuestas
    1. No basta con tener instalados los 2 jdk, tienes que asegurarte de que tu proyecto usa el de x86.
      Ejecuta como administrador el JMFRegistry e intenta buscar nuevos dispositivos.
      Los errores esos que dices si te siguen apareciendo una vez puedas acceder a la webcam me lo dices y buscamos solucion ;)

      Eliminar
    2. también me sale el mismo error, y solo me aparecen dispositivos de audio

      Eliminar
  4. Hola
    Me pareces que has hecho un trabajo muy bueno con respecto a la seguridad ya he aplicado todo estos conocimientos y son excelentes.
    Quiero decirte que estoy creando un proyecto con captura de huellas dactilares y no sé cómo empezar. Sería mucho pedirte una guía sobre esto
    Mario mendez mendezmartinezmario@gmail.com

    ResponderEliminar
  5. hola amigo, me gustaron mucho tus tutoriales, pero tengo una gran duda y no he podido solucionarla, aplicando lo que aprendi con tus tutoriales cree una aplicacion cliente servidor donde el servidor contiene todo lo necesario para activar la camara y el cliente solo manda la señal para que esta se active

    mi preguta es, en el IDE que es eclipse me funciona correctamente, pero cuando intento generar el archivo jar no me funciona las librerias de jmf

    QUE PUEDO HACER PARA SOLUCIONAR ESTO?

    ResponderEliminar
    Respuestas
    1. Por cierto tambien lo intente con netbeans , solo el ejemplo basico de tu tutorial 4, "sin cliente servidor" y al parecer cuando se abre la aplicacion se cierra sola, porque puede ser?

      Eliminar
    2. No he trabajado nunca con cámaras IP, así que me temo que no puedo ayudarte.
      En cuanto a lo del JAR de JMF, ¿has probado a extraer los archivos del JAR de JMF y posteriormente incluirlas en tu JAR?

      Eliminar
  6. No me muestra la imagen, y ya lo registre en el JMFRegistry si sale como registrada mi camara, pero al momento de correr el programa no muestra la imagen. Gracias por la ayuda

    ResponderEliminar
  7. Amigo me sale error en img = canvasCam.getCurrentImage() en public void itemStateChenged(ItemEvent e) me dice que debo crear el metodo getCurrentImage en canvasCam "is undefined for the type CanvasCam" sabes algo amigo?

    ResponderEliminar
    Respuestas
    1. ¿Tienes la clase CanvasCam? Creo recordar que en uno de los videotutoriales anteriores la creamos.

      Un saludo amigo!

      Eliminar
  8. Que onda amigo ya tengo ejecutando la aplicacion y todo bien pero necesito ayuda lo que pasa que veras me pidieron una aplicacion en java y escogi la que tu desarrollaste me parecio interesante y entendible pero lo que quiero hacer es hacer una condicion que por cada numero de mensajes de alerta me arroje la reproduccion del sonido cada ves que pasa algo por la camara no se si me entiendas amigo
    me podrias ayudar o asesorar de como hacer esa condicion que por cada numero de mensajes reprodusca el sonido de alerta y que no los reprodusca por cada mensaje
    este es mi facebook https://www.facebook.com/sony.jimenez.31
    y este es mi correo greenday_2I@hotmail.com no se si me puedas ayudar amigo por favor :D

    ResponderEliminar
  9. Este ejemplo solo aplica para camaras Web?

    ResponderEliminar
    Respuestas
    1. Todas las que soporte JMF que no sé cuales son... Imagino que solo cámaras web.

      Eliminar
  10. Aún no haces las mejoras? esto se ve muy interesante, las intentaré hacer yo.

    ResponderEliminar