lunes, 11 de febrero de 2013

Tarea 1: detección de bordes.

Para la tarea uno, hice un programa en Python en el cual utilizando numpy y una serie de pasos, pude detectar los bordes de una imagen, se nos pide documentar el código y tres imágenes en donde pongamos la original y la procesada, al igual que el tiempo de ejecución al hacer 30 repeticiones de cada imagen.

Código.

from Tkinter import *
from PIL import Image, ImageTk
from math import floor
import time
import numpy
def ventana():
#GUI de la aplicacion
root = Tk()
root.title('Bordes')
frame = Frame()
frame.pack(padx=5,pady=5)
poner_imagen(obtener_original(path_imagen_original))
b1 = Button(text='Original', command = boton_original).pack(in_=frame, side=LEFT)
b2 = Button(text='Detectar bordes', command = boton_bordes).pack(in_=frame, side=LEFT)
b1 = Button(text='Prueba tiempo', command = boton_prueba).pack(in_=frame, side=LEFT)
root.mainloop()
def poner_imagen(image):
#Carga imagen en ventana
photo = ImageTk.PhotoImage(image)
global label
label = Label(image=photo)
label.imagen = photo
label.pack()
def cambiar_agrises(path_original):
#Pone a grises la imagen
imagen = Image.open(path_imagen_original).convert("RGB")
pixeles = imagen.load()
x, y = imagen.size
imagen_nueva = Image.new("RGB", (x, y))
colores = []
for a in range(x):
for b in range(y):
pixel_color = pixeles[a, b]
promedio = sum(pixel_color)/3
tupla_promedio = (promedio, promedio, promedio)
colores.append(tupla_promedio)
imagen_nueva.putpixel((a, b), tupla_promedio)
return imagen_nueva
def convolucion(f, h):
#calculo de convolucion de las mascaras
pixeles = f.load()
x, y = f.size
F = Image.new("RGB", (x, y))
i = len(h[0])
j = len(h[0])
for a in range(x):
for b in range(y):
suma = 0
for c in range(i):
c1 = c - i/2
for d in range(j):
d1 = d - j/2
try:
suma = suma + (pixeles[a+c1, b+d1][0])*(h[c][d])
except:
pass
suma = int(floor(suma))
tupla_promedio = (suma, suma, suma)
F.putpixel((a,b),tupla_promedio)
return F
def cambiar_promedio(imagen):
#efecto borrado
pixeles = imagen.load()
x, y = imagen.size
imagen_nueva_prom = Image.new("RGB", (x, y))
colores = []
for a in range(x):
for b in range(y):
pixel_color = pixeles[a, b]
veces = 5
suma = 0
promedio = 0
try:
pixel_norte = pixeles[a-1,b]
except IndexError:
pixel_norte = (0, 0, 0)
veces = veces - 1
try:
pixel_sur = pixeles[a+1, b]
except IndexError:
pixel_sur = (0, 0, 0)
veces = veces - 1
try:
pixel_este = pixeles[a, b+1]
except IndexError:
pixel_este = (0, 0, 0)
veces = veces - 1
try:
pixel_oeste = pixeles[a, b-1]
except IndexError:
pixel_oeste = (0, 0, 0)
veces = veces - 1
Rojos_suma = pixel_norte[0] + pixel_sur[0] + pixel_este[0] + pixel_oeste[0] + pixel_color[0]
Verdes_suma = pixel_norte[1]+ pixel_sur[1] + pixel_este[1] + pixel_oeste[1] + pixel_color[1]
Azul_suma = pixel_norte[2]+ pixel_sur[2] + pixel_este[2] + pixel_oeste[2] + pixel_color[2]
Rojo_prom = Rojos_suma/veces
Verdes_prom = Verdes_suma/veces
Azul_prom = Azul_suma/veces
tupla_promedio = (Rojo_prom, Verdes_prom, Azul_prom)
colores.append(tupla_promedio)
imagen_nueva_prom.putpixel((a, b), tupla_promedio)
return imagen_nueva_prom
def normalizacion(imagen):
#normaliza utilizando todo el rango
pixeles = imagen.load()
x, y = imagen.size
min = 0
max = 0
imagen_nueva = Image.new("RGB", (x, y))
for a in range(x):
for b in range(y):
pixel_color = pixeles[a, b]
max_ant = max
max_new = pixel_color[0]
min_ant = min
min_new = pixel_color[0]
if (max_new >= max_ant):
max = max_new
elif (min_new <= min_ant):
min = min_new
elif (min == 0 and max == 255):
break
print min
print max
for a in range(x):
for b in range(y):
pixel_color = pixeles[a, b]
nuevo_pixel = ( float(pixel_color[0]) - float(min) )*( float(255) / (float(max) - float(min)) )
nuevo_pixel = int(floor(nuevo_pixel))
tupla_promedio = (nuevo_pixel, nuevo_pixel, nuevo_pixel)
imagen_nueva.putpixel((a, b), tupla_promedio)
return imagen_nueva
def cambiar_umbral(imagen, umbral_valor):
#dado un umbral pone en completamente blanco o negro
pixeles = imagen.load()
x, y = imagen.size
imagen_nueva = Image.new("RGB", (x, y))
for a in range(x):
for b in range(y):
pixel_color = pixeles[a, b]
valor_canal = float(pixel_color[0])
color_nor = valor_canal/255.0
if(color_nor>=umbral_valor):
poner_pixel = 255
else:
poner_pixel = 0
tupla_pixel = (poner_pixel, poner_pixel, poner_pixel)
imagen_nueva.putpixel((a, b), tupla_pixel)
return imagen_nueva
def obtener_original(path_imagen_original):
#cargar imagen original
imagen = Image.open(path_imagen_original)
return imagen
def boton_bordes():
inicio = time.time()
label.destroy()
#A grises
imagen_grises = cambiar_agrises(path_imagen_original)
imagen_grises.save("paso_1.jpg")
#Aplico mascara Sobel a 0 grados
h = numpy.array([[-1,0,1],[-2,0,2],[-1,0,1]])
imagen_con = convolucion(imagen_grises, h)
imagen_con.save("paso_2.jpg")
#Aplico mascara Sobel a 45 grados
h = numpy.array([[1,2,1],[0,0,0],[-1,-2,-1]])
imagen_con2 = convolucion(imagen_con, h)
imagen_con2.save("paso_3.jpg")
#Aplico gradiente horizontal
h_hori = numpy.array([[-1, -2, -1],[0, 0, 0], [1, 2, 1]])
imagen_con3 = convolucion(imagen_con2, h_hori)
imagen_con3.save("paso_4.jpg")
#Aplico gradiente vertical
h_verti = numpy.array([[-1, 0, 1],[-2, 0, 2],[-1, 0, 1]])
imagen_con4 = convolucion(imagen_con3, h_verti)
imagen_con4.save("paso_5.jpg")
#Normalizo la imagen
imagen_nor = normalizacion(imagen_con3)
imagen_nor.save("paso_6.jpg")
#Binarizo (umbral 0.5)
umbral_valor = 0.5
imagen_bin = cambiar_umbral(imagen_nor.convert("RGB"), umbral_valor)
imagen_bin.save("paso_7.jpg")
#Hace promedio
imagen_final1 = cambiar_promedio(imagen_bin.convert("RGB"))
imagen_final2 = cambiar_promedio(imagen_final1.convert("RGB"))
imagen_final2.save("paso_8.jpg")
#Pone en ventana
poner_imagen(imagen_final2)
#Tiempo
fin = time.time()
tiempo = fin - inicio
print "Tiempo que trascurrio -> " + str(tiempo)
return tiempo
def boton_original():
#carga imagen original
label.destroy()
imagen_original = obtener_original(path_imagen_original)
poner_imagen(imagen_original)
def boton_prueba():
#hace prueba de tiempo
tiempo = 0.0
for i in range(30):
tiempo = tiempo + boton_bordes()
promedio = tiempo / 30.0
print "Tiempo promedio de " + path_imagen_original + " es = " + str(promedio)
path_imagen_original = "fruta.jpg"
ventana()

Imágenes.



























Utilizando pasos intermedios.

  1. A grises.
  2. Máscara Sobel 0 grados.
  3. Máscara Sobel 45 grados.
  4. Máscara gradiente horizontal.
  5. Máscara gradiente vertical.
  6. Normalizar.
  7. Binarizar Umbral 0.5.
  8. Efecto borrado.







Tiempos generados en la prueba.




  • torre.jpg
    • 980 x 1470
    • 545,487 bytes
    • 326.35 seg

  • fruta.jpg
    • 1280 x 800
    • 303,806 bytes
    • 229.98 seg

  • woody.jpg
    • 640 × 960
    • 174,715 bytes
    • 174.21 seg

Como podemos ver tardó más tiempo en hacer la cantidad de bytes y pixeles que contiene cada imagen, por lo que entre más grande, más tiempo de cálculo.

Esto sería todo sobre la tarea 1 de la clase de visión computacional, cualquier duda o comentario favor hacérmelo saber.



    1 comentario: