Loading [MathJax]/extensions/TeX/AMSsymbols.js

13 de febrero de 2013

Actividad 2: Ruido Sal y Pimienta

Laboratorio de Visión Computacional
Actividad 2

La actividad para esta semana fue crear una rutina para generar el ruido sal y pimienta en imágenes para luego crear una rutina que eliminara este ruido de las imágenes.

¿Qué es el ruido sal y pimienta?

"En el tipo de ruido conocido como ruido sal y pimienta los pixeles de la imagen son muy diferentes en color o intensidad a los pixeles circundantes. El hecho que define este tipo de ruido es que el pixel ruidoso en cuestión no tiene relación alguna con los pixeles circundantes." [1]

Ejemplos


Con el programa que hice probé con varias intensidades de ruido para crear las imágenes con este efecto de sal y pimienta, para luego eliminar este mismo ruido. Veamos los resultados con algunas imágenes, primero agregando el ruido sal y pimienta, y luego la imagen después de eliminar el ruido sal y pimienta.

En esta imagen apliqué una intensidad de 0.01.



En esta imagen apliqué una intensidad de 0.1.



En esta imagen apliqué una intensidad de 0.05.



En esta imagen apliqué una intensidad de 0.3.



Código para sal y pimienta


import sys, os, random, Image
def open_image(image_file_path):
image = Image.open(image_file_path)
image.thumbnail((600, 450), Image.ANTIALIAS)
return image
def get_image_size(image):
width, height = image.size
return (width, height)
def grayscale(image):
width, height = get_image_size(image)
for w in range(width):
for h in range(height):
r, g, b = image.getpixel((w, h))
gray = (r+g+b)/3
image.putpixel((w, h), (gray, gray, gray))
return image
def put_salt_and_pepper(image_file_path, intensity):
image = open_image(image_file_path)
width, height = get_image_size(image)
image = grayscale(image)
for w in range(width):
for h in range(height):
if random.random() < intensity:
if random.random() < 0.5:
image.putpixel((w, h), (0, 0, 0))
else:
image.putpixel((w, h), (255, 255, 255))
image.show()
return image
def remove_salt_and_pepper(image):
image_copy = image
width, height = get_image_size(image)
for w in range(width):
for h in range(height):
pixel = image_copy.getpixel((w, h))[0]
if pixel == 0 or pixel == 255:
pixel_list = []
try: pixel_list.append(image_copy.getpixel((w, h-1))[0])
except: pass
try: pixel_list.append(image_copy.getpixel((w, h+1))[0])
except: pass
try: pixel_list.append(image_copy.getpixel((w-1, h))[0])
except: pass
try: pixel_list.append(image_copy.getpixel((w+1, h))[0])
except: pass
try: pixel_list.append(image_copy.getpixel((w-1, h-1))[0])
except: pass
try: pixel_list.append(image_copy.getpixel((w-1, h+1))[0])
except: pass
try: pixel_list.append(image_copy.getpixel((w+1, h-1))[0])
except: pass
try: pixel_list.append(image_copy.getpixel((w+1, h+1))[0])
except: pass
pixel = sum(pixel_list)/len(pixel_list)
image.putpixel((w, h), (pixel, pixel, pixel))
image.show()
def main():
if len(sys.argv) > 2:
image_file_path = str(sys.argv[1])
intensity = float(sys.argv[2])
if os.path.isfile(image_file_path):
image = put_salt_and_pepper(image_file_path, intensity)
remove_salt_and_pepper(image)
else:
print 'Image file does not exist'
else:
print 'Missing parameters'
if __name__ == '__main__':
main()

Detección de bordes


Para la detección de bordes hemos visto que es posible hacerlo mediante la aplicación de máscaras y el método de convolución, pero ahora usamos otra técnica más simple que implica calcular la diferencia entre la imagen original y la versión creada con el filtro de difuminado.

Aquí la muestra de como se obtienen los bordes de la imagen usando el método de convolución y máscaras, del cuál ya se habló en una publicación anterior a esta.


Y ahora la misma imagen pero con una nueva técnica. Podemos ver que no es tan precisa como la anterior, pero aún así se logran diferenciar bien los bordes de la imagen.


Aquí otra muestra.


Código para detección de bordes y más


En el siguiente código están incluidos la detección de bordes por medio de convolución, detección de bordes usando diferencia de imágenes, agregar ruido sal y pimienta, y por último eliminar ruido sal y pimienta.

Recibe como parámetro en línea de comandos el nombre de una imagen. Al ejecutarlo veremos una ventana como la siguiente.


from Tkinter import *
import sys, os, random, Image, ImageTk
from filters_methods import *
class Edges:
def __init__(self, image_file_path):
self.image_file_path = image_file_path
image = self.open_image(self.image_file_path)
self.temp_image = image
self.root = Tk()
self.root.title('Edges')
self.root.resizable(width=False, height=False)
self.imagetk = self.convert_to_imagetk(image)
self.label1 = Label(self.root, image=self.imagetk)
self.label1.pack(side=LEFT)
self.button1 = Button(text='Reset', width=15,
command=self.reset_image).pack()
self.button2 = Button(text='Convolution', width=15,
command=self.action).pack()
self.button3 = Button(text='Difference', width=15,
command=self.difference).pack()
self.button4 = Button(text='Put Salt & Pepper', width=15,
command=self.put_salt_and_pepper).pack()
self.button5 = Button(text='Remove Salt & Pepper', width=15,
command=self.remove_salt_and_pepper).pack()
self.button_exit = Button(text='Exit', width=15,
command=self.root.destroy).pack()
self.root.mainloop()
def open_image(self, image_file_path):
image = Image.open(image_file_path)
image.thumbnail((600, 450), Image.ANTIALIAS)
return image
def save_image(self, image, width, height):
pixels = image.getdata()
newimage = Image.new('RGB', (width, height))
newimage.putdata(pixels)
newimage.save('output.jpg')
def convert_to_imagetk(self, image):
return ImageTk.PhotoImage(image)
def reset_image(self):
image = self.open_image(self.image_file_path)
self.update_image(image)
def update_image(self, image):
self.imagetk = self.convert_to_imagetk(image)
self.label1.config(image=self.imagetk)
self.label1.pack()
self.root.mainloop()
def action(self):
f = self.open_image(self.image_file_path)
f = grayscale(f)
h = [[0, 1, 0], [1, -4, 1], [0, 1, 0]]
image = self.convolution(h, f)
image = average_allneighbors(image)
image = binarization(image, 18)
self.update_image(image)
def convolution(self, h, f):
F = self.open_image(self.image_file_path)
width, height = get_image_size(F)
k = len(h[1])
for x in range(width):
for y in range(height):
suma = 0
for i in range(k):
z1 = i - k/2
for j in range(k):
z2 = j - k/2
try:
suma += f.getpixel((x+z1, y+z2))[0]*h[i][j]
except:
pass
suma = int(suma)
F.putpixel((x, y), (suma, suma, suma))
return F
def difference(self):
image = self.open_image(self.image_file_path)
width, height = get_image_size(image)
image_original = self.open_image(self.image_file_path)
image_original = grayscale(image_original)
image_filtrada = self.open_image(self.image_file_path)
image_filtrada = grayscale(image_filtrada)
image_filtrada = average_allneighbors(image_filtrada)
for w in range(width):
for h in range(height):
r1, g1, b1 = image_filtrada.getpixel((w, h))
r2, g2, b2 = image_original.getpixel((w, h))
dif = int(abs(r2 - r1))
image.putpixel((w, h), (dif, dif, dif))
image = binarization(image, 18)
self.update_image(image)
def put_salt_and_pepper(self):
intensity = 0.05
image = self.open_image(self.image_file_path)
width, height = get_image_size(image)
image = grayscale(image)
for w in range(width):
for h in range(height):
if random.random() < intensity:
if random.random() < 0.5:
image.putpixel((w, h), (0, 0, 0))
else:
image.putpixel((w, h), (255, 255, 255))
self.save_image(image, width, height)
self.temp_image = image
self.update_image(image)
def remove_salt_and_pepper(self):
image_copy = self.temp_image
width, height = get_image_size(image_copy)
for w in range(width):
for h in range(height):
pixel = self.temp_image.getpixel((w, h))[0]
if pixel == 0 or pixel == 255:
pixel_list = []
try: pixel_list.append(image_copy.getpixel((w, h-1))[0])
except: pass
try: pixel_list.append(image_copy.getpixel((w, h+1))[0])
except: pass
try: pixel_list.append(image_copy.getpixel((w-1, h))[0])
except: pass
try: pixel_list.append(image_copy.getpixel((w+1, h))[0])
except: pass
try: pixel_list.append(image_copy.getpixel((w-1, h-1))[0])
except: pass
try: pixel_list.append(image_copy.getpixel((w-1, h+1))[0])
except: pass
try: pixel_list.append(image_copy.getpixel((w+1, h-1))[0])
except: pass
try: pixel_list.append(image_copy.getpixel((w+1, h+1))[0])
except: pass
pixel = sum(pixel_list)/len(pixel_list)
self.temp_image.putpixel((w, h), (pixel, pixel, pixel))
self.update_image(self.temp_image)
def main():
if len(sys.argv) > 0:
image_file_path = sys.argv[1]
if os.path.isfile(image_file_path):
Edges(image_file_path)
else:
print 'Image file does not exist'
else:
print 'First parameter must be an image file name'
if __name__ == '__main__':
main()
view raw edges.py hosted with ❤ by GitHub

Referencias:
[1] - Ruido en la fotografía

1 comentario:

Nota: solo los miembros de este blog pueden publicar comentarios.