Laboratorio 4 - Detección de diagonales
Hola, esta entrada corresponde a la cuarta actividad del laboratorio de visión computacional. La actividad consiste en localizar y pintar las diagonales de los objetos de una imagen.
En esta misma entrada primero hablaré sobre la detección de lineas horizontales y verticales (esto fue la tarea 4 de la misma materia) continuar con el seguimiento y explicar de donde viene la detección de lineas en diagonal.
Detección de líneas
Para la detección de lineas usamos la transformada de Hough, lo que realizamos fue hacer el cálculo de los gradientes vertical y horizontal de la imagen usando máscaras de convolución (como lo hicimos en la actividad de detección de bordes) seguido de obtener los gradiente antes mencionados, continuamos calculando los valores de theta de los pixeles de la imagen.
Cuando tenemos los gradientes, calculamos el ángulo de cada pixel, yo usé una imagen binarizada sin filtro, porque cuando la pasaba por mi filtro tendía a poner demasiadas lineas verticales y horizontales.
Bueno, obtuvimos los ángulo de los pixeles con la siguiente fórmula:
Las variables de esta fórmula son arctan (arcotangente), gy (gradiente y), gx (gradiente x).
Después de calcular los ángulos, se calcula la variable rho usando al fórmula siguiente:
El valor de rho es guardado en una lista con el valor del ángulo theta.
Seguido de esto obtuvimos las frecuencias de cada "theta, rho" usando un diccionario, esto con el fin de determinar qué pixeles son lineas, tomando en cuenta que cuando un par (theta, rho) tiene más repeticiones, quiere decir que hay más probabilidad de que el par sea una línea (mismo ángulo.)
Para terminar pintamos pixeles pertenecientes a las líneas (azules para horizontales, rojo para verticales y verde para las líneas diagonales)
Para las líneas diagonales solo agregué una condición que cuando el ángulo no fuera ni 0 ni 90 ni 180 ni 270 lo tomara como una diagonal (y lo pinté de verde).
A continuación los highlights del código:
''' Convolucion y deteccion de lineas ''' def convolucion(im,g): w, h = im.size pixeles = im.load() imConvolucion = Image.new('RGB', (w,h)) pix = imConvolucion.load() for x in range(w): for y in range(h): suma = 0 for i in range(x-1, x+2): for j in range(y-1, y+2): try: suma += g[i - (x-1)][j - (y-1)] * pixeles[i,j][1] except: pass pix[x,y] = (suma,suma,suma) return imConvolucion def frecuentes(histo, cantidad): frec = list() for valor in histo: if valor is None: continue frecuencia = histo[valor] acepta = False if len(frec) <= cantidad: acepta = True if not acepta: for (v, f) in frec: if frecuencia > f: acepta = True break if acepta: frec.append((valor, frecuencia)) frec = sorted(frec, key = lambda tupla: tupla[1]) if len(frec) > cantidad: frec.pop(0) incluidos = list() for (valor, frecuencia) in frec: incluidos.append(valor) return incluidos def deteccionDeLineas(): umbral = 10 im = Image.open("meh3.jpg") sobelx = [[-1, -1, -1], [2, 2, 2], [-1, -1, -1]] sobely = [[-1, 2, -1], [-1, 2, -1], [-1, 2, -1]] imx = convolucion(im, sobelx) imy = convolucion(im, sobely) gx = imx.load() gy = imy.load() w,h = im.size comb = {} pixeles = im.load() resultado = list() for x in range(w): datos = list() for y in range(h): hor = gx[x,y][0] ver = gy[x,y][0] if fabs(hor) + fabs(ver) <= 0.0:#nada en ninguna direccion theta = None elif hor == 0 and ver == 255: theta = 90 elif fabs(hor) > 0.0: theta = atan(fabs(ver/hor)) if theta is not None: rho = fabs( x * cos(theta) + y * sin(theta)) if x > 0 and x < w-1 and y > 0 and y < h-1: if (rho, theta) in comb: comb[ (rho, theta) ] += 1 else: comb[ (rho, theta) ] = 1 datos.append( (rho, theta) ) else: datos.append((None,None)) resultado.append(datos) incluir = int(ceil (len(comb) * umbral)) frec = frecuentes(comb, incluir) for x in range(w): for y in range(h): if x > 0 and x< w-1 and y > 0 and y < h-1: rho, theta = resultado[x][y] if (rho, theta) in frec: if theta == 0: pixeles[x,y] = (255,0,0) elif theta == 90: pixeles [x,y] = (0,0,255) elif theta != 0 and theta != 90 and theta != 180 and theta != 270: #Para diagonales pixeles [x, y] = (0,255,0) #Los pintamos verde print "Soy un pixel diagonal" im.save('meh5.jpg')
(Para diagonales)
(Una sección se pinto verde porque traia letras XD)
Mi liga de git: https://github.com/eddypre/VisionTriana
Cualquier duda o aclaración pueden dejarla en comentarios.
Saludos a todos!
Más o menos, pero trae mucho ruido, 6 pts.
ResponderEliminar