Created
April 20, 2016 05:32
-
-
Save ripper2hl/e9f184fcbc8fcaf8625d05a0072ac13f to your computer and use it in GitHub Desktop.
Script en python que busca y encuentra agujeros en imagenes
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
| from PIL import Image; | |
| from PIL import ImageDraw; | |
| import numpy as np; | |
| from sys import argv; | |
| import random; | |
| VERTICAL = 1; | |
| HORIZONTAL = 0; | |
| MAXIMA = 1; | |
| MINIMA = 0; | |
| size = 16; | |
| def get_peaks(vector, type = MAXIMA): | |
| pos = [] | |
| maximo = max(vector) | |
| minimo = min(vector) | |
| umbral = (maximo + minimo)/2 | |
| for i in range(1, len(vector) - 1): | |
| if type == MAXIMA: | |
| if (vector[i] > vector[i-1]) and (vector[i] > vector[i+1]): | |
| pos.append(i) | |
| if vector[i] > umbral: pos.append(i) | |
| elif type == MINIMA: | |
| if (vector[i] < vector[i-1]) and (vector[i] < vector[i+1]): | |
| pos.append(i) | |
| if vector[i] > umbral: pos.append(i) | |
| return pos | |
| def binarize(im, umbral): | |
| w, h = im.size | |
| pix = im.load() | |
| out = Image.new( 'RGB', ( w, h) ); | |
| outPix = out.load(); | |
| for i in range( w ): | |
| for j in range( h ): | |
| r, g, b = pix[ i, j ]; | |
| if r > umbral: | |
| outPix[i, j] = ( 255, 255, 255 ); | |
| else: | |
| outPix[ i, j] = (0, 0, 0); | |
| return out; | |
| def crearHistogramaVertical(imagen): | |
| imagenTemporal = imagen.copy(); | |
| pix = np.array( imagenTemporal.convert('L') ); | |
| return [sum(x) for x in zip(*pix)]; | |
| def crearHistogramaHorizontal(imagen): | |
| imagenTemporal = imagen.copy(); | |
| pix = np.array(imagenTemporal.convert('L')); | |
| return [sum(x) for x in pix]; | |
| def verificarArea( imagen, (x1, y1), (x2, y2) ): | |
| w, h = imagen.size; | |
| pix = imagen.load(); | |
| area = abs(x2 - x1) * abs(y2 - y1); | |
| contador = 0; | |
| i, j = (None, None); | |
| for x in range(x1, x2): | |
| for y in range(y1, y2): | |
| if x > 0 and x < w and y > 0 and y < h: | |
| if pix[x, y] == (0, 0, 0): | |
| i, j = x, y; | |
| contador += 1; | |
| if contador > area * 0.2: | |
| return True, (i, j); | |
| else: | |
| return False, (i, j); | |
| #Ejemplo1 --> http://www.razko.nl/solving-paper-mazes-with-python/ | |
| #Ejemplo2 --> http://stackoverflow.com/questions/12995434/representing-and-solving-a-maze-given-an-image | |
| def busquedaAnchura(imagen, origen, color): | |
| pix = imagen.load(); | |
| ancho, altura = imagen.size; | |
| q = []; | |
| coordenadas = []; | |
| q.append(origen); | |
| original = pix[origen]; | |
| while len( q ) > 0: | |
| (x, y) = q.pop(0); | |
| actual = pix[x, y]; | |
| if actual == original or actual == color: | |
| for dx in [-1, 0, 1]: | |
| for dy in [-1, 0, 1]: | |
| i, j = (x + dx, y + dy) | |
| if i >= 0 and i < ancho and j >= 0 and j < altura: | |
| contenido = pix[i, j]; | |
| if contenido == original: | |
| pix[i, j] = color; | |
| coordenadas.append((i, j)); | |
| q.append((i, j)); | |
| return len(coordenadas), coordenadas; | |
| def pintarPurpuraObscuro(): | |
| return (random.randint( 120, 230 ), random.randint( 0, 100 ), random.randint( 108, 255 ) ); | |
| def pintarPurpuraClaro(): | |
| return ( random.randint( 150, 230), random.randint( 100, 230), random.randint( 158 , 255 ) ); | |
| def dibujarPicos(imagenOriginal, vertical, horizontal): | |
| w, h = imagenOriginal.size; | |
| imagen = Image.open(argv[1]); | |
| draw = ImageDraw.Draw(imagen); | |
| pix = imagen.load(); | |
| id = 1; | |
| total = w * h; | |
| areas = []; | |
| for j in horizontal: | |
| for i in vertical: | |
| (x1, y1), (x2, y2) = ( i - ( size / 2 ), j - ( size / 2 ) ), ( i + ( size / 2 ), j + ( size / 2 ) ); | |
| confirm, begin = verificarArea( imagenOriginal, (x1, y1), (x2, y2 ) ); | |
| if confirm: | |
| if begin is not (None, None): | |
| n, coordenadas = busquedaAnchura( imagenOriginal, begin, (255, 0, 0)); | |
| suma = [ sum( x ) for x in zip( *coordenadas ) ] | |
| centro = ( suma[0] / len(coordenadas), suma[1] / len(coordenadas) ); | |
| pix[centro] = (255, 255, 0); | |
| areas.append(n); | |
| draw.ellipse( ( ( centro[0] - size / 2 , centro[1] - size / 2 ), | |
| (centro[0] + size / 2 , centro[1] + size / 2 ) ), outline = pintarPurpuraObscuro(), | |
| fill = pintarPurpuraClaro() ); | |
| draw.text( centro, "%s" %id, fill = (0, 0, 0) ); | |
| id += 1; | |
| for i in range(len(areas)): | |
| print "ID del agujero: %s Area: %0.2f%%"% (i, 100.0 * ( areas[i] / float( total ) ) ); | |
| imagen.save('final-' + str( random.randint(0,9) ) + '.png', 'PNG'); | |
| #fuente --> http://scipy.github.io/old-wiki/pages/Cookbook/SignalSmooth | |
| def alisar( histograma , dimensionVentanaSuavizado = 11, tipoVentana = 'flat'): | |
| if histograma.ndim != 1: | |
| raise ValueError, "El alisamiento solo acepta arreglos de una dimension"; | |
| if histograma.size < dimensionVentanaSuavizado: | |
| raise ValueError, "El vector debe ser mas grande que el tamano de la ventana"; | |
| if dimensionVentanaSuavizado < 3: | |
| return histograma; | |
| s=np.r_[ histograma [ dimensionVentanaSuavizado - 1 : 0 : -1 ] , histograma, histograma[ -1 : - dimensionVentanaSuavizado : -1 ] ]; | |
| if tipoVentana == 'flat': | |
| w = np.ones( dimensionVentanaSuavizado ,'d' ); | |
| else: | |
| w = eval( 'np.' + tipoVentana + '(dimensionVentanaSuavizado)' ); | |
| return np.convolve( w / w.sum(), s , mode='valid' ) | |
| def main(): | |
| imagen = Image.open( argv[1] ).convert( 'RGB' ); | |
| imagen = binarize( imagen, 80 ); | |
| histogramaVertical = crearHistogramaVertical( imagen ); | |
| histogramaHorizontal = crearHistogramaHorizontal( imagen ); | |
| vertical = list( alisar( np.array( histogramaVertical ) ) ); | |
| horizontal = list( alisar( np.array( histogramaVertical ) ) ); | |
| dibujarPicos(imagen, get_peaks(vertical, type = MINIMA), get_peaks(horizontal, type = MINIMA)); | |
| if __name__ == "__main__": | |
| main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment