miércoles, 29 de mayo de 2013

Entrada # 6

Teoría de la Información Y 
Métodos de Codificación
 
Image Compressor

The process effected was as follows:
  • Get an image .jpg what is asked the user.
  • Convert this image a gray scale.
  • It loads in an array one of variables rgb (As in each rgb the elements are equal, you take only one).
  • Decomposes the array using the library wavedec2 of pywt, the result gives us three variables, the first 2 are used only to rebuild the array. The last is applied one process (this is the coefficient variable).
  • Make new array of coefficient using the variable coefficient, sweep every element of the array and compares with the threshol, if data success the condition the value of the array is 0. All data (success the condition or not) save in the array.
  • Add in the new list the 2 variable and the array and aplied the method waverec2 and get one array, this array can change to integer for continue. This array is used to create the new image.
  • Sweep the array get every pixel of the image with your rgb (every element x 3) and create the new image.
  • Compare the weight of the image in gray scale with the compress for obtain the compress percentage.

Code Used

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()
Código

Make Test

We have the image:


Size 308 x 328

Aplied the Code



Image to gray scale:


Compress the image with threshold of 230. 



Test with different threshold:
Threshold 10


Threshold 159


As see in the images, while the threshold is high the quality of the image decreases so the compression become greater.

This can be rectify in the picture of below, which shows the result of the execution:



References

http://www.pybytes.com/pywavelets/ref/2d-dwt-and-idwt.html

1 comentario:

  1. Mala ortografía. Hubiera sido bueno medir los tiempos de ejecución. El reporte es además algo breve. 4 pts por el reporte.

    El método no es muy original; el simplemente llamadas a librerías y código ejemplo. Por mínimo tiene algo de comentarios... 6 pts por ello. Te veo en segundas.

    ResponderEliminar