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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
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