Laboratorio 2 - Ruido sal y pimienta, normalización y binarización
Hola, en esta entrada voy a presentar el trabajo realizado para el laboratorio 2 de Visión computacional.
Lo primero (obligatorio) que hice fue generar ruido de sal y pimienta en imágenes a colores, la manera en la que puse los puntos blancos y negros sobre la imagen fue muy sencilla. Cuando ejecuto el python, paso como parámetro 2 valores, el primero es la intensidad (ruido a generar en la imagen), y luego la polarización (que tan blancos o negros van a ser las sales y pimientas). El valor de la intensidad lo pongo dentro de un random para que la probabilidad en que salgan puntos (ya sea blancos o negros) dependan del valor dado.
Luego el valor de la polarización lo determino mediante condicionales, para ver que tan negros o blancos pongo los ruidos, tomando en cuenta que el valor 0 corresponde a negro y el valor 255 corresponde a blanco, con el valor leido de polarización solo vario entre esos 2 números.
Bueno, aquí muestro la subrutina con la que realicé el ruido:
def salPimienta(): # Subrutina para poner sal y pimienta a la imagen binarizada #tiempoInicial = time.time() i = 0 x = 0 y = 0 #Valores para instensidad y polarizacion respectivamente intensidad = int(argv[1]) # Nivel de pixeles (cantidades) polarizacion = int(argv[2]) # Que tan negros y blancos son los puntos en porcentaje... donde 0 es negro y 255 es blanco im = Image.open("bla.jpg") pix = im.load() for x in xrange(im.size[0]): for y in xrange(im.size[1]): #pix = im.load() tupla = pix[x, y] azar = int(random.randint(0,intensidad)) if azar == 9: #Aqui podria ser perfectamente cualquier numero (no necesariamente 9), seria la misma probabilidad: 1/intensidad if polarizacion > 25 and polarizacion < 75: a = 128 + 64 b = 128 + 64 # Para puntos "blancos" c = 128 + 64 # Fabricando la nueva tupla tupla1 = (a, b, c) # Poniendo pixel im.putpixel((x, y), tupla1) elif polarizacion >= 75: a = 255 b = 255 # Para puntos "blancos" c = 255 # Fabricando la nueva tupla tupla1 = (a, b, c) #Poniendo pixel im.putpixel((x, y), tupla1) elif polarizacion <= 25: a = 128 + 20 b = 128 + 20 # Para puntos "blancos" c = 128 + 20 # Fabricando la nueva tupla tupla1 = (a, b, c) #Poniendo pixel im.putpixel((x, y), tupla1) elif azar == 7: if polarizacion > 25 and polarizacion < 75: d = 128 - 64 e = 128 - 64 # Para puntos "negros" f = 128 - 64 tupla2 = (d, e, f) im.putpixel((x, y), tupla2) elif polarizacion >= 75: d = 0 e = 0 # Para puntos "negros" f = 0 tupla2 = (d, e, f) im.putpixel((x, y), tupla2) elif polarizacion <= 25: d = 128 - 20 e = 128 - 20 # Para puntos "negros" f = 128 - 20 tupla2 = (d, e, f) im.putpixel((x, y), tupla2) else: a = tupla[0] b = tupla[1] c = tupla[2] newTupla = (a,b,c) im.putpixel((x, y), newTupla) #print tupla, "--", a,",",b,",",c im.save('meh6.jpg') #tiempoFinal = time.time() #transcurso = tiempoFinal - tiempoInicial #print "Tiempo de escala de grises = ", transcurso
Ahora les muestro imágenes con distintos niveles de intensidad y polarización:
(Intensidad 60%, polarización 50%)
(Intensidad 90%, polarización 100%)
(Intensidad 60%, polarización 50%)
(Intensidad 90%, polarización 100%)
Ahora para quitar ese ruido generado hice otra subrutina, que lo que hace es compara pixel por pixel de la imagen, cuando detecta que el pixel es blanco o negro, genera un promedio con los valores de pixeles de los vecinos, seguido de eso el promedio obtenido se lo asigna al pixel en el que está posicionado.
A continuación les muestro la subrutina que realiza este proceso:
def quitarSalPimienta(): i = 0 x = 0 y = 0 im = Image.open("meh6.jpg") pix = im.load() width, height = im.size promedio = 0 width = width-1 height = height-1 #x = j y y = i for x in range(height): for y in range(width): tupla = pix[y, x] pR = tupla[0] pG = tupla[1] pB = tupla[2] print tupla #if (pB == 0 or pR == 255): if (pR >= 240 or pG >= 240 or pB >= 240) or (pR <=10 or pG <=10 or pB <=10): #esquina superior izquierda if y == 0 and x == 0: #promedio = (sum(pix[y + 1,x])/3 + sum(pix[y,x + 1])/3 + sum(pix[y,x])/3)/3 promedio1 = (pix[y + 1,x][0] + pix[y,x + 1][0])/2 promedio2 = (pix[y + 1,x][1] + pix[y,x + 1][1])/2 promedio3 = (pix[y + 1,x][2] + pix[y,x + 1][2])/2 #esquina superior derecha if y == width and x == 0: #promedio = (sum(pix[y,x+1])/3 + sum(pix[y-1,x])/3 + sum(pix[y,x])/3)/3 promedio1 = (pix[y,x+1][0] + pix[y-1,x][0])/2 promedio2 = (pix[y,x+1][1] + pix[y-1,x][1])/2 promedio3 = (pix[y,x+1][2] + pix[y-1,x][2])/2 if y == 0 and x == height: #promedio = (sum(pix[y,x-1])/3 + sum(pix[y+1,x])/3 + sum(pix[y,x])/3)/3 promedio1 = (pix[y,x-1][0] + pix[y+1,x][0])/2 promedio2 = (pix[y,x-1][1] + pix[y+1,x][1])/2 promedio3 = (pix[y,x-1][2] + pix[y+1,x][2])/2 if y == height and x == width: #promedio = (sum(pix[y - 1,x])/3 + sum(pix[y,x - 1])/3 + sum(pix[y,x])/3)/3 promedio1 = (pix[y - 1,x][0] + pix[y,x - 1][0])/2 promedio2 = (pix[y - 1,x][1] + pix[y,x - 1][1])/2 promedio3 = (pix[y - 1,x][2] + pix[y,x - 1][2])/2 if y > 0 and y < width and x == 0: #promedio = (sum(pix[y+1,x])/3 + sum(pix[y-1,x])/3 +sum(pix[y,x+1])/3+ sum(pix[y,x])/3)/4 promedio1 = (pix[y+1,x][0] + pix[y-1,x][0] + pix[y,x+1][0])/3 promedio2 = (pix[y+1,x][1] + pix[y-1,x][1] + pix[y,x+1][1])/3 promedio3 = (pix[y+1,x][2] + pix[y-1,x][2] + pix[y,x+1][2])/3 if y > 0 and y < width and x == height: #promedio = (sum(pix[y -1,x])/3 + sum(pix[y,x-1])/3 +sum(pix[y+1,x])/3+ sum(pix[y,x])/3)/4 promedio1 = (pix[y -1,x][0] + pix[y,x-1][0] + pix[y+1,x][0])/3 promedio2 = (pix[y -1,x][1] + pix[y,x-1][1] + pix[y+1,x][1])/3 promedio3 = (pix[y -1,x][2] + pix[y,x-1][2] + pix[y+1,x][2])/3 if x >0 and x0 and x < height: #promedio = (sum(pix[y - 1,x])/3 + sum(pix[y,x-1])/3 + sum(pix[y,x +1])/3+ sum(pix[y,x])/3)/4 promedio1 = (pix[y - 1,x][0] + pix[y,x-1][0] + pix[y,x +1][0])/3 promedio2 = (pix[y - 1,x][1] + pix[y,x-1][1] + pix[y,x +1][1])/3 promedio3 = (pix[y - 1,x][2] + pix[y,x-1][2] + pix[y,x +1][2])/3 if y > 0 and y< width and x>0 and x< height: #promedio = (sum(pix[y,x])/3 + sum(pix[y + 1,x])/3 + sum(pix[y - 1,x])/3 + sum(pix[y,x + 1])/3 + sum(pix[y,x -1])/3)/5 promedio1 = (pix[y + 1,x][0] + pix[y - 1,x][0] + pix[y,x + 1][0] + pix[y,x -1][0])/4 promedio2 = (pix[y + 1,x][1] + pix[y - 1,x][1] + pix[y,x + 1][1] + pix[y,x -1][1])/4 promedio3 = (pix[y + 1,x][2] + pix[y - 1,x][2] + pix[y,x + 1][2] + pix[y,x -1][2])/4 #----------------------------- #tupla = pix[x, y] a = promedio1 b = promedio2 c = promedio3 miTupla = (a,b,c) #Eso no es una tupla, pero asi le digo yo :P im.putpixel((y, x), miTupla) #Esto si es una tupla #pix[y, x] = (a,b,c) else: tuplaOriginal = (pR, pG, pB) #Esto tampoco es una tupla, pero asi le digo yo :P im.putpixel((y, x), tuplaOriginal) #Esto si es una tupla XD ''' newTupla = (prom,prom,prom) im.putpixel((x, y), newTupla) ''' #print tupla, "--", a,",",b,",",c im.save('meh7.jpg')
Ahora les muestro imágenes con ruido generado comparadas con las imágenes después de pasar por el fitro que limpia el ruido:
Normalización y binarización
Bien, para los puntos extra, hice una imagen difusa, luego realicé la diferencia entre la imagen original y la difusa y al final realicé la normalizacion y binarización.
Los métodos para realizar estos filtros los describí en el post anterior (Tarea 1), pero aquí explico superficialmente que la difusa la realicé con los promedios de los vecinos que se van visitando en cada pixel, la diferencia es tan solo una resta entre los valores de los pixeles que componen la imagen original y la imagen difusa. La normalización y binarización se realizan tan solo poniendo umbrales y comparando que tan oscuros o claros son los valores de los pixeles, para luego ponerlos en una categoría de blanco o negro (0 o 255).
A continuación les muestro la subrutina del proceso de difusa:
def filtrada(): #Filtrada por el metodo de los vecinos #tiempoInicial = time.time() i = 0 x = 0 y = 0 im = Image.open("meh.jpg") width, height = im.size pix = im.load() promedio = 0 width = width-1 height = height-1 #x = j y y = i for x in range(height): for y in range(width): #esquina superior izquierda if y == 0 and x == 0: promedio = (sum(pix[y + 1,x])/3 + sum(pix[y,x + 1])/3 + sum(pix[y,x])/3)/3 #esquina superior derecha if y == width and x == 0: promedio = (sum(pix[y,x+1])/3 + sum(pix[y-1,x])/3 + sum(pix[y,x])/3)/3 if y == 0 and x == height: promedio = (sum(pix[y,x-1])/3 + sum(pix[y+1,x])/3 + sum(pix[y,x])/3)/3 if y == height and x == width: promedio = (sum(pix[y - 1,x])/3 + sum(pix[y,x - 1])/3 + sum(pix[y,x])/3)/3 if y > 0 and y < width and x == 0: promedio = (sum(pix[y+1,x])/3 + sum(pix[y-1,x])/3 +sum(pix[y,x+1])/3+ sum(pix[y,x])/3)/4 if y > 0 and y < width and x == height: promedio = (sum(pix[y -1,x])/3 + sum(pix[y,x-1])/3 +sum(pix[y+1,x])/3+ sum(pix[y,x])/3)/4 if x >0 and x0 and x < height: promedio = (sum(pix[y - 1,x])/3 + sum(pix[y,x-1])/3 + sum(pix[y,x +1])/3+ sum(pix[y,x])/3)/4 if y > 0 and y< width and x>0 and x< height: promedio = (sum(pix[y,x])/3 + sum(pix[y + 1,x])/3 + sum(pix[y - 1,x])/3 + sum(pix[y,x + 1])/3 + sum(pix[y,x -1])/3)/5 #----------------------------- #tupla = pix[x, y] a = promedio b = promedio c = promedio ''' a = tupla[0] b = tupla[1] c = tupla[2] ''' #prom = int((a+b+c)/3) pix[y, x] = (a,b,c) #tup = pix[] #im.putpixel((y, y), pix) #print tupla, "--", a,",",b,",",c im.save('meh2.jpg') #tiempoFinal = time.time() #transcurso = tiempoFinal - tiempoInicial #print "Tiempo transcurrido durante la filtracion = ", transcurso
Luego la diferencia y la binarización:
def diferencia(): #O normalizacion #tiempoInicial = time.time() imagen1 = Image.open("meh.jpg") imagen2 = Image.open("meh2.jpg") width, height = imagen1.size pix = imagen1.load() pix2 = imagen2.load() for y in range(width): for x in range(height): (a,b,c) = pix[y, x] (d,e,f) = pix2[y, x] promedio = a+b+c/3 promedio1 = d+e+f/3 promedio2 = promedio - promedio1 if promedio2 > 115: promedio2 = 255 else: promedio2 = 0 a = promedio2 b = promedio2 c = promedio2 pix[y, x] = (a,b,c) imagen1.save("meh3.jpg") #tiempoFinal = time.time() #transcurso = tiempoFinal - tiempoInicial #print "Tiempo transcurrido durante la normalizacion = ", transcurrido
Subrutina para binarización:
def umbrales(): #tiempoInicial = time.time() i = 0 x = 0 y = 0 umbInferior = 77 umbSuperior = 177 im = Image.open("meh4.jpg") for x in xrange(im.size[0]): for y in xrange(im.size[1]): pix = im.load() tupla = pix[x, y] a = tupla[0] b = tupla[1] c = tupla[2] prom = int((a+b+c)/3) if prom < umbInferior: prom = 0 elif prom >= umbSuperior: prom = 255 newTupla = (prom,prom,prom) im.putpixel((x, y), newTupla) #print tupla, "--", a,",",b,",",c im.save('meh5.jpg') #tiempoFinal = time.time() #transcurrido = tiempoFinal - tiempoInicial #print "Tiempo transcurrido durante la binarizacion = ", transcurrido
Ya por último les muestro las imágenes después de pasar por todos los procesos antes mencionados:
(Original)
(Escala de grises)
(Difusa)
(Diferencia)
(Binarización)
Git sobre todo el trabajo realizado hasta ahora: https://github.com/eddypre/VisionTriana
Cualquier duda o aclaración pueden dejarla en comentarios.
Saludos a todos!
Bien, 10 puntos.
ResponderEliminar