Mostrando entradas con la etiqueta Laboratorio Visión Computacional. Mostrar todas las entradas
Mostrando entradas con la etiqueta Laboratorio Visión Computacional. Mostrar todas las entradas

jueves, 25 de abril de 2013

Actividad 7: Detección de Agujeros

Para ésta semana en el laboratorio, se nos pidió tener la detección de de agujeros.

Importancia:
La detección de agujeros es una de las repuestas que se aplican principalmente en la industria de la manufactura, enfocada principalmente en en la creación de piezas sólidas. Un ejemplo a mencionar es al momento de detectar fisuras u orificios en las piezas que se elaboraron, en la cual ayudan a clasificarlas, ya sea para quitarlas de la línea de producción u obtener las que no tienen imperfecciones.

Desarrollo:
Para poder tener una buena detección de histogramas, recomiendo hacer el uso de filtros o normalizar la imagen, en mi caso lo que emplie fue ordenar la lista, ya que sin el uso de éste, lo que se obtendría sería muchas líneas horizontales y verticales.


[imagen original]

[primeros resultados]

[imagen sin filtros]

[imagen sin filtro]



Resultados







Referencia:
http://elisa.dyndns-web.com/~elisa/teaching/comp/vision/agujeros.pdf

jueves, 18 de abril de 2013

Actividad 6: Reconocimiento de Elipses y Rellenado del fondo

Para ésta actividad se nos encargó implementar en el código que ya se tenía donde se detecta elipses, rellenar el fondo de éste, la idea sería aplicar el bfs en una vez que se encuentra el elipse y así colorearlo.

En ésta ocasión no pude realizar la actividad, por lo tanto me quede en el mismo código que había puesto en la entrada de clase, de detección de elipses, así que esta entrada es para no tener un np.

jueves, 7 de marzo de 2013

Actividad 5: Detección Círculos Radios Desconocidos

Para ésta entrada se nos encargó hacer la detección de círculos donde nosotros no conocemos el radio y buscamos que nuestro programa lo detecte.

A continuación les dejo el código el cuál esta incompleto, pero proximamente lo actualizaré.
Resultados




miércoles, 13 de febrero de 2013

PIL: Putpixel and Getpixel vs Array

En ésta entrada, veremos una comparativa respecto a la demora que se lleva en el procesamiento de una imagen con la librería de PIL.
Realizando las tareas respecto al tema, me encontré con un ligero problema que al analizarlo y compararlo tiene consecuencias como esperar un resultado de una determinada imagen. Así que me puse a investigar y buscar otra forma del poder procesar una imagen con PIL y me encontré con el uso de arreglos manipulados con la misma imagen.

Breve discusión:
Siendo un poco breve y analizando mi código encontré que las subrutinas getpixel y putpixel son un poco pesadas, ya que estamos manipulando y procesando la imagen en el momento que se carga determinado pixel y su determinado color, a comparación del uso de las listas con la subrutina load() donde cargamos la imagen en el arreglo, donde cada elemento contiene una tupla, siendo más ligera y fácil su manipulación.

Código:
En el siguiente código veremos como trabaja el procesar una imagen con lo ya antes mencionado aplicada a una imagen normal buscando obtener la escala de grises.

img.putpixel() & img.getpixel
img.load()


Resultados:
[511x684]

[511x684]

Como podemos notar en la siguiente imagen haciendo varios test de la misma imagen se encontró que el primer tiempo arrojado emplea el uso de getpixel y putpixel teniendo una demora aproximada de 3.2 segundos y en el segundo empleado el uso de arreglos obtuvo una demora aproximada de 0.7 segundos.
Podemos discutir que se tiene una reducción del 82% del tiempo empleado, siendo una mejora muy significante en el tiempo al momento de manipular imagenes.


Código Completo:

martes, 12 de febrero de 2013

Actividad 2: Ruido Sal y Pimienta

En esta entrada veremos como meter y quitar ruido. El ruido que se empleará es sal y pimienta en la cuál consiste que en una imagen dada tiene algunos pixeles en blanco y negro.

Importancia
Es importante saber como quitar en una imagen ruido, ya que nos podemos encontrar que en un imagen   su contenido sea afectado por la lente de la cámaras, ondas magnéticas, entre otras.

Sal y Pimienta
Para generar el ruido lo que se pide es la intensidad, donde nos servirá para que tan frecuente tendremos ruido en la image, entonces lo que hacemos es tomar un de forma aleatoria aleatoria, para después darle a ese mismo pixel una tonalidad blanca o negra.


[intensidad 0.01]

[intensidad 0.05]

[intensidad 0.1]

Remover Sal y Pimienta
Para remover el pixel de sal y pimienta, se pueden emplear varias técnicas, en mi caso empleo la técnica de media aritmética, donde consiste en tomar el pixel actual y sus vecinos, dentro de cada pixel estará su rgb, así que lo ordenamos y sacamos su valor medio, para después meterlo a la lista donde pondremos el actual con sus vecinos, para hacer nuevamente el mismo proceso, que es ordenarlo y sacar el valor medio, una vez obtenido ese valor es el que se pondrá en el pixel actual.

Resultado:
A continuación dejo el resultado y como podemos ver en la imagen que se removió sal y pimienta es casi efectivo, ya que podemos ver a simple vista uno o dos pixeles con ruido.

[Sal y Pimienta]

[Remover Sal y Pimienta]

Código Completo:


Referencias:

lunes, 4 de febrero de 2013

Actividad 1: Filtros


En ésta entrada veremos como aplicar diferentes tipos de filtros a una determinada imagen, para eso se empleo python junto con la librería PIL, donde los filtros aplicados son:
  • Escala de grises.
  • Escala de grises mínimo.
  • Escala de grises máximo.
  • Negativo.
  • Binaria.
El programa lo que hace es mostrarte en una ventana la imagen seleccionada, donde en la misma ventana te muestran botones para aplicar las diferentes tipos de escalas, al final dejo el código completo junto a la liga de github.


Algoritmo:
Para poder sacar los filtros primero se obtuvo cada pixel de la imagen, para después tener el rgb.

Escala de grises:
En la escala de grises, una vez obtenido el rgb del pixel, sacamos su media y este nuevo valor será el del rojo, verde y azul, para así obtener el nuevo pixel.
    def grayScale(self):
        for i in range(self.img.size[0]): #recorremos las de i & j para tener cada pixel de la iamgen
            for j in range(self.img.size[1]):
                r = self.rgb.getpixel((i, j))[0] #obtenemos r, g, b
                g = self.rgb.getpixel((i, j))[1]
                b = self.rgb.getpixel((i, j))[2]
                
                media = (r+g+b)/3 #Lo explicado
                pixel = tuple([media, media, media]) #Creamos nuestro nuevo pixel
                self.img.putpixel((i, j), pixel) #En la imagen ponemos el nuevo pixel           

        self.img.save('grayScale.png', 'PNG') #Guardamos la imagen
        return self.img #regresamos la imagen, para manipolarla posteriormente


[escala de grises]


Escala de grises máximo y mínimo
En ésta escala de grises, lo que hago es obtener el pixel completo, sacando el máximo o mínimo del rgb, para después el obtenido ponerlo en cada rbg
    def grayScaleMax(self):
        for i in range(self.img.size[0]): #Se aplica lo mismo mencionado
            for j in range(self.img.size[1]):
                
                pixel = max(self.rgb.getpixel((i, j))) #Sacamos el máximo
                
                pixel = tuple([pixel, pixel, pixel])
                self.img.putpixel((i, j), pixel)            

        self.img.save('grayScaleMax.png', 'PNG')
        return self.img

    def grayScaleMin(self):
        for i in range(self.img.size[0]):
            for j in range(self.img.size[1]):
                
                pixel = min(self.rgb.getpixel((i, j))) #Sacamos en mínimo
                
                pixel = tuple([pixel, pixel, pixel])
                self.img.putpixel((i, j), pixel)            

        self.img.save('grayScaleMin.png', 'PNG')
        return self.img


[escala de grises mínimo]

[escala de grises máximo]


Umbral:
El del umbral, interactúa un poco con el de la escala de grises, ya que nosotros pondremos un límite del valor obtenido (media), en mi caso si es mayor a 127 es 255, de lo contrario es 0.
    def binaryScale(self, umbral):
        if(umbral == None): umbral = 122
        for i in range(self.img.size[0]):
            for j in range(self.img.size[1]):
                r = self.rgb.getpixel((i, j))[0]
                g = self.rgb.getpixel((i, j))[1]
                b = self.rgb.getpixel((i, j))[2]
                
                media = (r+g+b)/3 #Obtenemos la media
                pixel = tuple([media, media, media])
                self.img.putpixel((i, j), pixel)            

                if media > umbral: media = 255 #Dependiendo del umbral nos asigna el nuevo valor
                else: media = 0

                pixel = tuple([media, media, media])
                self.img.putpixel((i, j), pixel)

        self.img.save('BinaryScale.png', 'PNG')
        return self.img


[filtro binario]


Negativo:
Investigando un poco del algoritmo para sacar el negativo, lo que se hace es tener el valor maximo de un color (el cual es 255) y éste es restado por el valor de cada rgb, pra despues tener el pixel.
    def negativeScale(self):
        for i in range(self.img.size[0]):
            for j in range(self.img.size[1]):
                r = self.rgb.getpixel((i, j))[0]
                g = self.rgb.getpixel((i, j))[1]
                b = self.rgb.getpixel((i, j))[2]
                
                nr = 255 - r # 255 que es nuestro valor máximo es restado por rgb
                ng = 255 - g
                nb = 255 - b
                pixel = tuple([nr, ng, nb])
                self.img.putpixel((i,j), pixel)

        self.img.save('negativeScale.png', 'PNG')
        return self.img


[filtro negativo]



Código:
Al igual dejo el enlace de github.

from Tkinter import * 
from PIL import ImageTk, Image
from sys import argv

