def BFS(imagen, inicio, color): #Busqueda de anchura para determinar una figura pixeles = imagen.load() altura, ancho = imagen.size fila, columna = inicio original = pixeles[fila, columna] cola = [] cola.append((fila, columna)) masa = [] c = [] while len(cola) > 0: (fila, columna) = cola.pop(0) actual = pixeles[fila, columna] if actual == original or actual == color: for dx in [-1, 0, 1]: for dy in [-1, 0, 1]: candidato = (fila + dy, columna + dx) if candidato[0] >= 0 and candidato[0] < altura and candidato[1] >= 0 and candidato[1] < ancho: contenido = pixeles[candidato[0], candidato[1]] if contenido == original: pixeles[candidato[0], candidato[1]] = color imagen.putpixel((candidato[0], candidato[1]), color) cola.append(candidato) masa.append((candidato[0], candidato[1])) c.append((candidato[0], candidato[1])) return imagen, masa, c def aplicar_BFS(imagen_BFS): #aplica busqueda de anchura a todas las figuras encontradas con color aleatorio pixeles = imagen_BFS.load() x, y = imagen_BFS.size colores = [] elipses = [] for a in range(x): for b in range(y): if pixeles[a, b] == (255, 255, 255): color = (random.randint(0,255), random.randint(0,255), random.randint(0, 255)) imagen_BFS, masa, c = BFS(imagen_BFS.convert("RGB"), (a, b), color) elipses.append(c) x_suma = 0 y_suma = 0 for i in range(len(masa)): x_suma = x_suma + masa[i][0] y_suma = y_suma + masa[i][1] x_centro = x_suma/len(masa) y_centro = y_suma/len(masa) colores.append([color, 0, (x_centro, y_centro)]) pixeles = imagen_BFS.load() masa = [] #suma la cantidad de colores diferentes en la imagen pixeles = imagen_BFS.load() for a in range(x): for b in range(y): for n in range(len(colores)): if colores[n][0] == pixeles[a,b]: colores[n][1] = colores[n][1] + 1 print colores suma = 0 for i in range(len(colores)): suma = suma + colores[i][1] global frame y = frame.winfo_height() #Obtenemos porcentajes prom = [] for i in range(len(colores)): promedio = float(colores[i][1])/float(suma)*100.0 if promedio > 3.0: print "Porcentajes: " print "Figura " + str(i) + ": " + str(promedio) prom.append((i, promedio, colores[i][0])) maxim = 0.0 for i in range(len(prom)): if maxim < prom[i][1]: maxim = prom[i][1] fig = prom[i][0] color_max = prom[i][2] #Itentificamos fondo y lo pintamos a gris print "Fondo fig: " + str(fig) imagen_BFS = pinta_fondo(imagen_BFS, color_max) #poner_imagen(imagen_BFS) return imagen_BFS, colores, elipses def pinta_fondo(imagen_BFS, color_max): #pintamos fondo de manera que obtenemos el color que predomina en la imagen pixeles = imagen_BFS.load() x, y = imagen_BFS.size for a in range(x): for b in range(y): if pixeles[a, b] == color_max: color = (100,100,100) imagen_BFS, masa, c = BFS(imagen_BFS.convert("RGB"), (a, b), color) return imagen_BFS def boton_elipse(): inicio = time.time() label.destroy() max = 0 suma = 0.0 #A grises imagen = cambiar_agrises(path_imagen_original) imagen.save("paso_1.jpg") votos = list() #A grises imagen = cambiar_agrises(path_imagen_original) imagen.save("paso_1.jpg") #Agrego Laplaciana h_lap = numpy.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]]) imagen_prom, puntos = convolucion(imagen, numpy.multiply(1.0/1.0,h_lap)) imagen_prom = cambiar_umbral(imagen_prom, 0.5) imagen_prom.save("paso_2.jpg") #Agrego normalizacion imagen_nor = normalizacion(imagen_prom) imagen_nor.save("paso_3.jpg") #Agrego umbral para binarizar umbral_valor = 0.1 imagen_bin = cambiar_umbral(imagen_nor.convert("RGB"), umbral_valor) imagen_bin.save("paso_4.jpg") #Pongo promedio imagen_prom = cambiar_promedio(imagen_bin.convert("RGB")) imagen_prom.save("paso_5.jpg") #Agrego umbral para binarizar umbral_valor = 0.08 imagen_bin2 = cambiar_umbral(imagen_prom.convert("RGB"), umbral_valor) imagen_bin2.save("paso_6.jpg") #Pongo promedio imagen_prom = cambiar_promedio(imagen_bin2.convert("RGB")) imagen_prom.save("paso_7.jpg") #Pongo promedio imagen_prom = cambiar_promedio(imagen_prom.convert("RGB")) imagen_prom.save("paso_8.jpg") #Agrego umbral para binarizar umbral_valor = 0.5 imagen_BFS = cambiar_umbral(imagen_prom.convert("RGB"), umbral_valor) imagen_BFS.save("paso_9.jpg") #Se aplica BFS imagen_BFS, colores, elipses = aplicar_BFS(imagen_BFS) imagen_BFS.save("paso_10.jpg") x, y = imagen_BFS.size pixeles = imagen_BFS.load() bordes_detectados = [] #Se aplican mascaras de sobel h_Y = numpy.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]) h_X = numpy.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]]) imagen_hori, puntos_GX = convolucion(imagen, numpy.multiply(1.0/1.0,h_X)) imagen_hori.save("paso_sobelX.jpg") pixeles_GX = imagen_hori.load() imagen_verti, puntos_GY = convolucion(imagen, numpy.multiply(1.0/1.0,h_Y)) imagen_verti.save("paso_sobelY.jpg") pixeles_GY = imagen_verti.load() #Empezamos a detectar elipses y circulos dibuja = ImageDraw.Draw(imagen_BFS) x, y = imagen_BFS.size puntos = numpy.zeros(x*y).reshape((x, y)) centros = [] for elipse in elipses: x, y = imagen_BFS.size puntos = numpy.zeros(x*y).reshape((x, y)) #Sacamos 2000 puntos aleatorios para calcular el centro mas preciso for i in range(2000): tam = len(elipse) punto_1 = elipse[randint(0,tam-1)] punto_2 = elipse[randint(0,tam-1)] x_1 = punto_1[0] y_1 = punto_1[1] x_2 = punto_2[0] y_2 = punto_2[1] gx_1 = puntos_GX[x_1, y_1] gy_1 = puntos_GY[x_1, y_1] gx_2 = puntos_GX[x_2, y_2] gy_2 = puntos_GY[x_2, y_2] gx_1 = - float(gx_1) gx_2 = - float(gx_2) x_22 = x_2 y_22 = y_2 x_11 = x_1 y_11 = y_1 if abs(gx_1) + abs(gy_1) <= 0: theta = None else: theta = atan2(gy_1, gx_1) l = 50 if theta is not None: theta = theta-(pi/2) x_1 = x_11 - l * cos(theta) y_1 = y_11 - l * sin(theta) x_2 = x_11 + l * cos(theta) y_2 = y_11 + l * sin(theta) if abs(gx_2) + abs(gy_2) <= 0: theta = None else: theta = atan2(gy_2, gx_2) if theta is not None: theta = theta-(pi/2) x_3 = x_22 - l * cos(theta) y_3 = y_22 - l * sin(theta) x_4 = x_22 + l * cos(theta) y_4 = y_22 + l * sin(theta) y_medio = (y_11+y_22) / 2 x_medio = (x_11+x_22) / 2 pixeles = imagen_BFS.load() try: Px = ((x_1*y_2-y_1*x_2)*(x_3-x_4)-(x_1-x_2)*(x_3*y_4-y_3*x_4))/((x_1-x_2)*(y_3-y_4)-(y_1-y_2)*(x_3-x_4)) Py = ((x_1*y_2-y_1*x_2)*(y_3-y_4)-(y_1-y_2)*(x_3*y_4-y_3*x_4))/((x_1-x_2)*(y_3-y_4)-(y_1-y_2)*(x_3-x_4)) Dx = Px - x_medio Dy = Py - y_medio m = Dy/Dx x0 = x_medio y0 = y_medio #Obtenemos votos while True: x = x0+1 y = m*(x-x0)+y0 if pixeles[x,y] == (0, 0, 0): puntos[x, y] = puntos[x, y] + 1 x0 = x y0 = y else: break except: pass max = numpy.max(puntos) index = numpy.where(puntos==max) try: mayor_x = sum(index[0])/len(index[0]) mayor_y = sum(index[1])/len(index[0]) #dibuja.ellipse((mayor_x-2, mayor_y-2, mayor_x+2, mayor_y+2), fill="blue") centros.append((mayor_x, mayor_y)) except: mayor_x = index[0] mayor_y = index[1] #dibuja.ellipse((mayor_x-2, mayor_y-2, mayor_x+2, mayor_y+2), fill="blue") centros.append((mayor_x, mayor_y)) #de los mayores detectados, los utilizamos como centros r_x = [] r_y = [] pixeles_imagen = imagen_BFS.load() for i in range(len(centros)): x0 = int(centros[i][0]) y0 = int(centros[i][1]) while True: y0 = y0 + 1 if pixeles_imagen[x0, y0] != (0, 0, 0): r_y.append((x0, y0)) break for i in range(len(centros)): x0 = int(centros[i][0]) y0 = int(centros[i][1]) while True: x0 = x0 + 1 if pixeles_imagen[x0, y0] != (0, 0, 0): r_x.append((x0, y0)) break Radios = [] x, y = imagen_BFS.size print "Semidiametros perpendiculares del elipse" for i in range(len(centros)): x0 = int(centros[i][0]) y0 = int(centros[i][1]) x1 = int(r_x[i][0]) y1 = int(r_x[i][1]) x2 = int(r_y[i][0]) y2 = int(r_y[i][1]) Rx = sqrt((x1-x0)**2+(y1-y0)**2) Ry = sqrt((x2-x0)**2+(y2-y0)**2) #si los radios son iguales, es un circulo if Rx == Ry: cad = "Es circulo" else: cad = "Es elipse" porcentaje = float(Rx * 100)/float(x) print "ID: %s SemiDiametro: %s Porcentaje: %s %s" % (i, Rx, porcentaje, cad) #Radios.append((Rx, Ry)) color = (255, 255, 255) a = 0 #Pintamos en los 360 grados while a < 2*pi: x4, y4 = x0 + Rx * sin(a), y0 + Ry * cos(a) a = a + 0.01 dibuja.ellipse((x4-2, y4-2, x4+2, y4+2), fill=color) for i in range(len(centros)): #Agregamos BFS empezando por el centro del circulo o elipse capturado color = (random.randint(0,255), random.randint(0,255), random.randint(0, 255)) imagen_BFS, masa, c = BFS(imagen_BFS.convert("RGB"), (int(centros[i][0]), int(centros[i][1])), color) dibuja.ellipse((centros[i][0]-2, centros[i][1]-2, centros[i][0]+2, centros[i][1]+2), fill="blue") poner_imagen(imagen_BFS) global frame y = frame.winfo_height() for i in range(len(centros)): label_fig = Label(text = str(i)) label_fig.place(x = centros[i][0], y = centros[i][1] + y) imagen_BFS.save("paso_lineas.jpg") #Tiempo fin = time.time() tiempo = fin - inicio print "Tiempo que trascurrio -> " + str(tiempo) return tiempo