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.
Código Binarización https://gist.github.com/vane90/4983297
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
Imagen con centros, porcentajes y etiquetas:
Porcentajes
Otro ejemplo :
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Otro ejemplo :
Repositorio :
OK; 5 pts.
ResponderEliminar