Para esta tarea, se nos pidió aplicar una máscara de convolución a una matriz de pixeles de la imagen.
Por ejemplo, en la siguiente imagen podemos ver como se toma un pixel central (borde rojo) y el área de acción del kernel que son los vecinos (borde verde). El cuadro del medio muestra la máscara(kernel) que se le aplicará a la matriz de pixeles de nuestra imagen y el último cuadro muestra el resultado de la multiplicación de estas dos anteriores, es decir se multiplica el valor de cada uno de ellos por el valor correspondiente del kernel y se hace una sumatoria de los resultados
En este caso por ejemplo sería: (40*0)+(42*1)+(46*0) + (46*0)+(50*0)+(55*0) + (52*0)+(56*0)+(58*0) = 42
El procedimiento que realicé para esta tarea fue el siguiente: Por ejemplo, en la siguiente imagen podemos ver como se toma un pixel central (borde rojo) y el área de acción del kernel que son los vecinos (borde verde). El cuadro del medio muestra la máscara(kernel) que se le aplicará a la matriz de pixeles de nuestra imagen y el último cuadro muestra el resultado de la multiplicación de estas dos anteriores, es decir se multiplica el valor de cada uno de ellos por el valor correspondiente del kernel y se hace una sumatoria de los resultados
En este caso por ejemplo sería: (40*0)+(42*1)+(46*0) + (46*0)+(50*0)+(55*0) + (52*0)+(56*0)+(58*0) = 42
1.- Convertí la imagen original en escala de grises con la subrutina que ya había hecho para el laboratorio.
2.- Apliqué la máscara Sobel horizontal y vertical para la detección de bordes
3.- Normalicé la imagen
4.- Realicé la binarización
Imagenes resultantes:
Original
Escala de grises
Máscara
Binarizado
Original
Escala de grises
Máscara
Binarizado
Original
Escala de grises
Máscara
Binarizado
Los tiempos promedio que tomaron estás imagenes para realizar este procedimiento son:
- Primera imagen "Taz bebe": 321 x 394 pixeles tardó 4.13 segundos
- Segunda imagen "Google": 543 x 378 pixeles tardó 6.94 segundos
- Tercera imagen "Persona": 605 x 792 pixeles tardó 14.9 segundos
Código:
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
from PIL import Image | |
from sys import argv | |
from math import floor | |
import numpy | |
import Image | |
import time | |
umbral = 100 | |
n_img = argv[1] | |
img = Image.open('/home/carmensrz/'+ n_img) | |
#tamaño de la imagen | |
width, height = img.size | |
#funcion para realizar el efecto de escala de grises | |
def grayscale(img): | |
imagen = img.convert("RGB") | |
new_image = Image.new("RGB",(width,height)) | |
for i in range(width): | |
for j in range(height): | |
r,g,b = imagen.getpixel((i,j)) | |
average = int(floor((r+g+b)/3)) | |
#print r,g,b, average | |
new_image.putpixel((i,j),(average,average,average)) | |
return new_image | |
#funcion para filtro de convolucion, deteccion de bordes | |
def convolucion(new_image, h): | |
pix = new_image.load() | |
F = Image.new("RGB",(width,height)) | |
k = len(h[0]) | |
for x in range(width): | |
for y in range(height): | |
suma = 0 | |
for i in range(k): | |
#centrar la mascara | |
z1 = (i - (k/2)) | |
for j in range(k): | |
#centrar la mascara en la imagen | |
z2 = (j - (k/2)) | |
#sin centrar z1=i z2=j | |
try: | |
suma += pix[x+z1,y+z2][0] * h[i][j] | |
except: | |
pass | |
suma = int(floor(suma)) | |
F.putpixel((x,y),(suma,suma,suma)) | |
return F | |
def b_w(imagen): | |
new_image = Image.new("RGB",(width,height)) | |
for i in range(width): | |
for j in range(height): | |
r,g,b = imagen.getpixel((i,j)) | |
mayor = max(r,g,b) | |
if(mayor<umbral): | |
color = 0 | |
else: | |
color = 255 | |
new_image.putpixel((i,j),(color,color,color)) | |
#img.save('byn_'+imagen) | |
return new_image | |
def normalizar(imagen): | |
pix = imagen.load() | |
imagen_norm = Image.new("RGB",(width,height)) | |
max = 0 | |
min = 0 | |
for i in range(width): | |
for j in range(height): | |
px = pix[i,j] | |
mayor = max | |
menor = min | |
n_max = px[0] | |
n_men = px[0] | |
if n_max >= mayor: | |
max = n_max | |
if n_men <= menor: | |
min = n_men | |
print min, max | |
prop = 256/(max-min) | |
print prop | |
for i in range(width): | |
for j in range(height): | |
r,g,b = imagen.getpixel((i,j)) | |
new_px = int(floor((g-min)*prop)) | |
imagen_norm.putpixel((i,j),(new_px,new_px,new_px)) | |
#img.save("norm_" + imagen) | |
return imagen_norm | |
def main(): | |
start = time.time() | |
grises = grayscale(img) | |
grises.save("Imagen1.jpg") | |
#Aplicar mascara | |
sx = [[-1,0,1],[-2,0,2],[-1,0,1]] #Sobel horizontal | |
sy = [[1,2,1],[0,0,0],[-1,-2,-1]] #Sobel vertical | |
#h = [[-1,1,1],[-1,-1,1],[-1,1,1]] #Prewit | |
conv_gx = convolucion(grises,sx) | |
conv_gx.save("Imagen2.jpg") | |
conv_gy = convolucion(conv_gx,sy) | |
conv_gy.save("Imagen3.jpg") | |
i_norm = normalizar(conv_gy) | |
i_norm.save("Imagen4.jpg") | |
imagen_f = b_w(i_norm) | |
imagen_f.save("Imagen5.jpg") | |
fin = time.time() | |
tiempo = fin - start | |
print "Tiempo total: "+ str(tiempo) | |
if __name__ == '__main__': | |
main() |
Liga a mi repositorio
https://github.com/carmensrz/VisionComputacional
Tendrás que trabajar un rato para que te salgan contínuos los bordes. 5 pts por la primera tarea.
ResponderEliminar