lunes, 11 de febrero de 2013

Detección de bordes

Lo primero que hay que hacer para poder detectar los bordes de las imágenes es convertir la imágen a escala de grises, la normalice, después les comencé a aplicar lás máscaras. La primera máscara que apliqué fue la de sobel horizontal y vertical después la de Prewitt 45°. Y por último la binarización. En la segunda imágen aplique algunos filtros en repetidas ocasiones.

Y las imágenes se ven así:


Original


 Resultado de máscaras



Binarización


Original

Resultado de máscaras


Binarización



Original



 Resultado de máscaras



Binarización



Tiempos de ejecución de 30 repeticiones (con numpy todo se hacia más lento)
Primera imágen -> 14.25 segundos
Segunda imágen -> 6.33 segundos
Tercera imágen -> 6.20 segundos

Código completo
#!/usr/bin/python
from Tkinter import *
from PIL import Image, ImageTk
import math
import sys
def convolucion(imagen_original, mascara):
x, y = imagen_original.size
pos = imagen_original.load()
nueva_imagen = Image.new("RGB", (x,y))
pos_nueva = nueva_imagen.load()
for i in range(x):
for j in range(y):
total = 0
for n in range(i-1, i+2):
for m in range(j-1, j+2):
if n >= 0 and m >= 0 and n < x and m < y:
total += mascara[n - (i - 1)][ m - (j - 1)] * pos[n, m][0]
pos_nueva[i, j] = (total, total, total)
nueva_imagen.save("mascara.png")
return nueva_imagen
def umbral(imagen_original):
x, y = imagen_original.size
imagen_umbral = Image.new("RGB", (x, y))
pixeles = []
for a in range(y):
for b in range(x):
color = imagen_original.getpixel((b,a))[0]
if color > 80:
color = 255
else:
color = 0
data = (color, color, color)
pixeles.append(data)
imagen_umbral.putdata(pixeles)
imagen_umbral.save("imagen_umbral.png", quality=100)
return imagen_umbral
def hacer_gris(imagen_original):
"""pone la foto en escala de grises
toma el valor maximo del rgb de cada pixel
"""
x, y = imagen_original.size
imagen_gris = Image.new("RGB", (x,y))
pixeles = []
for a in range(y):
for b in range(x):
r, g, b = imagen_original.getpixel((b, a))
rgb = (r, g, b)
#se elige el valor mas grande
maximo = max(rgb)
data = (maximo, maximo, maximo)
pixeles.append(data)
imagen_gris.putdata(pixeles)
imagen_gris.save("imagen_gris.png")
return imagen_gris
def hacer_difusa(imagen_original):
"""funcion que se encarga de tomar de cada pixel los pixeles
de izq, derecha, arriba, abajo y el mismo y los promedia, y ese
promedio es el valor de los nuevos pixeles
"""
x, y = imagen_original.size
imagen_difusa = Image.new("RGB", (x, y))
pixeles = []
#temp sirve para obtener el promedio de los
#pixeles contiguos
temp = []
for a in range(y):
for b in range(x):
actual = imagen_original.getpixel((b, a))[0]
if b>0 and b<(x-1) and a>0 and a<(y-1):
#en esta condicion entran todos los pixeles que no estan
#en el margen de la imagen, es decir casi todos
pix_izq = imagen_original.getpixel((b-1, a))[0]
pix_der = imagen_original.getpixel((b+1, a))[0]
pix_arriba = imagen_original.getpixel((b, a+1))[0]
pix_abajo = imagen_original.getpixel((b, a-1))[0]
temp.append(pix_izq)
temp.append(pix_der)
temp.append(pix_arriba)
temp.append(pix_abajo)
else:
#aqui entran todos los pixeles de la orilla
try:
pix_abajo = imagen_original.getpixel((b, a-1))[0]
temp.append(pix_abajo)
except:
pass
try:
pix_der = imagen_original.getpixel((b+1, a))[0]
temp.append(pix_der)
except:
pass
try:
pix_izq = imagen_original.getpixel((b-1, a))[0]
temp.append(pix_izq)
except:
pass
try:
pix_arriba = imagen_original.getpixel((b, a+1))[0]
temp.append(pix_arriba)
except:
pass
temp.append(actual)
#se obtiene el promedio para cambiar el pixel
prom = sum(temp)/len(temp)
temp = []
pixeles.append((prom, prom, prom))
imagen_difusa.putdata(pixeles)
imagen_difusa.save("imagen_difusa.png")
return imagen_difusa
def normalizar(imagen_original):
x, y = imagen_original.size
imagen_normalizada = Image.new("RGB", (x, y))
pixeles = []
for a in range(y):
for b in range(x):
pix = imagen_original.getpixel((b, a))[0]
pixeles.append(pix)
maximo = max(pixeles)
minimo = min(pixeles)
print maximo
print minimo
l = 256.0/(maximo - minimo)
pixeles = []
for a in range(y):
for b in range(x):
pix = imagen_original.getpixel((b, a))[0]
nuevo_pix = int(math.floor((pix-minimo)*l))
pixeles.append((nuevo_pix, nuevo_pix, nuevo_pix))
imagen_normalizada.putdata(pixeles)
imagen_normalizada.save("imagen_normalizada.png")
return imagen_normalizada
def main():
"""funcion principal
"""
try:
imagen_path = sys.argv[1]
print imagen_path
imagen_original = Image.open(imagen_path)
imagen_original = imagen_original.convert('RGB')
except:
print "No seleccionaste una imagen"
return
imagen_gris = hacer_gris(imagen_original)
nueva = normalizar(imagen_gris)
mascara1 = [[-1,0,1],[-2,0,2],[-1,0,1]]
mascara2 = [[1,1,1],[0,0,0],[-1,-1,-1]]
mascara3 = [[1,1,1],[-1,-2,1],[-1,-1,1]]
mascara4 = [[-1,1,1],[-1,-2,1],[-1,1,1]]
nueva = convolucion(nueva, mascara1)
nueva.save("mascara1.png")
nueva = convolucion(nueva, mascara2)
nueva.save("mascara2.png")
nueva = convolucion(nueva, mascara3)
nueva.save("mascara3.png")
nueva = convolucion(nueva, mascara4)
nueva.save("mascara4.png")
nueva = hacer_difusa(nueva)
nueva = umbral(nueva)
if __name__ == "__main__":
main()
view raw gistfile1.py hosted with ❤ by GitHub

1 comentario: