Para la parte de detectar esquinas lo que realicé fue lo siguiente:
- Convertir la imagen a escala de grises.
- Aplicar un filtro mediano, esto es recorrer la imagen, para cada pixel guardar sus vecinos en una lista incluyéndolo, ordenar la lista y tomar el pixel que se encuentre en el centro de la lista.
- Tomar la imagen en escala de grises y la que se le aplicó el filtro mediano y restar ambas imágenes, lo que da como resultado las esquinas de la imagen.
Ya teniendo esto lo que hice fue utilizar bfs tomando como punto de partida cada una de las esquinas para obtener de esta manera los bordes de la imagen, ya que por obvias razones las esquinas están dentro de los bordes.
Después busco cada coordenada de las esquinas en las coordenadas arrojadas por el bfs y calculo su ángulo, así como en la detección de líneas, para de esta manera conocer el orden en que se van a unir las líneas. Obteniendo los ángulos solo falta ordenar el arreglo para que siga el orden correcto.
Después busco cada coordenada de las esquinas en las coordenadas arrojadas por el bfs y calculo su ángulo, así como en la detección de líneas, para de esta manera conocer el orden en que se van a unir las líneas. Obteniendo los ángulos solo falta ordenar el arreglo para que siga el orden correcto.
Código:
This file contains hidden or 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 | |
from PIL import Image, ImageDraw | |
from math import sqrt, floor, atan2 | |
def grayScale(im): | |
w,h = im.size | |
gray = im.copy() | |
pix = gray.load() | |
for x in range(w): | |
for y in range(h): | |
curr = pix[x,y] | |
prom = max(curr) | |
pix[x,y] = prom, prom, prom | |
return gray | |
def median(im): | |
w,h = im.size | |
out = im.copy() | |
pix = out.load() | |
for x in range(w): | |
for y in range(h): | |
ngbs = [] | |
ngbs.append(pix[x,y]) | |
for i in range(x-1,x+2): | |
for j in range(y-1, y+2): | |
try: | |
ngbs.append(pix[i,j]) | |
except IndexError: | |
pass | |
ngbs.sort() | |
half = len(ngbs) | |
pix[x,y] = ngbs[(half/2)-1] | |
#out.show() | |
return out | |
def binarize(im, thresh): | |
w,h = im.size | |
binarized = im.copy() | |
pix = binarized.load() | |
for x in range(w): | |
for y in range(h): | |
if pix[x,y][0] >= thresh: | |
pix[x,y] = (255,255,255) | |
else: | |
pix[x,y] = (0,0,0) | |
return binarized | |
def normalize(im): | |
w,h = im.size | |
outpic = im.copy() | |
out = outpic.load() | |
high = 0 | |
low = 0 | |
for x in range(w): | |
for y in range(h): | |
if out[x,y][0] > high: | |
high = out[x,y][0] | |
if out[x,y][0] < low: | |
low = out[x,y][0] | |
prop = 256.0/(high - low) | |
for x in range(w): | |
for y in range(h): | |
n = int(floor((out[x,y][0] - low)* prop)) | |
out[x,y] = (n,n,n) | |
return outpic | |
def bfs(im, root, color): | |
'''q = queue ''' | |
pix = im.load() | |
w, h = im.size | |
q = [] | |
q.append(root) | |
coords = [] | |
original = pix[root] | |
tot = 0 | |
while len(q) > 0: | |
(x, y) = q.pop(0) | |
curr = pix[x, y] | |
if curr == original or curr == color: | |
for dx in [-1, 0, 1]: | |
for dy in [-1, 0, 1]: | |
i, j = (x + dx, y + dy) | |
if i >= 0 and i < w and j >= 0 and j < h: | |
rgb = pix[i, j] | |
if rgb == original: | |
tot+=1 | |
pix[i, j] = color | |
coords.append((i, j)) | |
q.append((i, j)) | |
return coords, tot | |
def convolution(im,m): | |
w, h = im.size | |
pixeles = im.load() | |
imCon = Image.new('RGB', (w,h)) | |
pixCon = imCon.load() | |
for x in range(w): | |
for y in range(h): | |
r,g,b = 0,0,0 | |
for i in range(x-1, x+2): | |
for j in range(y-1, y+2): | |
try: | |
r += int(m[i - (x-1)][j - (y-1)] * pixeles[i,j][0]) | |
g += int(m[i - (x-1)][j - (y-1)] * pixeles[i,j][1]) | |
b += int(m[i - (x-1)][j - (y-1)] * pixeles[i,j][2]) | |
except: | |
pass | |
pixCon[x,y] = (r,g,b) | |
return imCon | |
def edges(im,median): | |
w,h = im.size | |
output = Image.new("RGB",(w,h)) | |
out = output.load() | |
pix = im.load() | |
mpix = median.load() | |
for x in range(w): | |
for y in range(h): | |
out[x,y] = pix[x,y][0] - mpix[x,y][0], pix[x,y][1] - mpix[x,y][1], pix[x,y][2] - mpix[x,y][2] | |
output = binarize(output,70) | |
output.save("dots.png","PNG") | |
#maskx = [[-1, -1, -1], [2, 2, 2], [-1, -1, -1]] | |
#masky = [[-1, 2, -1], [-1, 2, -1], [-1, 2, -1]] | |
mask = [[1,3,3],[-3,-2,3],[-3,-3,1]] | |
edges = convolution(im,mask) | |
edges = binarize(normalize(edges), 80) | |
#edges.save("bordes.jpeg","JPEG") | |
pix = edges.load() | |
out = output.load() | |
corners = [] | |
coords = [] | |
for x in range(w): | |
for y in range(h): | |
if out[x,y] == (255,255,255): | |
corners.append((x,y)) | |
if pix[x,y] == (255,255,255): | |
c,tot = bfs(edges,(x,y),(0,0,255)) | |
coords.append(c) | |
points= [] | |
draw = ImageDraw.Draw(output) | |
for coord in coords: | |
#p = point | |
p = [] | |
x,y = 0,0 | |
for c in coord: | |
for i in corners: | |
if i == c: | |
print "entro" | |
p.append(c) | |
x += c[0] | |
y += c[1] | |
xm = x/len(p) | |
ym = y/len(p) | |
points.append([p, (xm, ym)]) | |
corners = [] | |
print points | |
for p in points: | |
c = [] | |
point, center = p | |
for i in point: | |
x,y = i | |
angle = atan2(x - center[0], y - center[1]) | |
c.append([angle, i]) | |
c.sort() | |
corners.append(c) | |
print corners | |
for c in corners: | |
print len(c) | |
for i in range(len(c)-1): | |
#print "entro" | |
draw.line((c[i][1], line[i+1][1]), fill="blue") | |
draw.line((c[0][1], c[i+1][1]), fill="yellow") | |
output.save("lineas.png","PNG") | |
if __name__ == '__main__': | |
path = sys.argv[1] | |
size = 128,128 | |
image = Image.open(path).convert('RGB') | |
copy = image.copy() | |
copy.thumbnail(size, Image.ANTIALIAS) | |
gray = grayScale(copy) | |
median = median(gray) | |
edges(gray,median) |
No comments:
Post a Comment