domingo, 19 de septiembre de 2010

Detector de Movimiento en pygst + pygame

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Capturador_Gstreamer.py (versión 1)
# por Flavio Danesse (fdanesse@hotmail.com)
# CeibalJAM! - Uruguay

import sys, os, time, string, gobject


import pygst
pygst.require("0.10")
import gst

import pygame
from pygame.locals import *

import gc
gc.enable()

UMBRAL = 160

class Capturador_Gstreamer():
    def __init__(self, frecuencia=2):


        self.frecuencia = frecuencia
        self.hora = time.strftime("%H:%M:%S") # hora de inicio, luego, hora de cada fotografía

        # Declaración elemendos para pipeline de fotografía
        self.pipeline = None
        self.source = None
        self.codec = None
        self.formato = None
        self.filesink = None

        self.start_streaming() # levanta el stream

        self.anizador_de_imagenes = Analiza(umbral=UMBRAL)
        self.estado = True # controla el estado general del programa

    def main(self):
        while self.estado:
            time.sleep(self.frecuencia)
            self.get_fotografia()

    def get_fotografia(self):
    # timer para ejecutar tareas programadas
        self.pipeline.set_state(gst.STATE_NULL) # anula el pipeline
        self.hora = time.strftime("%H:%M:%S") # obtiene la hora
        self.filesink.set_property("location", "%s.png" % (self.hora)) # Cambia nombre de archivo
        self.pipeline.set_state(gst.STATE_PLAYING) # Fotografía
        nombre_de_archivo = "%s.png" % (self.hora)
        self.anizador_de_imagenes.set_analisis(nombre_de_archivo)

    def construir_pipeline(self):
    # construye el stream de fotografia
        self.pipeline = gst.Pipeline("player")
       
        self.source = gst.element_factory_make("v4l2src", "camara") # origen
        self.codec = gst.element_factory_make("ffmpegcolorspace", "codec") # formato de video
        self.formato = gst.element_factory_make("pngenc", "png") # formato de imagen

        self.filesink = gst.element_factory_make("filesink", "filesink") # salida
        self.filesink.set_property("location", "%s.png" % (self.hora))

        self.pipeline.add(self.source, self.codec, self.formato, self.filesink) # armar el pipeline
        gst.element_link_many(self.source, self.codec, self.formato, self.filesink) # entubar los elementos

    def start_streaming(self):
    # Ejecuta el stream
        self.construir_pipeline() # construye el pipeline

            self.bus = self.pipeline.get_bus() # obtiene el bus de mensajes

            self.bus.add_signal_watch() # escucha las señales en el bus
            self.bus.connect("message", self.on_message) # conecta los mensajes al manejador de señales

    def on_message(self, bus, message):
    # mensajes en el bus
            if message.type == gst.MESSAGE_ERROR:
                    err, debug = message.parse_error()
                    print "ERROR ON_MESSAGE: ", err, debug

    def describe(self):
    # Descripción general del funcionamiento de la clase Capturador_Gstreamer
        descripcion = '''\t\t*** Clase Capturador_Gstreamer *** \n
        Esta clase recibe un parámetro entero que indica cada cuantos segundos debe realizar una fotografía.\n
        Luego, comenzara a fotografiar y guardar esas imágenes con el nombre de archivo igual a la hora de realizada la fotografía.\n
        Mientras la variable estado sea True, continuará realizando esta tarea.'''
        return descripcion



class Analiza():

    def __init__(self, umbral=160):
        pygame.init()
        pygame.mixer.quit()
        self.umbral = umbral
        self.imagenes = []

    def analiza_cambios(self, imagen1=None, imagen2=None, u=160):
    # recibe una imagen cargada por pygame y analiza las variaciones de color en cada pixel, retornando True o False, según sean cambios grandes o pequeños.
        (init_x, init_y, horizontal, vertival) = imagen1.get_bounding_rect()
        gris = 0
        blanco = 0
        negro = 0
        for x in range(horizontal):
            for y in range(vertival):
                (r, g, b, a) = imagen1.get_at((x,y))
                (rn, gn, bn, an) = imagen2.get_at((x,y))

                dif_rojo = r-rn
                dif_verde = g-gn
                dif_azul = b-bn

                if dif_rojo < -u or dif_rojo > u or dif_verde < -u or dif_verde > u or dif_azul < -u or dif_azul > u:
                    return True
        return False

    def set_analisis(self, nombre_de_archivo):
    # recibe una dirección de archivo para la imagen a analizar
        self.imagenes.append(nombre_de_archivo)

        # Esperar a tener 5 imagenes para asegurar que estén completamente guardadas las 2 primeras.
        if len(self.imagenes) > 5:
            direccion_imagen1 = self.imagenes[0]
            direccion_imagen2 = self.imagenes[1]

            imagen1 = pygame.image.load(direccion_imagen1)
            imagen2 = pygame.image.load(direccion_imagen2)

            # compare 1 con 2, si no hay cambios, borrar 1
            if not self.analiza_cambios(imagen1=imagen1, imagen2=imagen2, u=self.umbral):
                os.system ("rm %s" % (self.imagenes[0]))
               
            self.imagenes.remove(self.imagenes[0])


if __name__ == "__main__":
    # frecuencia es cada cuantos segundos debe fotografiar
    capturador = Capturador_Gstreamer(frecuencia=2) # 2 para pc normal 4 o más para xo
    #print capturador.describe()
    capturador.main()

No hay comentarios:

Publicar un comentario