Primeramente se obtuvieron las imágenes que serian utilizadas para este laboratorio, yo en mi caso use desde la cámara web , se utilizo opencv solamente para esto pero no para ninguna otra función.
Aquí se puede observar el momento de ejecutar el programa, iré dejando las partes importantes del código.


El proceso era muy lento ya que mientras se tomaba captura de vídeo con la cámara se procesaba la imagen , a escala de grises y se le aplicaba un filtrado , aquí arriba se muestran las dos imágenes con el filtrado aplicado y después se sacaba la convolución. Aquí dejo el código de eso.
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 cv | |
import Image | |
import numpy as np | |
def detect_painting(image): | |
image = filtro(image) | |
#img = mascara(image) | |
def mascara(self,image): | |
inicio = time() | |
#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 | |
img=self.convolucion(sobelx,sobely,image) | |
fin=time() | |
tiempo_t = fin - inicio | |
#print "Tiempo que tardo en ejecutarse convolucion = "+str(tiempo_t)+" segundos" | |
return img | |
def convolucion(self,h1,h2,image): | |
pixels = image.load() | |
ancho,alto = image.size | |
a=len(h1[0]) | |
self.conv = numpy.empty((ancho, alto)) | |
self.gx=numpy.empty((ancho, alto)) | |
self.gy=numpy.empty((ancho, alto)) | |
self.minimo = 255 | |
self.maximo = 0 | |
for x in range(ancho): | |
for y in range(alto): | |
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)) | |
self.conv[x,y]=gradiente | |
self.gx[x,y]=sumax | |
self.gy[x,y]=sumay | |
gradiente = int(gradiente) | |
pixels[x,y] = (gradiente,gradiente,gradiente) | |
p = gradiente | |
if p < self.minimo: | |
self.minimo = p | |
if p > self.maximo: | |
self.maximo = p | |
# print 'gx-------------',self.gx | |
# print 'gy-------------',self.gy | |
return image | |
def normalizar(self,image): | |
inicio=time() | |
pixels = image.load() | |
r = self.maximo-self.minimo | |
prop = 255.0/r | |
ancho,alto = image.size | |
for i in range(ancho): | |
for j in range(alto): | |
p =int(floor((self.conv[i,j]-self.minimo)*prop)) | |
pixels[i,j]=(p,p,p); | |
# print 'TERMINO' | |
fin = time() | |
tiempo_t = fin - inicio | |
# print "Tiempo que tardo en ejecutarse normalizar = "+str(tiempo_t)+" segundos" | |
return image | |
def binarizar(self,img): | |
inicio = time() | |
pixels = img.load() | |
ancho,alto = img.size | |
minimo = int(argv[2]) | |
for i in range(ancho): | |
for j in range(alto): | |
if pixels[i,j][1] < minimo: | |
p=0 | |
else: | |
p= 255 | |
pixels[i,j]=(p,p,p) | |
fin =time() | |
tiempo_t = fin - inicio | |
# print "Tiempo que tardo en ejecutarse binzarizar = "+str(tiempo_t)+" segundos" | |
return img | |
def filtro(image): | |
image,matriz = escala_grises(image) | |
pixels = image.load() | |
ancho, alto =image.size | |
lista = [-1,0,1] | |
for i in range(ancho): | |
for j in range(alto): | |
promedio = vecindad(i,j,lista,matriz) | |
pixels[i,j] = (promedio,promedio,promedio) | |
image.save('FILTRO.png') | |
return image | |
def escala_grises(image): | |
image = Image.open(image) | |
pixels = image.load() | |
ancho,alto = image.size | |
matriz = np.empty((ancho, alto)) | |
for i in range(ancho): | |
for j in range(alto): | |
(r,g,b) = image.getpixel((i,j)) | |
escala = (r+g+b)/3 | |
pixels[i,j] = (escala,escala,escala) | |
matriz[i,j] = int(escala) | |
df = image.save('escala.png') | |
return image,matriz | |
def vecindad(i,j,lista,matriz): | |
promedio = 0 | |
indice = 0 | |
for x in lista: | |
for y in lista: | |
a = i+x | |
b = j+y | |
try: | |
if matriz[a,b] and (x!=a and y!=b): | |
promedio += matriz[a,b] | |
indice +=1 | |
except IndexError: | |
pass | |
try: | |
promedio=int(promedio/indice) | |
return promedio | |
except ZeroDivisionError: | |
return 0 | |
def main(): | |
cam=cv.CaptureFromCAM(0) | |
while True: | |
im =cv.QueryFrame(cam) | |
snapshot = im | |
image_size = cv.GetSize(snapshot) | |
cv.SaveImage("test.png",im) | |
imagen=cv.CreateImage(image_size,cv.IPL_DEPTH_8U,3) | |
detect_painting("test.png") | |
cv.ShowImage('Camara', snapshot) | |
if cv.WaitKey(30)==27: | |
break | |
main() |
Posteriormente las imágenes se sometían a un binarizado y normalizado .
Después se procedía a sacarles una diferencia a estas imágenes eliminando un poco el ruido para comprobar los pixeles que sufrieron cambios de una imagen a otra.(cabe mencionar que salia mi dedo en una imagen la cambie por otra para evitar mas ruido)
Aun se puede apreciar que la imagen muestra ruido , pero claramente se observa también las lineas divisorias del movimiento.
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 | |
from pygame.locals import * | |
import Image | |
import math | |
#CONVOLUCION A ESCALA DE GRISES Y FILTRADA | |
image = Image.open("convo1.png") | |
pixeles = image.load() | |
ancho, altura =image.size | |
msobelX = ([-1, 0, 1], [-2, 0, 2], [-1, 0, 1]) #Para gradiente de x. | |
msobelY = ([1, 2, 1], [0, 0, 0], [-1, -2, -1]) #Para gradiente de y. | |
prewittX=([-1, 0, 1], [-1, 0, 1], [-1, 0, 1])#EJE X PREWITT | |
prewittY=([1, 1, 1], [0, 0, 0], [-1,-1,-1])#EJE Y PREWITT | |
tamanomatriz=3 | |
sumatoriaX = 0 | |
sumariaY = 0 | |
seleccion=raw_input("INGRESA 1 PARA SOBEL y DOS PARA PREWITT ") | |
matrizagarrada=int(seleccion) | |
if matrizagarrada==1: | |
for x in range(altura): | |
for y in range(ancho): | |
sumatoriaX = 0 | |
sumatoriaY = 0 | |
if x != 0 and y != 0 and y != ancho and x != altura: | |
for i in range(tamanomatriz): | |
for j in range(tamanomatriz): | |
try: | |
gx = msobelX[i][j]*pixeles[y+j, x+i][1] | |
gy = msobelY[i][j]*pixeles[y+j, x+i][1] | |
except: | |
productosGX = 0 | |
productosGY = 0 | |
sumatoriaX = gx+sumatoriaX | |
sumatoriaY = gy+sumatoriaY | |
gxalcuadrado = pow(sumatoriaX, 2) | |
gyalcuadrado = pow(sumatoriaY, 2) | |
gradienteResultante = int(math.sqrt(gxalcuadrado+gyalcuadrado)) | |
pixelNuevo=gradienteResultante | |
if pixelNuevo> 255: | |
pixelNuevo = 255 | |
if pixelNuevo < 0: | |
pixelNuevo = 0 | |
pixeles[y,x] = ( pixelNuevo, pixelNuevo, pixelNuevo) | |
image.save('convo1sal.png', 'png') | |
#image.show() | |
if matrizagarrada==2: | |
for x in range(altura): | |
for y in range(ancho): | |
sumatoriaX = 0 | |
sumatoriaY = 0 | |
if x != 0 and y != 0 and y != ancho and x != altura: | |
for i in range(tamanomatriz): | |
for j in range(tamanomatriz): | |
try: | |
gx = prewittX[i][j]*pixeles[y+j, x+i][1] | |
gy = prewittY[i][j]*pixeles[y+j, x+i][1] | |
except: | |
productosGX = 0 | |
productosGY = 0 | |
sumatoriaX = gx+sumatoriaX | |
sumatoriaY = gy+sumatoriaY | |
gxalcuadrado = pow(sumatoriaX, 2) | |
gyalcuadrado = pow(sumatoriaY, 2) | |
gradienteResultante = int(math.sqrt(gxalcuadrado+gyalcuadrado)) | |
pixelNuevo=gradienteResultante | |
if pixelNuevo> 255: | |
pixelNuevo = 255 | |
if pixelNuevo < 0: | |
pixelNuevo = 0 | |
pixeles[y,x] = ( pixelNuevo, pixelNuevo, pixelNuevo) | |
# image.save('rayitas.png', 'png') | |
# image.show() | |
#FOTO BINARISARLA | |
image = Image.open("convo1sal.png") | |
pixeles = image.load() | |
ancho, altura =image.size | |
minimoo=34 | |
for x in range(ancho): | |
for y in range(altura): | |
if pixeles[x,y][1] < minimoo: | |
prom=255 | |
else: | |
prom= 0 | |
pixeles[x,y] = (prom,prom,prom) | |
image.save('convo1convbinar.png', 'png') | |
#image.show() | |
# DIFERENCIA SE PEGO AQUI MISMO PARA EVITAR PONERMAS CUADROS DE CODIGO | |
import math | |
import sys | |
import os | |
import Image, ImageDraw, ImageFont | |
import random | |
import pygame | |
from pygame.locals import * | |
import Image | |
import math | |
import pygame | |
from pygame.locals import * | |
imagen1 = Image.open("convo1sal.png") | |
pixeles1 = imagen1.load() | |
ancho1, altura1 =imagen1.size | |
imagen2 = Image.open("convo2salcomparacion.png") | |
pixeles2 = imagen2.load() | |
ancho2, altura2 =imagen2.size | |
imagen3 = Image.new("RGB", (ancho1, altura1)) | |
pixeles3 = imagen3.load() | |
for x in range(altura1): | |
for y in range(ancho1): | |
contador = 0 | |
for i in range(-2,3): | |
for j in range(-2,3): | |
if y+a >= 0 and y+a < ancho1 and x+j >= 0 and x+j < altura1: | |
resta = abs(pixeles1[y+i,x+j][0] - pixeles2[y+i,x+j][0]) | |
if resta == 0: | |
contador= 1 | |
if contador == 1: | |
pixeles3[y,x] = (0,0,0) | |
else: | |
resta = abs(pixeles1[y,x][0] - pixeles2[y,x][0]) | |
if resta != 0: | |
pixeles3[y,x] = (255,255,255) | |
nueva.save("diferencia.jpg") | |
XXX

