jueves, 16 de mayo de 2013

Detección de movimiento

Generador de animaciones

El generador en python usando Blender y toma como parámetros el numero de objetos y los tipos (esfera, cubo), y después se elige de manera random hacia donde moverse, teniendo 6 opciones:

  • arriba (eje y)
  • abajo (eje y)
  • derecha (eje x)
  • izquierda (eje x)
  • enfrente (eje z)
  • atrás (eje z)
En el siguiente vídeo podemos ver el movimiento en las tres objetos tiene LUZ para poder ver claramente los movimientos en el eje Z, pero para procesarlos le quité estos efectos para poder identificarlos mejor:

Movimiento en los 3 ejes

Los siguientes ya no tienen luz:

Movimiento en 2 ejes

Movimiento en los 3 ejes


Código:

import random
import bpy#blender libreria
from math import pi
bpy.ops.object.delete()
add_cube = bpy.ops.mesh.primitive_cube_add
mylayers = [False]*20
mylayers[0] = True
obj = bpy.data.objects['Camera']
obj.location.x = 0.0
obj.location.y = 80
obj.location.z = 0.0
obj.rotation_euler[0] = 4.71
obj.rotation_euler[1] = 0
obj.rotation_euler[2] = 0
obj.keyframe_insert(data_path="location", frame=0.0)
def izquierda(obj,f_i, f_f,v):
"""movimiento a la izquierda
"""
obj.keyframe_insert(data_path="location", frame=f_i, index=0)
obj.location[0] = obj.location[0] + v
x = obj.location[0]
y = obj.location[1]
z = obj.location[2]
obj.keyframe_insert(data_path="location", frame=f_f, index=0)
def derecha(obj,f_i, f_f,v):
"""movimiento a la derecha
"""
obj.keyframe_insert(data_path="location", frame=f_i, index=0)
obj.location[0] = obj.location[0] - v
obj.keyframe_insert(data_path="location", frame=f_f, index=0)
def abajo(obj,f_i, f_f,v):
"""movimiento hacia abajo
"""
obj.keyframe_insert(data_path="location", frame=f_i, index=-1)
obj.location[2] = obj.location[2] - v
obj.keyframe_insert(data_path="location", frame=f_f, index=-1)
def arriba(obj,f_i, f_f,v):
"""movimiento hacia arriba
"""
obj.keyframe_insert(data_path="location", frame=f_i, index=-1)
#obj.location[2] = random.random()*10
obj.location[2] = obj.location[2] + v
obj.keyframe_insert(data_path="location", frame=f_f, index=-1)
def acercar(obj,f_i, f_f,v):
"""acercar el objeto
"""
obj.keyframe_insert(data_path="location", frame=f_i, index=-1)
obj.location[1] = obj.location[1] - v
obj.keyframe_insert(data_path="location", frame=f_f, index=-1)
def alejar(obj,f_i, f_f,v):
"""alejar el objeto
"""
obj.keyframe_insert(data_path="location", frame=f_i, index=-1)
obj.location[1] = obj.location[1] + v
obj.keyframe_insert(data_path="location", frame=f_f, index=-1)
for index in range(0, 3):
if index >=1:
add_cube(location=(index*6, 0, 0), layers=mylayers)
else:
bpy.ops.mesh.primitive_uv_sphere_add(location=(index*3,0,0))
obj = bpy.context.object
f_i= 2
f_f = 5
for i in range(10):
eleccion = random.randint(1,6)
v = random.randint(2,4)
if eleccion == 1:
alejar(obj, f_i, f_f,v)
elif eleccion == 2:
acercar(obj, f_i, f_f,v)
elif eleccion == 3:
izquierda(obj, f_i, f_f,v)
elif eleccion == 4:
derecha(obj,f_i, f_f,v)
elif eleccion == 5:
arriba(obj,f_i, f_f,v)
else:
abajo(obj,f_i, f_f,v)
f_i = f_f + 1
f_f = f_i + 2
view raw gistfile1.py hosted with ❤ by GitHub



Detección de movimiento

Método de diferencia

Se utilizo el método de diferencia que funciona de la siguiente manera:

if (pix_act[i,j] - pix_ant[i,j]) > 50
 
Si se cumple con esta condición entonces se dice que hubo un movimiento y el pixel se pinta de negro y los demás de blanco.

Para saber hacia que lado se mueven las figuras se hizo BFS a todo lo que se encuentra en la imagen  y se guardaron en una lista cada elemento que pertenece a un objeto de esta manera para saber si se movió simplemente se hacia una comparación entre los objetos del nuevo frame y si esta cercano al objeto del frame pasado entonces se sabe que se movió y se realizan restas simplemente para poder deducir hacia que lado se movió.

Ejemplo:

Animación original

Diferencia

Indicando la dirección





Este es el código:

#!/usr/bin/python
import math
import sys
import filtros
import random
from math import sqrt, atan2, pi, atan
from collections import defaultdict
from PIL import ImageDraw
import Image
import glob
import os
import time
def frames():
"""toma todas las imagenes de
la carpeta
"""
os.chdir("cuatro")
files = []
secuencia = []
for file in glob.glob("*.png"):
files.append(file)
for i in range(1, len(files)):
secuencia.append("%04d.png" %i)
print secuencia
return secuencia
def bfs(imagen, origen, color):
"""colorea todo el objeto recibe como parametros el
nuevo color con el que se pinta,la coordenada de inicio y
la imagen, y regresa un arreglo con la masa y la imagen
"""
cola = []
cont = 0
masa = []
pixeles = imagen.load()
alto, ancho = imagen.size
cola.append(origen)
original = pixeles[origen]
todos_pixeles = []
while len(cola) > 0:
(x, y) = cola.pop(0)
actual = pixeles[x, y]
if actual == original or actual == color:
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
candidato = (x + dx, y + dy)
pix_x = candidato[0]
pix_y = candidato[1]
if pix_x >= 0 and pix_x < alto and pix_y >= 0 and pix_y < ancho:
contenido = pixeles[pix_x, pix_y]
if contenido == original:
pixeles[pix_x, pix_y] = color
masa.append((pix_x,pix_y))
imagen.putpixel((pix_x, pix_y), color)
cont += 1
cola.append((pix_x, pix_y))
todos_pixeles.append((pix_x, pix_y))
imagen.save("../bfs"+str(time.time()), 'png')
return imagen, cont, masa, todos_pixeles
def diferencia(ant, act):
"""
"""
alto, ancho = ant.size
p_ant = ant.load()
p_act = act.load()
nueva = Image.new("RGB", (alto, ancho))
for i in range(alto):
for j in range(ancho):
if abs(p_ant[i,j][0]-p_act[i,j][0])>4:
a = abs(p_ant[i,j][0]-p_act[i,j][0])
color = (0,0,0)
else:
color = (255,255,255)
nueva.putpixel((i,j), color)
nueva.save("../dif/"+str(time.time())+".png")
return nueva
def main():
existe = False
secuencia = frames()
for i in range(len(secuencia)):
if i == 0:
ant = filtros.abrir_imagen(secuencia[i])
act = filtros.abrir_imagen(secuencia[i])
continue
ant = act
act = filtros.abrir_imagen(secuencia[i])
aux = act.copy()
draw = ImageDraw.Draw(aux)
res = diferencia(ant, act)
alto, ancho = res.size
pixeles = res.load()
for x in range(alto):
for y in range(ancho):
if pixeles[x,y] == (0,0,0):
r = int(random.random()*250)
g = int(random.random()*250)
b = int(random.random()*250)
nuevo_color = (r,g,b)
imagen, cont, masa, todos_pixeles = bfs(res, (x,y), nuevo_color)
x_max = todos_pixeles[0][0]
x_min = todos_pixeles[0][0]
y_max = todos_pixeles[0][1]
y_min = todos_pixeles[0][1]
total_x = 0
total_y = 0
for l in range(len(masa)):
total_x = total_x + masa[l][0]
total_y = total_y + masa[l][1]
x_centro = total_x/len(masa)
y_centro = total_y/len(masa)
centro = (x_centro,y_centro)
for p in todos_pixeles:
if p[0] > x_max:
x_max = p[0]
if p[0] < x_min:
x_min = p[0]
if p[1] > y_max:
y_max = p[1]
if p[1] < y_min:
y_min = p[1]
if abs(y_max-y_min) > abs(x_max-x_min):
print "mov vertical"
if existe:
if pp[x_max+1, y_max-3] == (255, 255, 255):
print "mov izq"
draw.text(centro, "->", (255, 0, 0))
else:
print "mov der"
draw.text(centro, "<-", (255, 0, 0))
aux.save("../fin/"+str(time.time())+".png")
else:
print "mov horizontal"
if existe:
if pp[x_max-3, y_max+1] == (255, 255, 255):
print "mov abajo"
draw.text(centro, "v", (255, 0, 0))
else:
print "mov arriba"
draw.text(centro, "^", (255, 0, 0))
aux.save("../fin/"+str(time.time())+".png")
try:
a = res.copy()
pp = a.load()
existe = True
except:
pass
main()
view raw gistfile1.py hosted with ❤ by GitHub







1 comentario:

  1. Movimiento 3D de múltiples objetos con generador propio; cámara estacionaria; detección de dirección de movimiento. 16 pts.

    ResponderEliminar