30 julio 2009

Codificación RLE para una imagen binaria en MATLAB

La codificacion RLE (Run Length Encoding) se aplica a cadenas de caracteres en las cuales existe una secuencia de datos. En este caso tenemos una imagen binaria, que es resultado de aplicar la extracción de bits a una imagen en escala de grises, como se pretende extraer solo un bit en especifico de la imagen, pues el resultado es una imagen binaria, en la cual se tienen valores de 0 o 1 dependiendo del valor del pixel. La imagen será del mismo tamaño de la imagen original puesto que es una operación de pixel por pixel.

Para visualizar de mejor manera lo que se intenta hacer aquí es menester mostrar un ejemplo. La imagen es una matriz de 2D de MxN, y tendremos para una imagen de 8x8 una matriz como la siguiente:

 
Bit Extraction Example

De lo anterior se desprende:

a) Aquí podemos observar la imagen de 8x8 original, en la cual cada valor de la matriz representa un pixel de 8 bits, o sea valores de 0-255.

b) En esta imagen se representa cada valor en su equivalente binario, con el propósito de visualizar el valor en bits de cada pixel.

c) El ultimo ejemplo de estas tres imágenes muestra el valor extraído de cada pixel para el bit mas significativo (MSB), o sea el bit 8.

La matriz que nos interesa es la matriz contenida en c). Para poder codificarla tenemos que tener una cadena de valores en los cuales existan secuencias de valores repetidos. En este caso son solo 0 y 1, y dado a que es una matriz 2D, tenemos que redimensionarla a 1D, y quedaría como se muestra a continuación:

 

Matiz 1D de bits extraídos

Tenemos una secuencia de valores que se representa en 16 caracteres, y debido a que sabemos que tendremos una secuencia de ceros y unos es importante notar el primer número y después de ahí solo se irán alternando.

Necesitamos establecer una manera de poder decodificar nuestra cadena de caracteres, y reconstruir la imagen original, necesitamos saber un par de datos para regresar a nuestra imagen original. Como se decía en el párrafo anterior es necesario saber con que valor se empieza la secuencia de caracteres, también es necesario saber el tamaño de la imagen original, para que al reconstruir la secuencia unidimensional la podamos regresar a 2D de la misma manera que la original.

Así que el encabezado nos quedará mas o menos de la siguiente manera: Fb M N . . . Secuencia . . .

En donde Fb es el primer caracter, M y N es el tamaño de la imagen original y Secuencia, como su nombre lo indica es la cadena de valores que vamos a almacenar iniciando con Fb y alternando hasta terminar. El ejemplo anterior nos quedaría como a continuación:

1 8 8 1 1 1 4 1 3 1 1 1 1 1

Ahora si, despues de tanto rollo, aqui esta el código en MATLAB para hacer esto.

a = imread('c:\matlab7\work\lena.pgm');
[cols rows] = size(a);
b = BitExtraction(a,8,1,1);
figure(1); imshow(a);
figure(2); imshow(uint8(b));
myEncodedImageB = EncodeRLEimage(b);

Este es el código de la función para extraer bits de la imagen:

function x = BitExtraction(myImagen, B, n ,L)

myImagenNueva = myImagen;
[rows cols] = size(myImagen);

for i = 1 : rows
    for j = 1 : cols
        u = double(myImagen(i,j));
        iEne = floor(u/2^(B-n));
        iEneMenosUno = floor(u/2^(B-(n-1)));
       BitExtraido = iEne - (2*iEneMenosUno);
       if BitExtraido == 1
           BitExtraido = L;
       else
           BitExtraido = 0;
       end
       myImagenNueva(i,j) = BitExtraido;
    end
end
x = myImagenNueva;

Este es la función encargada de codificar la imagen.

function eImg = EncodeRLEimage(myImage)
    encoded = [];
    [cols rows] = size(myImage);
    img1D = double(reshape(myImage,1,[]));
    SizeOf1D = cols*rows;
    counter = 0;
    encoded = [img1D(1)];
    for i =1:SizeOf1D-1
        if img1D(i)==img1D(i+1)
            counter=counter+1;
        else
            encoded = [encoded counter];
            counter = 1;
        end
    end

    if counter ~= 1
    encoded = [encoded counter+1];
    end

    eImg = encoded;

¿Sirve de algo?

2 comentarios:

  1. Buen Dia, luego de colocar este código, en teoría que nos debería ejecutar¿?
    aparte me aparece un error en: Function definitions are not permitted in this context. en function x

    ResponderEliminar
  2. Si, este código debe funcionar bien. Yo lo tomé de un proyecto que hice.

    ¿que te marca de error? ¿cuál es el mensaje completo?

    ResponderEliminar

This is I

Blog dedicado a escribir sobre Sistemas Embebidos y el Internet de las Cosas o IoT que le llaman.