vv
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 math | |
import sys | |
import os | |
import Image, ImageDraw, ImageFont | |
import random | |
import pygame | |
from pygame.locals import * | |
import Image | |
import math | |
import pygame | |
from pygame.locals import * | |
fuente =ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeSansBold.ttf", 20) | |
imagen1 = Image.open("convo1sal.png") | |
pixeles = imagen1.load() | |
ancho, altura =imagen1.size | |
imagen2 = Image.open("convo2salcomparacion.png") | |
pixeles2 = imagen2.load() | |
ancho2, altura2 =imagen2.size | |
imagen3 = Image.new("RGB", (ancho, altura)) | |
pixeles3 = imagen3.load() | |
for i in range(altura): | |
for j in range(ancho): | |
if pixeles2[j,i][0] != 0: | |
if pixeles[j,i] == pixeles2[j,i]: | |
pixeles3[j,i] = (0,0,0) | |
else: | |
pixeles3[j,i] = (255,255,255) | |
else: | |
pixeles3[j,i] = (0,0,0) | |
imagen3.save("deteccion.jpg") | |
imagen1 = Image.open("deteccion.jpg") | |
pixeles = imagen1.load() | |
ancho, altura =imagen1.size | |
imagen2 = Image.open("difer.jpg") | |
pixeles2 = imagen2.load() | |
ancho2, altura2 =imagen2.size | |
imagen3 = Image.new("RGB", (ancho, altura)) | |
pixeles3 = imagen3.load() | |
draw = ImageDraw.Draw(imagen3) | |
for x in range(altura2): | |
for y in range(ancho2): | |
i = 1 | |
j = 0 | |
exit = 0 | |
if pixeles2[y,x][0] == 255: | |
while i < ancho2: | |
if y+i >= 0 and y+i < ancho-10 and x+j >= 0 and x+j < altura-10: | |
if pixeles[y+i,x][0] != 0: | |
exit = i | |
pixeles[y+i,x] = (0,0,0) | |
i = ancho2 | |
break | |
if y-i >= 0 and y-i < ancho-10 and x+j >= 0 and x+j < altura-10: | |
if pixeles[y-i,x][0] != 0: | |
exit = i | |
pixeles[y-i,x] = (0,0,0) | |
i = ancho2 | |
break | |
i += 1 | |
if exit != 0: | |
draw.line((y, x, y+ exit, x), fill=255) | |
imagen3.save("salida.jpg") |
Se divide la imagen en cuadrantes
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
def cuadrante(image, movimient, tamano = 15): | |
enX = ancho / tamano | |
enY = altura / tamano | |
cuadrado = tamano*tamano | |
pixeles = cv2_array(movimiento).copy() | |
color, h=None,1 | |
for x in range(enX): | |
for y in range(enY): | |
primerp1 = x*tamano, y*tamano | |
segundop2 = (x + 1)*tamano, (y + 1)*tamano | |
tmp = ocupados(pixeles, primerp1, segundop2) | |
Rect = (primerp1[0], primerp1[1], segundop2[0], segundop2[1]) | |
if tmp > 0: | |
h = 2 | |
color = (0, 255, 0) | |
else: | |
h = 1 | |
color = (128, 128, 128) | |
draw.line((primerp1, (segundop2[0], primerp1[1])), color, width = h) | |
draw.line(((segundop2[0], primerp1[1]), segundop2), color, width = h) | |
draw.line((segundop2, (primerp1[0], segundop2[1])), color, width = h) | |
draw.line(((primerp1[0], segundop2[1]), primerp1), color, width = h) | |
pygame.display.update() | |
return image, centrar(pixeles, (255)) |
Lo siguiente es que ya teniendo donde hubo movimiento regresamos a la segunda imagen donde ocurrió movimiento
Una ves que se conoce los pixeles donde hubo cambio y su posición , regresamos a la imagen esa
y se pinta el cuadrante de verde donde hubo movimiento de el pixel inicial al pixel final en cada frame.


Aquí arriba se muestran los resultados obtenidos, por cuestiones técnicas no se pudo descargar algún programa para grabar la pantalla ya que en FIME no lo permitía , y la que se empezó a descargar eran 11 MB pero duro cerca de media hora y aun no pasaba de la mitad de carga, mas tarde si se puede conseguir este programa se pondrá aquí abajo el vídeo.
Aqui ya se agrego el video ,por falta de tiempo se decidió saltarse algunos frames pero este es el video.
Gracias
8 pts para el lab. Haz lo de wavelets.
ResponderEliminar