viernes, 24 de mayo de 2013

Laboratorio Wavelets - Puntos extra

Para esta entrada de laboratorio por puntos extra se nos pidió utilizar wavelets.

Que  son:

Las wavelets son funciones que satisfacen  ciertos requerimientos ,la transformada wavelet es una de las técnicas más recientes propuestas para resolver problemas de compresión de imágenes, relevamiento de bordes y análisis de texturas. El interés por este nuevo instrumento matemático nace de la posibilidad que el mismo ofrece de superar algunas de las limitaciones que se enfrentan al emplear otras transformaciones, entre las que se destaca la muy conocida transformación de Fourier.  


Existen tres tipos posibles: transformada continua wavelet (CWT), expansión en serie wavelet
y transformada discreta wavelet (DWT). 


Donde se utiliza:

La transformada wavelet discreta (DWT) es comúnmente utilizada en ingeniería y ciencias de la computación para la codificación de señales, mientras que la transformada wavelet continua (CWT) es
empleada en investigación científica para el análisis de señales. Las transformadas wavelet han sido adoptadas como herramientas para un vasto número de aplicaciones de naturaleza diversa, reemplazando a menudo a la transformada de Fourier convencional.

Muchas áreas de la física han testimoniado este cambio de paradigma, incluyendo dinámica molecular, astrofísica, geofísica sísmica, óptica, mecánica de turbulencia y mecánica cuántica. Otras áreas que han experimentado este cambio son: procesamiento de imágenes, análisis de señales médicas, análisis de proteínas y de ADN, climatología, topografía y geografía, reconocimiento del habla, gráficos computacionales, procesamiento de señales y análisis multifractal. Uno de los usos principales de las wavelets es la compresión de datos, mejora de imágenes y fusión de imágenes.

Ejemplo


Para el ejemplo que se dejara aquí abajo se utilizo la Cohen-Daubechies-Feauveau wavelet que históricamente es la primer familia de wavelets biortogonales. Para estos ejemplos se utilizo la Cohen–Daubechies–Feauveau 9/7 o abreviada la transformada de wavelet CDF 9/7 que es una wavelet es biortogonal.


Lo que se hizo fue una implementacion del wavelet y su transformada inversa. Para que se aprecie mes claramente como funciona aquí se deja un video de su funcionamiento y lo que realiza.

Aunque en el video no se aprecia a alcanzar a ver muy bien por la calidad ya que es muy mala, pero de igual manera se dejan las imágenes de resultados aquí abajo.


Se utilizaron imágenes en escala de grises para ya omitir su transformación. Imágenes de resultados

Original


 












Aplicando Wavelet




























Inversas
























CÓDIGO

