jueves, 16 de mayo de 2013

Laboratorio de Visión: Detección de movimiento

En esta entrada se trata de detectar el movimiento y lo que se me ocurrio fue que puedo detectar el movimiento de la siguiente manera:

Primero que nada me base en puras figuras solidas como en este caso un cuadrado:

  • Obtenemos la primer imagen de una animación y la procesamos de la siguiente manera:
    • escala de grises
    • filtro
    • convolución
    • formas
  • Ya obteniendo la imagen en formas debemos de tener el centro de esta forma y lo guardamos en una lista.
  • La segunda imagen creada por la animación se le aplica el mismo proceso:
    • escala de grises
    • filtro
    • convolución
    • formas
  • De la misma manera se obtiene lo que son sus centros
  • Ahora para saber si existe movimiento comparamos  lo la posición de los centros y si la posición es diferente entonces encontramos que si se realizo movimiento.



Prueba 1:

Primera imagen obtenida de la animación:





Filtro:

Convolución:


Normalizar:


Binzarizar:


Cambio de Movimiento:





La imagen anterior muestra hacia que lado se hizo el movimiento según los centros y lo pinte con una línea azul.

Código:

import pygame, sys, time
from pygame.locals import *
import Image
import numpy as np
import math
from sys import argv
from math import *
import random
img='nuevo.png'
ancho=300
alto=300
ventana=None
centro_a=[]
centro_s=[]
anterior=None
siguiente=None
centro=[]
v=False
def open_p():
imagen=Image.open('nuevo.png')
pixels=imagen.load()
return pixels
def detect_motion(pix1,pix2):
global img,ancho,alto
pix=[pix1,pix2]
for p in pix:
#print 'FORMA'
formas(p)
return
def formas(pix):
image = filtro(pix)
# print 'salio de filtro'
#raw_input()
image_c,minimo,maximo,gx,gy,conv = mascara(image)
pix_n=normalizar(image_c,minimo,maximo,conv)
pix_b= binarizar(pix_n)
v=deteccion(pix_b,pix_b)
return v
def deteccion(img,im):
global centro_a,centro_s,v
imagen,masa,centros=c_colorear(img,im)
centros.pop(0)
if len(centro_a)==0:
centro_a.append(centros[0])
else:
centro_s.append(centros[0])
v=motion(centro_a,centro_s)
centro_s=centro_s
return v
def motion(centro_a,centro_s):
if centro_a[0]==centro_s[0] and centro_a[1]==centro_s[1]:
print 'No hay mov'
v=False
else:
print 'Hay movimiento'
print 'centro_a',centro_a
print 'centro_s',centro_s
pygame.draw.line(ventana, (0, 0, 255), centro_a[0], centro_s[0])
v=True
return v
def c_colorear(im,imag):
pixels=im.load()
global ancho,alto
porcentajes=[]
fondos=[]
centro_masa=[]
masa=[]
ancho,alto=im.size
t_pixels=ancho*alto
c=0
pintar=[]
f=0
m=[]
for i in range(ancho):
for j in range(alto):
pix = pixels[i,j]
r,g,b= random.randint(0,255),random.randint(0,255), random.randint(0,255)
fondo=(r,g,b)
if (pix==(0,0,0)):
#print 'entro'
c +=1
origen=(i,j)
num_pixels,abscisa,ordenada,puntos=bfs(pix,origen,imag,fondo)
p=(num_pixels/float(t_pixels))*100
if p>.3:
centro=(sum(abscisa)/float(num_pixels),sum(ordenada)/float(num_pixels))
#centro_masa.append(centro)
masa.append(num_pixels)
porcentajes.append(p)
# self.pintar(puntos)
fondos.append(fondo)
centro_masa.append(centro)
# print centro
#imprimir_porcentajes(porcentajes)
im.save('formas.png')
return im,m,centro_masa
def bfs(pix,origen,im,fondo):
pixels=im.load()
cola=list()
lista=[-1,0,1]
abscisa=[]
ordenada=[]
puntos=[]
cola.append(origen)
original = pixels[origen]
num=1
while len(cola) > 0:
(i,j)=cola.pop(0)
actual = pixels[i,j]
if actual == original or actual==fondo:
for x in lista:
for y in lista:
a= i+x
b = j+y
try:
if pixels[a,b]:
contenido = pixels[a,b]
if contenido == original:
pixels[a,b] = fondo
abscisa.append(a)
ordenada.append(b)
num +=1
cola.append((a,b))
puntos.append((a,b))
except IndexError:
pass
return num,abscisa,ordenada,puntos
def normalizar(image,minimo,maximo,conv):
pixels=image.load()
global anocho,alto
r = maximo-minimo
prop = 255.0/r
for i in range(ancho):
for j in range(alto):
p =int(floor((conv[i,j]-minimo)*prop))
pixels[i,j]=(p,p,p);
image.save('normalizar.png')
return image
def binarizar(img):
global anocho,alto
pixels=img.load()
img.save('para.png')
minimo = int(argv[1])
for i in range(ancho):
for j in range(alto):
# print pixels[i,j][0]
if pixels[i,j][0] < minimo:
p=0
# print 'entro al if'
#raw_input()
else:
p= 255
pixels[i,j]=(p,p,p)
img.save('binarizar.png')
return img
def mascara(image):
#Mascara Sobel
sobelx = ([-1,0,1],[-2,0,2],[-1,0,1]) #gradiente horizontal
sobely = ([1,2,1],[0,0,0],[-1,-2,-1]) # gradiente vertical
pixels,minimo,maximo,gx,gy,conv=convolucion(sobelx,sobely,image)
return pixels,minimo,maximo,gx,gy,conv
def convolucion(h1,h2,image):
global ancho,alto
pixels=image.load()
a=len(h1[0])
conv = np.empty((ancho, alto))
gx=np.empty((ancho, alto))
gy=np.empty((ancho, alto))
minimo = 255
maximo = 0
for x in range(ancho):
for y in range(alto):
#print 'prob',pixels[x,y]
sumax = 0.0
sumay = 0.0
for i in range(a):
for j in range(a):
try:
sumax +=(pixels[x+i,y+j][0]*h1[i][j])
sumay +=(pixels[x+i,y+j][0]*h2[i][j])
except:
pass
gradiente = math.sqrt(pow(sumax,2)+pow(sumay,2))
conv[x,y]=gradiente
gx[x,y]=sumax
gy[x,y]=sumay
# print 'sumax',sumax
# print 'sumay',sumay
gradiente = int(gradiente)
pixels[x,y] = (gradiente,gradiente,gradiente)
p = gradiente
if p <minimo:
minimo = p
if p >maximo:
maximo = p
#print 'gx-------------',minimo
#print 'gy-------------',maximo
image.save('convolucion.png')
return image,minimo,maximo,gx,gy,conv
def filtro(pix):
global ancho,alto
imagen = Image.new('RGB', (ancho, alto), (255, 255, 255))
image=escala_grises(pix,imagen)
# print 'regreso de grises'
# print 'entro a filtro'
pixels=image.load()
lista = [-1,0,1]
for i in range(ancho):
for j in range(alto):
#print 'i',i
#print 'j',j
promedio = vecindad(i,j,lista,image)
#print 'promedio',promedio
#raw_input()
pixels[i,j] = (promedio,promedio,promedio)
image.save('filtro.png')
return image
def vecindad(i,j,lista,image):
#raw_input()
#image.save('imagen.png')
pixels=image.load()
promedio = 0
indice = 0
for x in lista:
for y in lista:
#print pixels[i,j]
a = i+x
b = j+y
try:
#print 'try'
#print 'a',a
#print 'b',b
if pixels[a,b] and (x!=a and y!=b):
# print 'entro al if'
promedio += pixels[a,b][0]
indice +=1
except IndexError:
pass
try:
promedio=int(promedio/indice)
return promedio
except ZeroDivisionError:
return 0
def escala_grises(pix,image):
p=image.load()
global ancho,alto
pixels = pix
matriz = np.empty((ancho, alto))
for i in range(ancho):
for j in range(alto):
(r,g,b) = pixels[i,j]
escala = (r+g+b)/3
pixels[i,j] = (escala,escala,escala)
p[i,j]=(escala,escala,escala)
image.save('escala.png')
return image
def main():
#anterior=None
#siguiente=None
global img,ventana,anterior,siguiente
pygame.init()
ancho = 300
alto = 300
ventana= pygame.display.set_mode((ancho, alto), 0, 32)
pygame.display.set_caption('Deteccion de Movimiento')
DOWNLEFT = 1
DOWNRIGHT = 3
UPLEFT = 7
UPRIGHT = 9
MOVESPEED = 4
RED = (25, 120, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
b1 = {'rect':pygame.Rect(50, 50,50, 50), 'color':RED, 'dir':UPRIGHT}
blocks = [b1]
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
ventana.fill((255,255,255))
for b in blocks:
if b['dir'] == DOWNLEFT:
b['rect'].left -= MOVESPEED
b['rect'].top += MOVESPEED
if b['dir'] == DOWNRIGHT:
b['rect'].left += MOVESPEED
b['rect'].top += MOVESPEED
if b['dir'] == UPLEFT:
b['rect'].left -= MOVESPEED
b['rect'].top -= MOVESPEED
if b['dir'] == UPRIGHT:
b['rect'].left += MOVESPEED
b['rect'].top -= MOVESPEED
if b['rect'].top < 0:
if b['dir'] == UPLEFT:
b['dir'] = DOWNLEFT
if b['dir'] == UPRIGHT:
b['dir'] = DOWNRIGHT
if b['rect'].bottom > ancho:
# block has moved past the bottom
if b['dir'] == DOWNLEFT:
b['dir'] = UPLEFT
if b['dir'] == DOWNRIGHT:
b['dir'] = UPRIGHT
if b['rect'].left < 0:
# block has moved past the left side
if b['dir'] == DOWNLEFT:
b['dir'] = DOWNRIGHT
if b['dir'] == UPLEFT:
b['dir'] = UPRIGHT
if b['rect'].right > alto:
# block has moved past the right side
if b['dir'] == DOWNRIGHT:
b['dir'] = DOWNLEFT
if b['dir'] == UPRIGHT:
b['dir'] = UPLEFT
# draw the block onto the surface
#if anterior==None:
# anterior=imagen
pygame.draw.rect(ventana, b['color'], b['rect'])
im='nuevo.png'
pygame.image.save(ventana,img)
#img='nuevo.png'
if anterior==None:
#pygame.image.save(ventana,img_a)
pix_a=open_p()
anterior=pix_a
#print 'anterior',anterior
else:
#pygame.image.save(ventana,img_s)
pix_s=open_p()
siguiente=pix_s
#print 'siguiente'
flecha=detect_motion(pix_a,pix_s)
anterior=siguiente
if flecha==True:
print 'flecha==TRue'
pygame.draw.line(ventana, (0, 0, 255), centro_a, centro_s)
pygame.display.update()
#anterior=siguiente
time.sleep(0.02)
main()
view raw mov.py hosted with ❤ by GitHub

1 comentario:

  1. Detección de movimiento – en secuencias de imágenes - sin clasificar según la dirección de movimiento; generación de entrada. Sin conclusiones muy claras sobre cómo funcionó. 7 pts. Haz lo de wavelets.

    ResponderEliminar