Skip to content

Instantly share code, notes, and snippets.

@ripper2hl
Created April 20, 2016 05:32
Show Gist options
  • Select an option

  • Save ripper2hl/e9f184fcbc8fcaf8625d05a0072ac13f to your computer and use it in GitHub Desktop.

Select an option

Save ripper2hl/e9f184fcbc8fcaf8625d05a0072ac13f to your computer and use it in GitHub Desktop.
Script en python que busca y encuentra agujeros en imagenes
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