Un modelo de algoritmos en C para manejar imágenes .raw (con visualización en Matlab) Introducción a la Computación Clase 22 María Elena Buemi ¿Qué es una imagen digital? Es una función bidimensional f(x,y), donde x e y son coordenadas espaciales y f es la intensidad en esas coordenadas. Imagen Lena Un pixel Usaremos imágenes .raw, donde los datos están almacenados como una tira de bytes, en la que el primer byte corresponde a la esquina superior izquierda de la imagen y el ultimo a la esquina inferior derecha. El tipo será uint8, por lo que en c usaremos unsigned char(valores de 0 a 255). Al usar imágenes raw, no necesitamos librerías especiales. Crear una imagen (en C sin GUI) #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #define filas 256 #define columnas 256 /*crearimagen*/ void crearimagen(unsigned char **im) { int i,j; for (i=0;i<filas;i++) for (j=0;j<columnas;j++){ im[i][j]=i; } } /* Almacenar archivo imagen, ingresa el nombre del archivo y la matriz asociada- */ void guardaimagen(char archivo[], unsigned char **im) { FILE *outfp; int i; outfp=fopen(archivo, "wb"); for(i=0;i<filas;i++) fwrite(im[i],1,columnas,outfp); fclose(outfp); } /*- main--------------------------------------------------------------------*/ int main() { unsigned char **imagen; int i; char nom[20]; imagen=(unsigned char **)malloc (sizeof (unsigned char *)*filas); for (i=0; i<filas; i++) imagen[i]=(unsigned char *)malloc (sizeof (unsigned char )*columnas); crearimagen(imagen); sprintf(nom,"grises.raw"); guardaimagen(nom,imagen); return(0); } Para visualizar el archivo .raw lo hacemos en Matlab Editar esta función y usarla function [img] = readraw( fname, filas, columnas ) % % [img] = readraw( filename, filas, columnas ) % Read RAW data. Each pixels is allocated in 8 bits of data % img = 0; fp = fopen(fname); if fp == -1 disp(['Error: no se puede abrir archivo ' fname]); return; end img = fread(fp, [filas, columnas], 'uint8'); fclose(fp); >> %% desde línea de comandos >> I=0; >> file=fopen('grises.raw'); >> if file=-1 disp(['Error: no se puede abrir archivo 'grises.raw']); return; end >> I= fread(file, [256,256], 'uint8'); >> fclose(file) >> imshow(I',[]) %para visualizar la imagen, el,operador ' lo uso para trasponer la imagen >> >> %si tengo la funcion readraw, solo la uso >> T=readraw('grises.raw',256,256); >> imshow(T,[]) En línea de comando de Matlab Leer imagen raw void leeimagen(char archivo[], unsigned char **im){ FILE *fp; unsigned char ch; int i,j; } fp=fopen(archivo, "rb"); if ( fp == NULL ){ printf("No puedo abrir el archivo \n"); exit(1); } for(i=0;i<filas;i++){ for(j=0;j<columnas;j++){ fread(&ch,sizeof(ch),1,fp); im[i][j]=ch; } } fclose(fp); Crear un efecto y multiplicarlo a lena pixel a pixel Sea la función f(i,j)=1-(1/(sqrt(2)*128)*sqrt((i-128)*(i-128)+(j-128)(j-128))) De modo más general para cualquier tamaño f(i,j)=1-(1/(sqrt(2)*(tamfila/2))*sqrt((i-(fila/2))*(i-fila/2)+(j-(columnas/2))(j-(columnas/2)))) Crear un efecto void efectoilum(unsigned char **im, unsigned char **imsal){ long int i,j; float lum; for (i=0;i<filas;i++){ for (j=0;j<columnas;j++){ lum=1-(1/(sqrt(2)*128))*sqrt((i-128)*(i-128)+(j-128)*(j-128));//variación de la luminosidad imsal[i][j]=(floor(lum*(float)im[i][j])); } } int main() } { unsigned char **imagen; unsigned char **imagenmod; int i; imagen=(unsigned char **)malloc (sizeof (unsigned char *)*filas); imagenmod=(unsigned char **)malloc (sizeof (unsigned char *)*filas); for (i=0; i<filas; i++){ imagen[i]=(unsigned char *)malloc (sizeof (unsigned char )*columnas); imagenmod[i]=(unsigned char *)malloc (sizeof (unsigned char )*columnas); } leeimagen(“lena.raw”,imagen); efectoilum(imagen,imagenmod); guardaimagen(“lenaefecto.raw”,imagenmod); return(0); } Ejercicios 1. Hacer una función que invierta los valores de gris de lena, aplicarla a la imagen de lena con “efecto”. 2. El operador de umbral es una transformación que, dado un valor(llamado umbral, entre 0 y 255), pone en 0 todos los pixels menores que umbral y en 255 los iguales o mayores. Hacer una función umbral y aplicarla a lena con “efecto” para 3 umbrales distintos. 3. Hacer una imagen que para cada pixel de la imagen original, la de salida es el promedio del pixel de entrada y sus 8 vecinos(sin tener en cuenta los bordes), es una imagen de medias, ídem mediana. 4. Dada una imagen de tamaño N x N, devolver una de tamaño N/2 x N/2 y otra con tamaño N*2 x N*2. i-1 j-1 i-1 j i-1 j+1 i j-1 ij i j+1 i+1 j-1 i+1 j i+1 j+1 ij Guardar con otro formato En Matlab, supongamos que en lena170.raw está una mi agen de salida del ejercicio 2. >> I=readraw('lena170.raw',256,256); >> I=uint8(I); >> imshow(I',[ ]) >> imwrite(I,'lena170.bmp','bmp') ¿Qué vimos? Qué es una imagen digital ●Imagenes raw ●Crear una imagen ●Guardar una imagen ●Leer imagen ●Visualizar en Matlab ●Alamcenar como .bmp en matlab ●