class Filtro(object):
    """docstring for Filtro"""
    def __init__(self, fileName):
        self.img = Image.open(fileName)
        self.rgb = self.img.convert('RGB')

    def grayScale(self):
        for i in range(self.img.size[0]):
            for j in range(self.img.size[1]):
                r = self.rgb.getpixel((i, j))[0]
                g = self.rgb.getpixel((i, j))[1]
                b = self.rgb.getpixel((i, j))[2]
                
                media = (r+g+b)/3
                pixel = tuple([media, media, media])
                self.img.putpixel((i, j), pixel)            

        self.img.save('grayScale.png', 'PNG')
        return self.img

    def grayScaleMax(self):
        for i in range(self.img.size[0]):
            for j in range(self.img.size[1]):
                
                pixel = max(self.rgb.getpixel((i, j)))
                
                pixel = tuple([pixel, pixel, pixel])
                self.img.putpixel((i, j), pixel)            

        self.img.save('grayScaleMax.png', 'PNG')
        return self.img

    def grayScaleMin(self):
        for i in range(self.img.size[0]):
            for j in range(self.img.size[1]):
                
                pixel = min(self.rgb.getpixel((i, j)))
                
                pixel = tuple([pixel, pixel, pixel])
                self.img.putpixel((i, j), pixel)            

        self.img.save('grayScaleMin.png', 'PNG')
        return self.img

    def binaryScale(self, umbral):
        if(umbral == None): umbral = 122
        for i in range(self.img.size[0]):
            for j in range(self.img.size[1]):
                r = self.rgb.getpixel((i, j))[0]
                g = self.rgb.getpixel((i, j))[1]
                b = self.rgb.getpixel((i, j))[2]
                
                media = (r+g+b)/3
                pixel = tuple([media, media, media])
                self.img.putpixel((i, j), pixel)            

                if media > umbral: media = 255
                else: media = 0

                pixel = tuple([media, media, media])
                self.img.putpixel((i, j), pixel)

        self.img.save('BinaryScale.png', 'PNG')
        return self.img

    def negativeScale(self):
        for i in range(self.img.size[0]):
            for j in range(self.img.size[1]):
                r = self.rgb.getpixel((i, j))[0]
                g = self.rgb.getpixel((i, j))[1]
                b = self.rgb.getpixel((i, j))[2]
                
                nr = 255 - r
                ng = 255 - g
                nb = 255 - b
                pixel = tuple([nr, ng, nb])
                self.img.putpixel((i,j), pixel)

        self.img.save('negativeScale.png', 'PNG')
        return self.img


path_image = sys.argv[1]
debug = True
imagen = Filtro(path_image)#Instanciamos la imagen de la clase filtro

def main():
    window()

def window():
 root = Tk()
 frame = Frame()
 frame.pack(fill=X, padx=5, pady=5)
 root.title("Imagen Original")

 call(Image.open(path_image)) #Ponemos la imagen original

 panel1 = Button(text="Original", command=original)
 panel1.pack(in_=frame, side=LEFT)

 panel2 = Button(text="GrayScale", command=grayScale)
 panel2.pack(in_=frame, side=LEFT)

 panel3 = Button(text="GrayScaleMin", command=grayScaleMin)
 panel3.pack(in_=frame, side=LEFT)

 panel4 = Button(text="GrayScaleMax", command=grayScaleMax)
 panel4.pack(in_=frame, side=LEFT)
 
 panel5 = Button(text="BinaryScale", command=binaryScale)
 panel5.pack(in_=frame, side=LEFT)

 panel6 = Button(text="Negative", command=negativeScale)
 panel6.pack(in_=frame, side=LEFT)
 
 root.mainloop()

def call(im): #Metodo que ponemos la nueva imagen
    global panel
    img = ImageTk.PhotoImage(im)
    panel = Label(image = img)
    panel.pict = img
    panel.pack() 

def original(): #Metodo del Boton para llamar la imagen Original
 panel.destroy()   #Destruimos el panel para poner la nueva imagen
 return call(Image.open(path_image)) 

def grayScale(): #Metodo del Boton para llamar la escala de grises
 global imagen
 panel.destroy()
 call(imagen.grayScale()) # de nuestro objeto imagen mandamos llamar la funcion

def grayScaleMin(): #Metodo del Boton para llamar la escala de grises de min
 global imagen
 panel.destroy()
 call(imagen.grayScaleMin())

def grayScaleMax(): #Metodo del Boton para llamar la escala de grises de max
 global imagen
 panel.destroy()
 call(imagen.grayScaleMax())

def binaryScale(): #Metodo del Boton para llamar la escala binaria
 global imagen
 panel.destroy()
 call(imagen.binaryScale(None))

def negativeScale(): #Metodo del Boton para llamar la imagen en negativo
 global imagen
 panel.destroy()
 call(imagen.negativeScale())

if __name__ == '__main__':
    main()

Nota:
Debo de mencionar que me apoyé del crear y poner la imagen en la ventana del código de un compañero de clase, todo lo demás lo algorítmico del procesamiento de imagenes es de mi parte.


Referencias:
http://lodev.org/cgtutor/filtering.html
http://www.pythonware.com/library/tkinter/introduction/hello-again.htm