|
import Image |
|
import os |
|
import sys |
|
import numpy |
|
import pywt |
|
import random |
|
|
|
#Convierte la imagen original a escala de grises y regresa la variable Image de la imagen a escala de grises |
|
def grises(im, name, ext): |
|
x, y = im.size |
|
pixeles = im.load() |
|
|
|
for i in range(x): |
|
for j in range(y): |
|
(r,g,b) = pixeles[i,j] #Obtengo el rgb del pixel[i, j] de la imagen |
|
suma = r + g + b #Sumo las variables |
|
promedio = int(suma/3) #Obtengo el promedio de la suma |
|
#Sustituyo el promedio para cada variable |
|
r = promedio |
|
g = promedio |
|
b = promedio |
|
pixeles[i,j] = (r,g,b) #Se substituye en el pixel[i, j] el nuevo valor rgb |
|
ImGrises = name+"-Grises"+ext |
|
im.save(ImGrises) #Se crea la nueva imagen |
|
return ImGrises |
|
|
|
#Metodo en el cual se obtienen los rgb de cada pixel de la imagen a escala de grises y se agrega el elemento r (de los rgb) a una lista, por ultimo esa lista se convierte a un arreglo de numpy para trabajarlo de la mejor manera |
|
def matriz(ImGrises): |
|
im2 = Image.open(ImGrises) |
|
x, y = im2.size |
|
pixeles = im2.load() |
|
lista1 = list() |
|
for i in range(x): |
|
lista2 = list() |
|
for j in range(y): |
|
lista2.append(pixeles[i,j][0]) #Agrego a la lista el primer elemento del arreglo, como son iguales puedo poner o el segundo o el tercero |
|
lista1.append(lista2) |
|
arreglo = numpy.array(lista1) #Convierto la lista a arreglo de numpy para poderlo utilizar |
|
return arreglo |
|
|
|
#En este metodo se obtiene el arreglo, el cual sera utilizado para crear la imagen comprimida |
|
def pequeno(arreglo, umbral): |
|
j = pywt.Wavelet('haar') #Se define el wavelet a usar |
|
var = pywt.wavedec2(arreglo, j, level=2) #Se descompone el arreglo |
|
|
|
a, b, coeficientes = var #Se guarda en tres variables la descomposicion del arreglo |
|
|
|
lista = list() #Lista provisional que tendra el resultado de la transformada de cada elemento de la fila de coeficientes comparada con el umbral |
|
for i in coeficientes: |
|
c = numpy.where(((i > umbral)), i, 0) #Se busca en todo el arreglo i si alguno cumple la condicion si lo cumple valor se cambia por 0 |
|
lista.append(c) |
|
|
|
#Lista que tendra los nuevos coeficientes |
|
lisfi = list() |
|
lisfi.append(a) |
|
lisfi.append(b) |
|
lisfi.append(tuple(lista)) |
|
|
|
arrfi = pywt.waverec2(lisfi, j) #Arreglo que almacena los valores de la lista final aplicados la transformada de wavelet |
|
arrint = arrfi.astype(int) #Convertimos todo el arreglo a integer |
|
return arrint |
|
|
|
#Se crea la imagen comprimida en base al arreglo generado de la transformada inversa, se barre en x y despues en y, en cada pixel[x][y] se agrega su rgb correspondiente |
|
def crearImagen(x, y, nuearreglo, name, extension, umbral): |
|
nimagen = Image.new('RGB', (x, y)) #Variable del tipo image de un tamano x, y de formato RGB |
|
|
|
lista = list() |
|
for i in nuearreglo: |
|
lista2 = list() #Lista provisional que almacenara los rgb para cada fila i |
|
for j in i: |
|
lista2.append((int(j), int(j), int(j))) #Se agrega a la lista el elemento i, j |
|
lista.append(lista2) #Se agrega a la lista final los rgb de la fila i |
|
|
|
#Se barre la lista final para agregarlo a la imagen a crear |
|
for i in range(x): |
|
for j in range(y): |
|
nimagen.putpixel((i, j), lista[i][j]) #Se agrega el pixel i, j el elemento RGB correspondiente de la lista |
|
nimagen.save(str(name)+"-Compress con "+str(umbral)+" de Umbral"+str(extension)) #Se crea la imagen |
|
nombre = name+"-Compress con "+str(umbral)+' de Umbral'+extension+"" |
|
return nombre |
|
|
|
def detumbral(x, y): |
|
umbral = int((x+y)/2) |
|
if umbral > 255: |
|
#if umbral > x: |
|
while True: |
|
umbral = umbral / 2 |
|
if umbral <= 255: |
|
#if umbral <= x: |
|
break |
|
elif umbral < 0: |
|
umbral = 1 |
|
|
|
return umbral |
|
|
|
def comparar(ncompre, ngris, x, y): |
|
imcompre = Image.open(ncompre) |
|
infogri = Image.open(ngris) |
|
|
|
infogri = os.stat(ngris) |
|
infocompre = os.stat(ncompre) |
|
|
|
tamgri = int(infogri.st_size) |
|
tamcompre = int(infocompre.st_size) |
|
|
|
print "Tamano imagen en escala de grises: ",tamgri, "bytes" |
|
print "Tamano imagen comprimida: ",tamcompre, "bytes" |
|
|
|
porcompress = (float(tamcompre)*100.0) / float(tamgri) |
|
porcompress = 100.0 - porcompress |
|
print "Porcentaje de Compresion: "+str(porcompress)+"%" |
|
|
|
def main(): |
|
|
|
Archivo = str(sys.argv[1]) |
|
|
|
extension = Archivo[-4:] |
|
nombre = Archivo[:-4] |
|
info = os.stat(Archivo) |
|
|
|
im = Image.open(Archivo) |
|
x, y = im.size |
|
|
|
print "Ancho Imagen: ", x |
|
print "Alto Imagen: ", y |
|
|
|
#Se determinal el umbral, si es dado por el usuario con que este dentro del rango no hay problema si se pasa se genera aleatoriamente; si no se da el umbral se aplica el metodo para determinar el umbral |
|
try: |
|
umbral = int(sys.argv[2]) #Umbral dado por el usuario, debe de ser entre 1 y 255 |
|
if umbral > 255 or umbral <= 0: #Si no se cumple la condicion el umbral se da de forma aleatoria |
|
umbral = random.randint(1, 255) |
|
print "Umbral dado no esta en el rango por lo que se genera aleatoriamente: ", umbral |
|
else: |
|
print "Voy por el umbral que diste: ", umbral |
|
except: |
|
umbral = detumbral(x, y) |
|
print "Voy por el umbral del metodo: ", umbral |
|
|
|
ImGrises = grises(im, nombre, extension) #Se crea la imagen a escala de grises |
|
Arreglo = matriz(ImGrises) #Guarda en un arreglo |
|
|
|
narreglo = pequeno(Arreglo, umbral) |
|
imfinal = crearImagen(x, y, narreglo, nombre, extension, umbral) |
|
|
|
print "Tamano imagen original: ",info.st_size, "bytes" |
|
comparar(imfinal, ImGrises, x, y) |
|
|
|
main() |