Monday 1 July 2013

Detección de Bordes

Este es el post de la tarea 1: Detección de bordes, en las 3 imágenes siguientes muestro dibujos que hice para meditar el problema:

Se tendrán 3 imágenes en formato PNG, las cuales fueron convertidas a escala de grises, para esto simplemente se sumaron las 3 matrices de grises que conforman al RGB y se promediaron, en el código me aseguro que sean enteros y genero una nueva imagen en gris:

Código Fuente para convertir imágenes a color a escala de grises

Para la detección de bordes se hizo uso de la mascara Prewitt 3 x 3 "gradiente suavizado" tomado de la referencia 1, para la convolución se procedió a barrer la imagen pixel por pixel y tomando sus 8 vecinos formar una zona de la imagen original, tomar esos valores y multiplicarlos con la mascara, después del resultado de la multiplicación se toman y se hace una suma de todos sus valores para tener el gradiente en x y y segun sea el caso; después sacamos una distancia euclidiana para obtener el gradiente en magnitud mas no en dirección, por ultimo los gradientes mas grandes o cercanos a 255 (Blanco) se toman como borde y los que sean menores se dejan como fondo. En cuanto al programa este se posiciona en el pixel [1,1] esto para evitar salirse del arreglo, esto no afecta en gran medida ya que no hay información muy relevante en el marco de la imagen, el tamaño se conserva pero teniendo los valores de esos pixeles en el marco a 0.

Con la detección paso algo curioso, el programa arrojaba como bordes algunas partes de la imagen original que servían de detalles como se ve en la imagen de abajo, mi Starman tiene algo de profundidad con esas lineas esparcidas en sus filos:

Hay dos detalles en el código de detección de bordes que servirán para quitar este ruido que no es representativo de un borde, este "umbral" servirá para, dependiendo de la imagen, quitar el ruido y dejar los bordes y variara de acuerdo a la situación. A continuación los resultados con su tiempo de respuesta:

En la imagen de arriba el "umbral" fue de 135.

En la imagen de arriba el "umbral" fue de 135, no se modifico.

En la imagen de arriba el "umbral" fue de 135, no se modifico. Parece ser que la detección de borde es algo fina ya que pone como fondo el interior de las lineas negras.

En la tabla de abajo, se muestran los tiempos de respuesta:

Abajo muestro el código fuente de la detección de bordes:

Referencias:

  1. Machine Vision by E.R. Davies Third Edition, Chapter 5.
  2. Blog de Visión Computacional de Esteban Sifuentes Samaniego, 2013
    http://esteban-vision.blogspot.mx/
  3. Blog de Isaias Garza acerca de Visión Computacional, 2013
    http://isaias-garza.blogspot.mx/search/label/Visi%C3%B3n%20Computacional
  4. Programa de manipulación de imágenes de GNU: Manual de usuario, by Equipo de documentación de GIMP and Ignacio AntI (ant.ign@gmail.com)
    http://docs.gimp.org/es/plug-in-convmatrix.html
  5. http://wiki.scipy.org/Tentative_NumPy_Tutorial#head-c5f4ceae0ab4b1313de41aba9104d0d7648e35cc
  6. http://docs.scipy.org/doc/numpy/reference/generated/numpy.sum.html

2 comments:

  1. Van extras en la primera tarea que faltó, pero sigue faltando la segunda.

    ReplyDelete
  2. -----FUNCIÓN PARA PYTHON 3

    #!/usr/bin/python
    #coding: utf-8

    from PIL import Image
    from numpy import array
    import cv2
    import numpy as np
    import math
    from time import time

    #Funcion para sacar la magnitud de gradiente
    def edge_mag(gx,gy,n,m):
    xm = pow(gx,2)
    ym = pow(gy,2)
    g = int(math.sqrt(xm+ym))
    #arr_gra(n,m) = g
    if g > 255:
    g = 255 #Si el gradiente es mayor a 255 entonces es blanco
    if g < 0: #Si el gradiente es menor a 0 entonces es negro
    g = 0
    #arr_bor(n,m) = g #Si es borde valdra 255 si no lo es sera 0

    def main():
    t_inicial = time()

    im = Image.open('Captura.jpg')
    im.show()
    arr_gry = array(im)
    (i,j) = (arr_gry.shape[0],arr_gry.shape[1])
    arr_gra = np.zeros(shape = (arr_gry.shape[0],arr_gry.shape[1]))
    arr_bor = np.zeros(shape = (arr_gry.shape[0],arr_gry.shape[1]))
    # mask_Robx = ([0,1],[-1,0])
    # mask_Roby = ([-1,0],[0,-1])
    mask_Prewx = array([(-1,0,1),(-1,0,1),(-1,0,1)])
    mask_Prewy = array([(1,1,1),(0,0,0),(-1,-1,-1)])
    a = arr_gry #solo le cambio el nombre
    #Barrido para la mascara Prewitt

    # Me comere las lineas de las imagnes y las reconstruire duplicando valores
    n = 1
    m = 1
    for n in range(i-1): #Barremos por filas
    for m in range(j-1): #Barremos por columnas
    #Esto no funciona muy impractico
    # if n < 0 and m < 0: #caso espacial de esquina sup izq
    # p_z_9 = array([(255,255,255),(255,a[n,m],a[n,m+1]),(255,a[n+1,m],a[n+1,m+1])])
    # gx = np.sum(p_z_9*mask_Prewx)
    # gy = np.sum(p_z_9*mask_Prewy)
    # edge_mag(gx,gy,n,m)
    # if n < 0 and m > #caso especial de esquina sup der
    # p_z_9 = array([(255,255,255),(a[n,m-1],a[n,m],a[n,m+1]),(255,a[n+1,m],a[n+1,m+1])])
    p_z_9 = array([(a[n-1,m-1],a[n-1,m],a[n-1,m+1]),(a[n,m-1],a[n,m],a[n,m+1]),(a[n+1,m-1],a[n+1,m],a[n+1,m+1])])
    gx = np.sum(p_z_9*mask_Prewx)
    gy = np.sum(p_z_9*mask_Prewy)
    #edge_mag(gx,gy,n,m)
    xm = pow(gx,2)
    ym = pow(gy,2)
    g = int(math.sqrt(xm+ym))
    #arr_gra[n,m] = g
    if g > 135: #Este numero sirve de umbral para quitar ruido
    g = 255 #Si el gradiente es mayor a 255 entonces es blanco
    elif g < 0: #Si el gradiente es menor a 0 entonces es negro
    g = 0
    else: #Este tambien sirve para quitar ruido
    g = 0
    arr_bor[n,m] = g #Si es borde valdra 255 si no lo es sera 0 para fondo; ¡a sí! con esto construimos la imagen de bordes.

    #!/usr/bin/env python
    import pdb; pdb.set_trace()
    cv2.imwrite("Captura.jpg",np.array(arr_bor))
    #im_cv = cv.LoadImage("bord_n_50.png")
    im_b = Image.open('Captura.jpg')
    im_b.show()
    #cv.ShowImage('imagen',im_cv)
    #cv.WaitKey(0)

    t_final = time()
    t_total = t_final - t_inicial
    print("Tiempo de convolución: ",t_total)
    if __name__ == '__main__':
    main()

    #Referencias:
    #Blog de Visión Computacional de Esteban Sifuentes Samaniego, 2013
    #http://esteban-vision.blogspot.mx/

    #Agradecimientos por el apoyo de Estaban Sifuentes Samaniego

    ReplyDelete