martes, 12 de febrero de 2013

Tarea 1 Clase: Detección de Bordes

En esta tarea tenemos que detectar lo que son los bordes en una imagen, para lo cual se realiza lo siguiente:


  • Primero convertimos la imagen a escala de grises
  • Le aplicamos filtro
  • Aplicamos convolución
  • Aplicamos normalización
  • Aplicamos binarización
La imagen original es:



Escala de grises: En esta parte se convierte la imagen en escala de grises.

Código
def escala_grises(self):
image = Image.open(self.o_imagen)
pixels = image.load()
ancho,alto = image.size
self.matriz = numpy.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)
self.matriz[i,j] = int(escala)
return image
view raw escala.py hosted with ❤ by GitHub
Imagen obtenida:


Le aplicamos filtro:

Para usar el filtro ya trabajamos con la imagén en escala de grises
  1. Seleccionamos los vecinos de cada uno de los pixeles
  2. Sumamos la escala de grises q le pertenece a cada pixel vecino
  3. Sacamos un promedio de la suma de lo anterior
  4. Y lo asignamos al pixel
Código:
def filtro(self):
inicio = time()
image = self.escala_grises()
pixels = image.load()
ancho, alto =image.size
lista = [-1,0,1]
for i in range(ancho):
for j in range(alto):
promedio = self.vecindad(i,j,lista,self.matriz)
pixels[i,j] = (promedio,promedio,promedio)
fin = time()
tiempo_t = fin - inicio
print "Tiempo que tardo en ejecutarse filtro = "+str(tiempo_t)+" segundos"
return image
def vecindad(self,i,j,lista,matriz):
promedio = 0
indice = 0
for x in lista:
for y in lista:
a = i+x
b = j+y
try:
if self.matriz[a,b] and (x!=a and y!=b):
promedio += self.matriz[a,b]
indice +=1
except IndexError:
pass
try:
promedio=int(promedio/indice)
return promedio
except ZeroDivisionError:
return 0
view raw filtro.py hosted with ❤ by GitHub

Imagen obtenida





Aplicamos convolución

Para aplicar convolución utilizamos el operador de sobel, aplicamos el gradiente horizontal y vertical al mismo tiempo obteniendo la magnitud del gradiente, para más información sobre este tema.

Código
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.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
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
return image
view raw con.py hosted with ❤ by GitHub
Imagen obtenida



Aplicamos normalización

Para aplicar normalización se hace de la siguiente manera:
De la imagen que nos arrojo la convolución seleccionamos el valor del pixel mas alto y mas bajo:

 r = smaximo-minimo
 prop = 255.0/r
 p =int(floor((p-minimo)*prop))
El resultado lo aplicamos al pixel

Código:
def normalizar(self,image):
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'
return image
view raw nor.py hosted with ❤ by GitHub
Imagen obtenida







Aplicamos binarización

Le damos al programa un valor el cual ayudara a binarizar la imagen, por ejemplo valor=34
si el velor del pixel es mayor al valor 34 el pixel se hace blanco si es menor el pixel se hace negro.

Código:
def binarizar(self,img):
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)
return img
view raw binarizar.py hosted with ❤ by GitHub
Imagen obtenida





Tiempo que tardo en ejecutarse escala de grises = 1.02590990067 segundos
Tiempo que tardo en ejecutarse filtro = 2.71544289589 segundos
Tiempo que tardo en ejecutarse convolucion = 2.23032712936 segundos
Tiempo que tardo en ejecutarse normalizar = 2.07841897011 segundos
Tiempo que tardo en ejecutarse binzarizar = 0.44579911232 segundos


1 comentario: