lunes, 18 de febrero de 2013

Tarea 2(clase). Detección de formas


Para está tarea se utilizaron las rutinas anteriores para poder encontrar las separaciones que existen entre componentes de la imagen y poder diferenciarlos. 
Para detectar los contornos se realizaron los siguientes pasos:

  • Conversión de imagen a escala de grises.
  • Convolución de la imagen con la máscara aplicada anteriormente
  • Binarización de la imagen

Aplique lo anterior a una nueva imagen para ver el comportamiento de la imagen con menos componentes.




Detectar formas 
Para realizar el bfs utilice como base el algoritmo bfs utilizado por la Dra con texto ASCII visto en clase. Después de tener los contornos marcados donde tenemos un punto de inicio en las coordenadas x, y, se guarda el valor de su píxel en una variable, así poder recorrer todos los píxeles que son del mismo color y marcarlos de un color determinado. 


Mientras se recorren estos píxeles se va contando la cantidad de los píxeles para después calcular el porcentaje que tiene esa figura con respecto al total de píxeles y al ir recorreriendo cada píxel de la imagen binarizada, se aplicara BFS a cada pixel negro que se encuentre y coloreando sus vecinos con un color aleatorio. 


 
def im2():
image = Image.open('binarizada1.png')
imagen = image.load()
ancho,alto = image.size
print ancho
print alto
for a in range(ancho):
for b in range(alto):
color=(random.randint(0,255),random.randint(0,255),random.randint(0,255))
if imagen[a,b]==(0,0,0):
n,xs,xy= bfs(image,color,a,b)
nueva='formas.jpg'
image.save(nueva)
return nueva
#aplicamos bfs en la imagen
def bfs(image,color,a,b):
imagen=image.load()
ancho,alto=image.size
original = imagen[a,b]
c=[] #lista color
xs=[] #coordenada x
ys=[] #coordenada y
c.append((a,b))
n = 0
while len(c) > 0:
(x, y) = c.pop(0)
actual = imagen[x, y]
if actual == original or actual == color:
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
i, j = (x + dy, y + dx)
if i >= 0 and i < ancho and j >= 0 and j < alto:
contiene = imagen[i, j]
if contiene == original:
imagen[i, j] = color
xs.append(i)
ys.append(j)
n += 1
c.append((i, j))
forma1 = image.save('formas.png')
return n, xs, ys
view raw bfs1.py hosted with ❤ by GitHub

Ahora el componente más grande es el fondo y se colorea gris.
Para hacer esto primero se necesitaba tener coloreadas las figuras, después se saca un porcentaje dependiendo de la cantidad de píxeles que cubre una figura con respecto a la cantidad de píxeles totales de la imagen, una vez que se tiene cual es la de mayor porcentaje con ese color que se guardo se hace de nuevo bfs() para pintar todo el fondo de color gris.


def im2():
image = Image.open('binarizada2.png') #carca la imagen con convolucion y binarizada
imagen = image.load()
ancho,alto = image.size
total = ancho*alto
porcentaje = []
centro = []
contiene = 0
print ancho
print alto
#aplicamos bfs para la imagen
for a in range(ancho):
for b in range(alto):
if imagen[a,b] == (0, 0, 0):
color = random.randint(0,255),random.randint(0,255),random.randint(0,255)
n,xs,xy= bfs(image,color,a,b)
p = float(n)/float(total) * 100.0 #promedio maximo
if p > 0.5:
centro.append((sum(xs)/len(xs),sum(xy)/len(xy))) #obtenemos los centros de la imagen
porcentaje.append([p, (color)])
print "Pinta figura %s"%contiene
contiene +=1
fondo_new = porcentaje.index(max(porcentaje)) #
max_c = porcentaje[fondo_new][1]
print "Pinta fondo"
for i in range(ancho): #ciclo para pintar en gris la parte con un mayor porcentaje de color
for j in range(alto):
if imagen[i,j]==max_c:
imagen[i,j]=(120,120,120)
nueva='fondogris.jpg'
image.save(nueva)
view raw pgris.py hosted with ❤ by GitHub
Imagen con centros, porcentajes y etiquetas: 

Ahora lo que sigue es dibujar el centro de masa esto se obtiene sumando sus coordenadas "x" y "y"  para después promediarlas. Al lado del centro de masa se agrega una etiqueta del ID del componente al que pertenece.

Porcentajes

import sys, pygame
import Image
from math import*
from time import*
import math
import random
import ImageDraw
def im2():
image = Image.open('binarizada2.png') #carca la imagen con convolucion y binarizada
imagen = image.load()
ancho,alto = image.size
total = ancho*alto
porcentaje = []
centro = []
contiene = 0
print ancho
print alto
#aplicamos bfs para la imagen
for a in range(ancho):
for b in range(alto):
if imagen[a,b] == (0, 0, 0):
color = random.randint(0,255),random.randint(0,255),random.randint(0,255)
n,xs,xy= bfs(image,color,a,b)
p = float(n)/float(total) * 100.0 #promedio maximo
if p > 0.5:
centro.append((sum(xs)/len(xs),sum(xy)/len(xy))) #obtenemos los centros de la imagen
porcentaje.append([p, (color)])
print "Pinta figura %s"%contiene
contiene +=1
fondo_new = porcentaje.index(max(porcentaje)) #
max_c = porcentaje[fondo_new][1]
print "Pinta fondo"
for i in range(ancho): #ciclo para pintar en gris la parte con un mayor porcentaje de color
for j in range(alto):
if imagen[i,j]==max_c:
imagen[i,j]=(120,120,120)
nueva='fondogris.jpg'
image.save(nueva)
#return nueva
print "centros de masa"
print centro
#dibujar los centros y las etiquetas en las formas
draw = ImageDraw.Draw(image)
m=0
for i in centro:
draw.ellipse((i[0]-2, i[1]-2,i[0]+2,i[1]+2), fill=(0,0,0)) #dibuja los puntos en los centros de las formas
draw.text(((i[0]+4,i[1]+4),), str(m), fill=(0,0,0)) #muestra las etiquetas cerca de los centros
m +=1
contiene = 0
for p in porcentaje: #muestra el id de la etiqueta y el porcentaje de color de cada una
print "Porcentaje de ID %d: %.2f"%(contiene, p[0])
contiene +=1
nueva2 = 'centro.jpg'
image.save(nueva2)
return nueva2
def bfs(image,color,a,b):
imagen=image.load()
ancho,alto=image.size
original = imagen[a,b]
c=[]
xs=[]
ys=[]
c.append((a,b))
n = 0
while len(c) > 0:
(x, y) = c.pop(0)
actual = imagen[x, y]
if actual == original or actual == color:
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
i, j = (x + dy, y + dx)
if i >= 0 and i < ancho and j >= 0 and j < alto:
contiene = imagen[i, j]
if contiene == original:
imagen[i, j] = color
xs.append(i)
ys.append(j)
n += 1
c.append((i, j))
forma1 = image.save('formas.png')
return n, xs, ys
def main():
pygame.init() # Inicializa pygame
screen = pygame.display.set_mode((550, 300))
pygame.display.set_caption('Formas')
imagen = im2()
img = pygame.image.load(imagen)
screen = pygame.display.get_surface()
while True: # Ciclo para las acciones en la ventana
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.blit(img, (0,0)) # muestra la posicion de la imagen en x = 0 y y=0
pygame.display.update()
if __name__ == "__main__":
main()
view raw bfs2.py hosted with ❤ by GitHub


Otro ejemplo :




Repositorio :





1 comentario: