- Hacer detección de borde.
- Elegir pares antiparalelos.
- Generar votos a tomando como frontera el borde y las rectas de pares antiparalelos.
- Determinar a partir de porcentaje de votos sí realmente es un elipse (Por agregar).
Lo primero es necesario para saber en que area vamos a trabajar, después de saber el area en la que trabajamos, se empiezan a tomar pares de puntos aleatorios para luego sacar su punto medio y tomarlo como voto. A partir del porcentaje de votos se podrá determinar sí es un elipse.
Ahora lo que se implementó, tuve grandes problemas donde dichos problemas eran de herencia de tareas anteriores con los indices en donde estaban en algunos invertidos en otros no. En fin lo que se implementaron solamente fue la realización de los votos y la creación de las rectas antiparalelas con puntos aleatorios seleccionados. Esto fue lo que obtuve.
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 operator | |
import random | |
from math import fabs | |
from sys import argv | |
import numpy as np | |
from Tkinter import * | |
from PIL import ImageDraw, Image, ImageTk | |
def escalaGrises(imagen): | |
width, height = imagen.size | |
print "Este es el ancho: ", width, " altura: ",height | |
imagen = imagen.convert('RGB') | |
pixeles = imagen.load() | |
promedio = 0.0 | |
for y in xrange(height): | |
for x in xrange(width): | |
r, g, b = pixeles[x, y] | |
promedio = ( r + g + b ) / 3.0 | |
pixeles[x, y] = int( promedio ), int( promedio ), int( promedio ) | |
datos = np.array(imagen) | |
imagen = Image.fromarray(datos) | |
return imagen | |
def convolucion(imagen, mascara): | |
width, height = imagen.size | |
imagen = imagen.convert('L') | |
pixeles = imagen.load() | |
mascara_height, mascara_width = mascara.shape | |
#print mascara.shape | |
g = np.zeros( shape = ( height, width ) ) | |
for y in xrange(height): | |
for x in xrange(width): | |
sum = 0.0 | |
for j in xrange(mascara_height): | |
zj = ( j - ( mascara_height / 2 ) ) | |
for i in xrange(mascara_width): | |
zi = ( i - ( mascara_width / 2 ) ) | |
try: | |
sum += pixeles[x + zi, y + zj] * mascara[j, i] | |
except: | |
pass | |
g[y, x] = sum | |
return g | |
def deteccionDeElipse(g, umbral, gx, gy, imagen): | |
width, height = imagen.size | |
imagen = imagen.convert('RGB') | |
pixeles = imagen.load() | |
#print "Gradiente x size: %s, Gradiente y size: %s "%(gx.shape, gy.shape) | |
borde = list() | |
margen = 50 | |
print '%d por %d' % (width, height) | |
for y in xrange(margen, height - margen): | |
for x in xrange(margen, width - margen): | |
try: | |
if fabs(g[y, x]) > umbral: | |
borde.append((y, x)) | |
#print '(%d, %d) es borde' % (y, x) | |
pixeles[y, x] = 0,255,0 | |
except: | |
pass | |
print len(borde), 'son borde' | |
frec = dict() | |
pares = int(0.10 * len(borde)) | |
print 'seleccionando', pares | |
for i in xrange(pares): | |
(y1, x1) = random.choice(borde) | |
(y2, x2) = random.choice(borde) | |
# print "Puntos para segmentoDeVotos( Pixel uno ( %d, %d ), Pixel dos ( %d, %d) ) "% (y1, x1, y2, x2) | |
votos = segmentoDeVotos((x1, height - y1), (gx[y1, x1], gy[y1, x1]), (x2, height - y2), (gx[y2, x2], gy[y2, x2]), width, height) | |
if votos is not None: | |
try: | |
pixeles[y1, x1] = 0,0,255 | |
pixeles[y2, x2] = 0,0,255 | |
except: | |
pass | |
for voto in votos: | |
if voto in frec: | |
frec[voto] += 1 | |
else: | |
frec[voto] = 1 | |
promedio = sum(frec.values()) / (1.0 * len(frec)) | |
for y in xrange(height): | |
for x in xrange(width): | |
if (x, y) in frec: | |
f = frec[(x, y)] | |
if f > promedio: | |
# print "Estoy en pixel[ %s, %s] con ancho %d y altura %d" % (x, y, width, height) | |
try: | |
pixeles[y, x] = 255,0,0 | |
except: | |
print "Fack" | |
datos = np.array(imagen) | |
imagen = Image.fromarray(datos) | |
return imagen | |
def puntoMedio(p1, p2): | |
(x1, y1) = p1 | |
(x2, y2) = p2 | |
return ((x1 + x2) / 2.0, (y1 + y2) / 2.0) | |
PASO = 0.001 | |
def segmentoDeVotos(p1, g1, p2, g2, ancho, altura): | |
global PASO | |
#print "Punto 1: %s Punto 2: %s Grandiente 1: %s Gradiente 2: %s "%(p1, p2, g1, g2) | |
t1 = rectaTangente(p1, g1) | |
t2 = rectaTangente(p2, g2) | |
if t1 is None or t2 is None: | |
return None | |
#print "t1 %s, t2 %s"%(t1, t2) | |
cruceDeTangentes = cruceAntiparalelo(t1, t2) | |
if cruceDeTangentes is None: | |
return None | |
pm = puntoMedio(p1, p1) | |
recta = ecuacionDeRecta(cruceDeTangentes, pm) | |
if recta is None: | |
return None | |
(cx, cy) = cruceDeTangentes | |
(mx, my) = pm | |
dx = cx - mx | |
dy = cy - my | |
cambioX = PASO * dx | |
cambioY = PASO * dy | |
if dx < 0: | |
cambioX *= -1 | |
if dy < 0: | |
cambioY *= -1 | |
posX = mx | |
posY = my | |
votos = list() | |
while posX < ancho and posY < altura and posX > 0 and posY > 0: | |
pixel = (int(round(posX)), altura - int(round(posY))) | |
if not pixel in votos: | |
votos.append(pixel) | |
posX += cambioX | |
posY += cambioY | |
return votos | |
def rectaGradiente(coordenadasDePixel, gradiente): | |
(xg, yg) = gradiente | |
puntoAuxiliar = ( x + xg , y + yg ) | |
return ecuacionDeRecta(coordenadasDePixel, puntoAuxiliar) | |
def rectaTangente(coordenadasDePixel, gradiente): | |
(xg, yg) = gradiente | |
(x, y) = coordenadasDePixel | |
puntoAuxiliar = (x + yg, y - xg) | |
# print "[rectaTangente] : Punto auxiliar %s, %s "%( (x+yg), (y -xg) ) | |
return ecuacionDeRecta(coordenadasDePixel, puntoAuxiliar) | |
UMBRALCERO = 0.1 | |
def cruceAntiparalelo(l1, l2): | |
global UMBRALCERO | |
(a1, b1) = l1 | |
(a2, b2) = l2 | |
if fabs(a1 - a2) < UMBRALCERO: | |
return None | |
# ax + b = y | |
x = (b2 - b1) / (1.0 * (a1 - a2)) | |
y = a1 * x + b1 | |
return (x, y) | |
def ecuacionDeRecta(p1, p2): | |
global UMBRALCERO | |
(x1, y1) = p1 | |
(x2, y2) = p2 | |
if fabs(x1 - x2) < UMBRALCERO: | |
return None | |
a = (y1 - y2) / (1.0 * (x1 - x2)) | |
b = y1 - a * x1 | |
return (a, b) | |
def coordenadas(lista): | |
coor = list() | |
for l in lista: | |
print l | |
c = l.split(' ') | |
coor.append((int(c[0]),int(c[1]))) | |
return coor | |
def nuevaImagen(matriz): | |
height, width = matriz.shape | |
imagen = Image.new(mode='L', size = ( width, height ) ) | |
pixeles = imagen.load() | |
for y in xrange(height): | |
for x in xrange(width): | |
pixeles[x, y] = matriz[y, x] | |
datos = np.array(imagen) | |
imagen = Image.fromarray(datos) | |
return imagen | |
def binario(imagen): | |
width, height = imagen.size | |
imagen = imagen.convert('L') | |
pixeles = imagen.load() | |
for y in xrange(height): | |
for x in xrange(width): | |
pixel = pixeles[x, y] | |
if pixel < 40: #Ajuste | |
pixeles[x, y] = 0 | |
else: | |
pixeles[x, y] = 255 | |
datos = np.array(imagen) | |
imagen = Image.fromarray(datos) | |
return imagen | |
def main(): | |
imagen = Image.open( argv[1] ) | |
imagen = escalaGrises( imagen ) | |
px = np.array( [ [ -1, 0, 1 ], [ -2, 0, 2 ], [ -1, 0, 1 ] ] ) | |
py = np.array( [ [ -1, -2, -1 ], [ 0, 0, 0 ], [ 1, 2, 1 ] ] ) | |
gx = convolucion( imagen, px ) | |
gy = convolucion( imagen, py ) | |
gx_2 = gx ** 2 | |
gy_2 = gy ** 2 | |
g = ( gx_2 + gy_2 ) ** 0.5 | |
ming = np.min(g) | |
maxg = np.max(g) | |
umbral = 0.5 * (maxg + ming) / 2.0 | |
print 'umbral', umbral, ming, maxg | |
h, w = g.shape | |
minimos = np.ones( shape=( h, w ) ) | |
minimos *= ming | |
gn = g - ming | |
gn = gn / ( maxg - ming ) | |
bn = np.ones( shape=( h, w) ) | |
bn *= 255 | |
gn = gn * bn | |
imagen_ = nuevaImagen(gn) | |
imagen_ = binario(imagen_) | |
imagen_ = deteccionDeElipse(g, umbral, gx, gy, imagen_) | |
############################--( TKINTER )--####################################################################################################################################################################### | |
root = Tk() | |
width, height = imagen_.size | |
canvas = Canvas(root, width=width, height=height) | |
canvas.pack(expand=YES, fill=BOTH) | |
imagen_canvas = ImageTk.PhotoImage(imagen_) | |
imagen_canvas_setting = canvas.create_image((2, 2), image=imagen_canvas, anchor=NW) | |
root.mainloop() | |
################################################################################################################################################################################################################## | |
main() |
Viendo tus rectas es obvio que algo aritmético va mal. Mejor dibuja el segmento para un sólo par de puntos para ver qué está mal (orientación, selección del par, algo de índices, etc.) 3 pts.
ResponderEliminarNP tarea 6.
ResponderEliminar