miércoles, 13 de febrero de 2013

PIL: Putpixel and Getpixel vs Array

En ésta entrada, veremos una comparativa respecto a la demora que se lleva en el procesamiento de una imagen con la librería de PIL.
Realizando las tareas respecto al tema, me encontré con un ligero problema que al analizarlo y compararlo tiene consecuencias como esperar un resultado de una determinada imagen. Así que me puse a investigar y buscar otra forma del poder procesar una imagen con PIL y me encontré con el uso de arreglos manipulados con la misma imagen.

Breve discusión:
Siendo un poco breve y analizando mi código encontré que las subrutinas getpixel y putpixel son un poco pesadas, ya que estamos manipulando y procesando la imagen en el momento que se carga determinado pixel y su determinado color, a comparación del uso de las listas con la subrutina load() donde cargamos la imagen en el arreglo, donde cada elemento contiene una tupla, siendo más ligera y fácil su manipulación.

Código:
En el siguiente código veremos como trabaja el procesar una imagen con lo ya antes mencionado aplicada a una imagen normal buscando obtener la escala de grises.

img.putpixel() & img.getpixel
def grayScale(self):
start = time.time()
self.rgb = self.img.convert('RGB')
for i in range(self.img.size[0]):
for j in range(self.img.size[1]):
r = self.rgb.getpixel((i, j))[0]
g = self.rgb.getpixel((i, j))[1]
b = self.rgb.getpixel((i, j))[2]
media = (r+g+b)/3
pixel = tuple([media, media, media])
self.img.putpixel((i, j), pixel)
self.img.save('grayScale.png', 'PNG')
end = time.time()
print 'Tiempo tomado: '+str(end-start)
return self.img
img.load()
def grayScale2(self):
start = time.time()
w, h = self.img.size
for i in range(w):
for j in range(h):
r = self.pixel[i,j][0]
g = self.pixel[i,j][1]
b = self.pixel[i,j][2]
media = (r+g+b)/3
self.pixel[i,j] = (media, media, media)
self.img.save('grayScale.png', 'PNG')
end = time.time()
print 'Tiempo tomado: '+str(end-start)
return self.img


Resultados:
[511x684]

[511x684]

Como podemos notar en la siguiente imagen haciendo varios test de la misma imagen se encontró que el primer tiempo arrojado emplea el uso de getpixel y putpixel teniendo una demora aproximada de 3.2 segundos y en el segundo empleado el uso de arreglos obtuvo una demora aproximada de 0.7 segundos.
Podemos discutir que se tiene una reducción del 82% del tiempo empleado, siendo una mejora muy significante en el tiempo al momento de manipular imagenes.


Código Completo:

from PIL import Image
from sys import argv
import time
class Filtro(object):
"""docstring for Filtro"""
def __init__(self, fileName):
self.img = Image.open(fileName)
self.pixel = self.img.load()
def grayScale(self):
start = time.time()
self.rgb = self.img.convert('RGB')
for i in range(self.img.size[0]):
for j in range(self.img.size[1]):
r = self.rgb.getpixel((i, j))[0]
g = self.rgb.getpixel((i, j))[1]
b = self.rgb.getpixel((i, j))[2]
media = (r+g+b)/3
pixel = tuple([media, media, media])
self.img.putpixel((i, j), pixel)
self.img.save('grayScale.png', 'PNG')
end = time.time()
print 'Tiempo tomado: '+str(end-start)
return self.img
def grayScale2(self):
start = time.time()
w, h = self.img.size
for i in range(w):
for j in range(h):
r = self.pixel[i,j][0]
g = self.pixel[i,j][1]
b = self.pixel[i,j][2]
media = (r+g+b)/3
self.pixel[i,j] = (media, media, media)
self.img.save('grayScale.png', 'PNG')
end = time.time()
print 'Tiempo tomado: '+str(end-start)
return self.img
def main():
im = argv[1]
imagen = Filtro(im)
imagen.grayScale()
imagen.grayScale2()
main()

No hay comentarios:

Publicar un comentario