from PIL import Image
import sys
def dosdimension(lista, nniveles=1):
# Realizar la transformada CDF 9/7 en matriz 2D
# donde nniveles es el numero de veces deseado para transformar recursivamente la senal''
w = len(lista[0])
h = len(lista)
for i in range(nniveles):
lista =wavtrans2di(lista, w, h) # columnas
lista = wavtrans2di(lista, w, h) # filas
w /= 2
h /= 2
return lista
def inversedosdimen(lista, nniveles=1):
# se saca inverso,el valor nniveles debe ser el mismo que los utilizados para realizar en la funcion anterior.
w = len(lista[0])
h = len(lista)
# Find starting size of m:
for i in range(nniveles-1):
h /= 2
w /= 2
for i in range(nniveles):
lista = inverso(lista, w, h) # filas
lista = inverso(lista, w, h) # columnas
h *= 2
w *= 2
return lista
def wavtrans2di(s, ancho, altura):
# 9/7 coeficientes:
a1 = -1.586134342
a2 = -0.05298011854
a3 = 0.8829110762
a4 = 0.4435068522
# escala de coeficientes:
k1 = 0.81289306611596146
k2 = 0.61508705245700002
for columnas in range(ancho): # Hace la transdormada 1D en todas las columnas
for filas in range(1, altura-1, 2):
s[filas][columnas] += a1 * (s[filas-1][columnas] + s[filas+1][columnas])
s[altura-1][columnas] += 2 * a1 * s[altura-2][columnas] # Symmetric extension
for filas in range(2, altura, 2):
s[filas][columnas] += a2 * (s[filas-1][columnas] + s[filas+1][columnas])
s[0][columnas] += 2 * a2 * s[1][columnas]
for filas in range(1, altura-1, 2):
s[filas][columnas] += a3 * (s[filas-1][columnas] + s[filas+1][columnas])
s[altura-1][columnas] += 2 * a3 * s[altura-2][columnas]
for filas in range(2, altura, 2):
s[filas][columnas] += a4 * (s[filas-1][columnas] + s[filas+1][columnas])
s[0][columnas] += 2 * a4 * s[1][columnas]
temp = [[0]*ancho for i in range(altura)]
for filas in range(altura):
for columnas in range(ancho):
if filas % 2 == 0:
temp[columnas][filas/2] = k1 * s[filas][columnas]
else:
temp[columnas][filas/2 + altura/2] = k2 * s[filas][columnas]
for filas in range(ancho):
for columnas in range(altura):
s[filas][columnas] = temp[filas][columnas]
return s
def inverso(s, ancho, altura):
# 9/7 coeficientes inversos
a1 = 1.586134342
a2 = 0.05298011854
a3 = -0.8829110762
a4 = -0.4435068522
# Coeficientes de escala inversa
k1 = 1.230174104914
k2 = 1.6257861322319229
# Intercalado
temp = [[0]*ancho for i in range(altura)]
for columnas in range(ancho/2):
for filas in range(altura):
#transponer las imagenes
temp[columnas * 2][filas] = k1 * s[filas][columnas]
temp[columnas * 2 + 1][filas] = k2 * s[filas][columnas + ancho/2]
for filas in range(ancho):
for columnas in range(altura):
s[filas][columnas] = temp[filas][columnas]
for columnas in range(ancho): #
#Realiza la trasformada inversa 1d
for filas in range(2, altura, 2):
s[filas][columnas] += a4 * (s[filas-1][columnas] + s[filas+1][columnas])
s[0][columnas] += 2 * a4 * s[1][columnas]
for filas in range(1, altura-1, 2):
s[filas][columnas] += a3 * (s[filas-1][columnas] + s[filas+1][columnas])
s[altura-1][columnas] += 2 * a3 * s[altura-2][columnas]
for filas in range(2, altura, 2):
s[filas][columnas] += a2 * (s[filas-1][columnas] + s[filas+1][columnas])
s[0][columnas] += 2 * a2 * s[1][columnas]
for filas in range(1, altura-1, 2):
s[filas][columnas] += a1 * (s[filas-1][columnas] + s[filas+1][columnas])
s[altura-1][columnas] += 2 * a1 * s[altura-2][columnas]
return s
def convimag(lista, pixeles):
for filas in range(len(lista)):
for columnas in range(len(lista[filas])):
pixeles[columnas,filas] = lista[filas][columnas]
if __name__ == "__main__":
imPath = sys.argv[1]
im = Image.open(imPath)
pixeles = im.load()
# Convertir la imagen 2D a una secuencia de 1D
lista = list(im.getdata())
# Convertir la secuencia de 1D a matriz 2D
# Cada sublista representa una fila. El acceso se realiza a traves de m [filas] [columnas].
lista = [lista[i:i+im.size[0]] for i in range(0, len(lista), im.size[0])]
# Todos los elementos de la lista a flotante
for filas in range(0, len(lista)):
for columnas in range(0, len(lista[0])):
lista[filas][columnas] = float(lista[filas][columnas])
# Realiza la transformada en laimagen
lista = dosdimension(lista, 3)
convimag(lista, pixeles) # Convertir la lista de listas a una imagen
im.save("imag1.png")
# Convertir a la inversa
lista = inversedosdimen(lista, 3)
convimag(lista, pixeles) # Convertir la lista inversa de la matriz de las listas a una imagen.
im.save("imag2.png")
view raw gistfile1.py hosted with ❤ by GitHub


Aquí les muestro un ejemplo de la trasformada de Wavelet obtenida desde la liga de wikipedia , que en teoría debería de obtenerse resultados parecidos, habría que hacer algunos ajustes simplemente.



Por mi parte sería todo como pueden observar habría que hacer algunas mejoras en los valores, para obtener resultados mucho mas visibles

Esta fue mi entrada de laboratorio de visión por puntos extras en espera de 5 puntos o mas :).

Fin

Referencias:

Wikipedia(http://en.wikipedia.org/wiki/Cohen-Daubechies-Feauveau_wavelet)[Acceso 23 Mayo ]

Wikipedia (http://en.wikipedia.org/wiki/Wavelet)[Acceso 23 Mayo ]
Wavelet Digest (http://www.wavelet.org/)[Acceso 23 Mayo ]
Wavelets made Simple (http://www.ee.ryerson.ca/~jsantarc/html/theory.html)[Acceso 23 Mayo ]
Una introducción a los Wavelets(http://www.amara.com/IEEEwave/IEEEwavelet.html)[Acceso 23 Mayo]

1 comentario: