コード例 #1
0
ファイル: 11_union_canales.c プロジェクト: aruiz/AAN
int
main (int argc, char** argv)
{
	int w, h;
	unsigned char *red1, *green1, *blue1,
	              *red2, *green2, *blue2;
	float         *fred1, *fgreen1, *fblue1,
	              *fred2, *fgreen2, *fblue2;
	
	if (argc < 2)
	{
		fprintf (stderr, "Usage: %s <BMP file>\n", argv[0]);
		return -1;
	}

	/* Leemos el fichero dado por el primer argumento */	
	if (ami_read_bmp (argv[1], &red1, &green1, &blue1, &w, &h) < 0)
		return -1;
	
	/********** TEST DE aan_unir_canales_unsigned_char **************/
		
	aan_unir_canales_unsigned_char (red1, red1, &red2, w, h);
	aan_unir_canales_unsigned_char (green1, green1, &green2, w, h);
	aan_unir_canales_unsigned_char (blue1, blue1, &blue2, w, h);
		
	ami_write_bmp ("./11_union_canales_rgb.bmp", red2, green2, blue2, w*2 + 4, h);
	/* Liberamos la memoria usada para esta imagen  */	
	free (red2); free (green2); free (blue2);
	
	/************* TEST DE aan_unir_canales_float ******************/
	/* Transformamos los tres canales en canales flotantes*/	
	fred1   = uchar_to_float (red1,   w * h);
	fgreen1 = uchar_to_float (green1, w * h);
	fblue1  = uchar_to_float (blue1,  w * h);
	
	aan_unir_canales_float (fred1,   fred1,   &fred2,   w, h);
	aan_unir_canales_float (fgreen1, fgreen1, &fgreen2, w, h);
	aan_unir_canales_float (fblue1,  fblue1,  &fblue2,  w, h);
	
	/* Transformamos los tres canales en canales enteros para guardarlos en BMP */
	red2   = float_to_uchar (fred2,   (w*2 + 4) * h);
	green2 = float_to_uchar (fgreen2, (w*2 + 4) * h);
	blue2  = float_to_uchar (fblue2,  (w*2 + 4) * h);
	
	ami_write_bmp ("./11_union_canales_float.bmp", red2, green2, blue2, w*2 + 4, h);

	/* Liberamos la memoria usada */
	free (red1); free (green1); free (blue1);
	free (red2); free (green2); free (blue2);
	free (fred1); free (fgreen1); free (fblue1);
	free (fred2); free (fgreen2); free (fblue2);
	return 0;
}
コード例 #2
0
ファイル: 4_calor_explicito.c プロジェクト: aruiz/AAN
int
main (int argc, char** argv)
{
	int i, w, h;
	unsigned char *red, *green, *blue;
	float *fred1, *fgreen1, *fblue1,
		    *fred2, *fgreen2, *fblue2;
	char salida[100];

	if (argc < 2)
	{
		fprintf (stderr, "Usage: %s <BMP file>\n", argv[0]);
		return -1;
	}

	/* Leemos el fichero dado por el primer argumento */
	if (ami_read_bmp (argv[1], &red, &green, &blue, &w, &h) < 0)
		return -1;

	/* Copiamos de uchar a float */
	fred1   = uchar_to_float (red,   w*h);
	fgreen1 = uchar_to_float (green, w*h);
	fblue1  = uchar_to_float (blue,  w*h);

	/* Liberamos memoria */
	free (red); free (green); free (blue);

	fred2   = (float*)malloc (sizeof(float) * w * h);
	fgreen2 = (float*)malloc (sizeof(float) * w * h);
	fblue2  = (float*)malloc (sizeof(float) * w * h);

	for (i = 0; i < NITERS; i++)
	{
		sprintf(salida, "imagen_1%05d.bmp", i);
		
		fprintf (stderr, "0/%d - dt=%f - Generando fichero %s\n", i, DT, salida);
		
		aan_ecuacion_calor_metodo_explicito(fred1, fgreen1, fblue1,
		                                    fred2, fgreen2, fblue2,
		                                    w, h,
		                                    DT, 1);

		red   = float_to_uchar (fred2,   w*h);
		green = float_to_uchar (fgreen2, w*h);
		blue  = float_to_uchar (fblue2,  w*h);

		memcpy (fred1,   fred2,   sizeof(float) * w * h);
		memcpy (fgreen1, fgreen2, sizeof(float) * w * h);
		memcpy (fblue1,  fblue2,  sizeof(float) * w * h);

		ami_write_bmp (salida, red, green, blue, w, h);

		free (red); free (green); free (blue);
	}

	free (fred2); free (fgreen2); free (fblue2);
	
	return 0;
}
コード例 #3
0
ファイル: practica9.c プロジェクト: groteck/perona
// función que aplica el  método de perona malik a cada canal de una imagen dada
void perona_malik(float* red_input,float*green_input,float*blue_input,int width,int height,float dt, int niter,float lambda){
  int i,j;
  char name[200];
  unsigned char *ro,*go,*bo;

  ro=(unsigned char*)malloc((width*height)*sizeof(unsigned char));
  go=(unsigned char*)malloc((width*height)*sizeof(unsigned char));
  bo=(unsigned char*)malloc((width*height)*sizeof(unsigned char));

  for(i=0;i<(width*height);i++){
    ro[i]=red_input[i];
    go[i]=green_input[i];
    bo[i]=blue_input[i];
  }

  for(i=0;i<niter; i++){
    sprintf(name,"/home/groteck/Imágenes/practica9/resultado/imagen_%d.bmp",100000+i);
    ami_write_bmp(name,ro,go,bo,width,height);
    perona_canal(red_input,width,height,dt,lambda);
    perona_canal(green_input,width,height,dt,lambda);
    perona_canal(blue_input,width,height,dt,lambda);
    for(j=0;j<(width*height);j++){
      if(red_input[j]>255){
        ro[j]=255;
      }
      else{
        if(red_input[j]<0){
          ro[j]=0;
        }
        else ro[j]=(unsigned char)red_input[j];
      }
      if(green_input[j]>255){
        go[j]=255;
      }
      else{
        if(green_input[j]<0){
          go[j]=0;
        }
        else go[j]=(unsigned char)green_input[j];
      }
      if(blue_input[j]>255){
        bo[j]=255;
      }
      else{
        if(blue_input[j]<0){
          bo[j]=0;
        }
        else bo[j]=(unsigned char)blue_input[j];
      }
    }

  };
  free(ro);
  free(go);
  free(bo);
}
コード例 #4
0
int
main (int argc, char** argv)
{
	int i, w, h;
	unsigned char *red, *green, *blue;
	float *fred1, *fgreen1, *fblue1,
		    *fred2, *fgreen2, *fblue2;
	char salida[100];
	float t0red,   t1red,   t2red,
	      t0green, t1green, t2green,
	      t0blue,  t1blue,  t2blue;

	if (argc < 2)
	{
		fprintf (stderr, "Usage: %s <BMP file>\n", argv[0]);
		return -1;
	}

	/* Leemos el fichero dado por el primer argumento */
	if (ami_read_bmp (argv[1], &red, &green, &blue, &w, &h) < 0)
		return -1;

#ifdef P1
	t0red = t0green = t0blue = T0;
	t1red = t1green = t1blue = T1;
	t2red = t2green = t2blue = T2;
#endif

#ifdef P2
	canal_a_valores_t (red,   w, h, &t0red,   &t1red,   &t2red);
	canal_a_valores_t (green, w, h, &t0green, &t1green, &t2green);
	canal_a_valores_t (blue,  w, h, &t0blue,  &t1blue,  &t2blue);
#endif

	/* Copiamos de uchar a float */
	fred1   = uchar_to_float (red,   w*h);
	fgreen1 = uchar_to_float (green, w*h);
	fblue1  = uchar_to_float (blue,  w*h);

	/* Liberamos memoria */
	free (red); free (green); free (blue);

	fred2   = (float*)malloc (sizeof(float) * w * h);
	fgreen2 = (float*)malloc (sizeof(float) * w * h);
	fblue2  = (float*)malloc (sizeof(float) * w * h);

	for (i = 0; i < NITERS; i++)
	{
		sprintf(salida, "imagen_1%05d.bmp", i);
		
		fprintf (stderr, "%d/%d - dt=%f - A=%f :: Generando fichero %s\n", i, NITERS, DT, A, salida);
		
		aan_ecuacion_calor_fuerza_externa_metodo_explicito (fred1,   fred2,   w, h, DT, 1, A, t0red,   t1red,   t2red);
		aan_ecuacion_calor_fuerza_externa_metodo_explicito (fgreen1, fgreen2, w, h, DT, 1, A, t0green, t1green, t2green);
		aan_ecuacion_calor_fuerza_externa_metodo_explicito (fblue1,  fblue2,  w, h, DT, 1, A, t0blue,  t1blue,  t2blue);
				
		red   = float_to_uchar (fred2,   w*h);
		green = float_to_uchar (fgreen2, w*h);
		blue  = float_to_uchar (fblue2,  w*h);

		memcpy (fred1,   fred2,   sizeof(float) * w * h);
		memcpy (fgreen1, fgreen2, sizeof(float) * w * h);
		memcpy (fblue1,  fblue2,  sizeof(float) * w * h);

		ami_write_bmp (salida, red, green, blue, w, h);

		free (red); free (green); free (blue);
	}

	free (fred2); free (fgreen2); free (fblue2);
	
	return 0;
}
コード例 #5
0
int
main (int argc, char** argv)
{
	int w, h;
	unsigned char *red, *green, *blue;

	float *fred1, *fgreen1, *fblue1,
          *fred2, *fgreen2, *fblue2,
          *fred3, *fgreen3, *fblue3;
	
	float *hr, *hg, *hb;
	float *e1, *e2;
	int *f;

	if (argc < 2)
	{
		fprintf (stderr, "Usage: %s <BMP file>\n", argv[0]);
		return -1;
	}

	/* Leemos el fichero dado por el primer argumento */
	if (ami_read_bmp (argv[1], &red, &green, &blue, &w, &h) < 0)
		return -1;

	/* Generarmos histogramas de origen */		
	hr = generar_histograma (red,   w, h);
	hg = generar_histograma (green, w, h);
	hb = generar_histograma (blue,  w, h);
	
	/* Generamos histogramas objetivo */
	e1 = generar_e1();
	e2 = generar_e2();
	
	/* Normalizamos los histogramas */
	normalizar_histograma(hr);
	normalizar_histograma(hg);
	normalizar_histograma(hb);
	normalizar_histograma(e1);
	normalizar_histograma(e2);

	fred1   = uchar_to_float (red,   w*h);
	fgreen1 = uchar_to_float (green, w*h);
	fblue1  = uchar_to_float (blue,  w*h);
	free (red); free (green); free (blue);

	/* Reservamos memoria para los canales de salida y el vector de ecualizacion f */
	fred2    = (float*)malloc (sizeof(float) * w*h);
	fgreen2  = (float*)malloc (sizeof(float) * w*h);
	fblue2   = (float*)malloc (sizeof(float) * w*h);

	f = (int*)malloc (sizeof(int) * 256);
	
	/************* Ecualizamos al histograma E1 (y = 1/256) *************/
	aan_ecualizar_histograma(hr, e1, f); /* rojo */
	aan_ecualizar_histograma_canal(fred1,   fred2,   w, h, f);
	aan_ecualizar_histograma(hg, e1, f); /* verde */
	aan_ecualizar_histograma_canal(fgreen1, fgreen2, w, h, f);
	aan_ecualizar_histograma(hb, e1, f); /* azul */
	aan_ecualizar_histograma_canal(fblue1,  fblue2,  w, h, f);
		
	aan_unir_canales_float (fred1,   fred2,   &fred3,   w, h);
	aan_unir_canales_float (fgreen1, fgreen2, &fgreen3, w, h);
	aan_unir_canales_float (fblue1,  fblue2,  &fblue3,  w, h);

	red   = float_to_uchar (fred3,   (w*2 + 4)*h);
	green = float_to_uchar (fgreen3, (w*2 + 4)*h);
	blue  = float_to_uchar (fblue3,  (w*2 + 4)*h);

	ami_write_bmp ("imagen_ecualizada_e1.bmp", red, green, blue, w*2 + 4, h);

	/* Liberamos memoria */
	free (red); free (green); free (blue);
	free (fred3); free (fgreen3); free (fblue3);

	/************* Ecualizamos al histograma E1 (y = 1/256) *************/
	aan_ecualizar_histograma(hr, e2, f); /* rojo */
	aan_ecualizar_histograma_canal(fred1,   fred2,   w, h, f);
	aan_ecualizar_histograma(hg, e2, f); /* verde */
	aan_ecualizar_histograma_canal(fgreen1, fgreen2, w, h, f);
	aan_ecualizar_histograma(hb, e2, f); /* azul */
	aan_ecualizar_histograma_canal(fblue1,  fblue2,  w, h, f);
		
	aan_unir_canales_float (fred1,   fred2,   &fred3,   w, h);
	aan_unir_canales_float (fgreen1, fgreen2, &fgreen3, w, h);
	aan_unir_canales_float (fblue1,  fblue2,  &fblue3,  w, h);

	red   = float_to_uchar (fred3,   (w*2 + 4)*h);
	green = float_to_uchar (fgreen3, (w*2 + 4)*h);
	blue  = float_to_uchar (fblue3,  (w*2 + 4)*h);

	ami_write_bmp ("imagen_ecualizada_e2.bmp", red, green, blue, w*2 + 4, h);
		
	/* Liberamos memoria */
	free (red); free (green); free (blue);
	free (fred1); free (fgreen1); free (fblue1);
	free (fred2); free (fgreen2); free (fblue2);
	free (fred3); free (fgreen3); free (fblue3);
	free (hr); free (hg); free (hb); free(e1); free(e2); free(f);
	return 0;
}
コード例 #6
0
ファイル: 2_mascara_grad_vertical.c プロジェクト: aruiz/AAN
int
main (int argc, char **argv)
{
	int w, h;
	unsigned char *red1, *green1, *blue1,
	              *red2, *green2, *blue2,
	              *red3, *green3, *blue3;
	              
	float         *fred1, *fgreen1, *fblue1,
	              *fred2, *fgreen2, *fblue2;
	
	float **u_y;

	if (argc < 2)
	{
		fprintf (stderr, "Usage: %s <BMP file>\n", argv[0]);
		return -1;
	}
	
	/* Leemos el fichero dado por el primer argumento */	
	if (ami_read_bmp (argv[1], &red1, &green1, &blue1, &w, &h) < 0)
		return -1;
	
	ami_malloc2d (u_y, float, 3, 3);
	
	/* Gradiente vertical */
	u_y[0][0] = 0.25 * -(2.0 - sqrt(2.0)); u_y[0][1] = 0.25 * -2.0 * (sqrt(2.0) - 1); u_y[0][2] = 0.25 * -(2.0-sqrt(2.0));
	u_y[1][0] = 0;                         u_y[1][1] = 0;                             u_y[1][2] = 0;
	u_y[2][0] = 0.25 *  (2.0 - sqrt(2.0)); u_y[2][1] = 0.25 *  2.0 * (sqrt(2.0) - 1); u_y[2][2] = 0.25 *  (2.0 - sqrt(2.0));
	
	/* Pasamos los canales a precision flotante */
	fred1   = uchar_to_float (red1,   w * h);
	fgreen1 = uchar_to_float (green1, w * h);
	fblue1  = uchar_to_float (blue1,  w * h);
	
	aan_normalizar_imagen_float (fred1, fgreen1, fblue1, w , h);
	
	fred2   = (float*) malloc (sizeof (float) * w * h);
	fgreen2 = (float*) malloc (sizeof (float) * w * h);
	fblue2  = (float*) malloc (sizeof (float) * w * h);

	/*********************** GRADIENTE VERTICAL ****************************/
	/* Aplicamos la mascara de gradiente vertical y guardamos el resultado */
	
	aan_mascara_imagen (fred1, fgreen1, fblue1,
	                    fred2, fgreen2, fblue2,
	                    w, h, u_y);
	
	aan_normalizar_imagen_float (fred2, fgreen2, fblue2, w, h);
	
	red2   = float_to_uchar (fred2,   w * h);
	green2 = float_to_uchar (fgreen2, w * h);
	blue2  = float_to_uchar (fblue2,  w * h);
	
	aan_unir_canales_unsigned_char (red1, red2, &red3, w, h);
	aan_unir_canales_unsigned_char (green1, green2, &green3, w, h);
	aan_unir_canales_unsigned_char (blue1, blue2, &blue3, w, h);
	
	ami_write_bmp ("./2_gradiente_vertical.bmp", red3, green3, blue3, w*2 + 4, h);
	
	/* Liberamos memoria */
	free (red2); free (green2); free (blue2);
	free (red3); free (green3); free (blue3);
	
	/* Liberamos memoria */
	free (red1); free (green1); free (blue1);
	free (fred1); free (fgreen1); free (fblue1);
	free (fred2); free (fgreen2); free (fblue2);
	ami_free2d (u_y);
	return 0;
}
コード例 #7
0
ファイル: aan_ondas.c プロジェクト: aruiz/AAN
void
aan_ecuacion_ondas_metodo_explicito(float *red_input,
                                    float *green_input,
                                    float *blue_input,
                                    float *red_output,
                                    float *green_output,
                                    float *blue_output,
                                    int    width,
                                    int    height,
                                    float dt,
                                    int Niter)
{
  int i;

  /* Canales auxiliares para la entrada de cada iteracion */
  float *red   = (float*)malloc (sizeof(float) * width * height);
  float *green = (float*)malloc (sizeof(float) * width * height);
  float *blue  = (float*)malloc (sizeof(float) * width * height);

  /* Canal de la iteracion anterior a la actual (input-1) */ 
  float *red_anterior   = (float*)malloc (sizeof(float) * width * height);
  float *green_anterior = (float*)malloc (sizeof(float) * width * height);
  float *blue_anterior  = (float*)malloc (sizeof(float) * width * height);

  memcpy (red,   red_input,   sizeof(float) * width * height);
  memcpy (green, green_input, sizeof(float) * width * height);
  memcpy (blue,  blue_input,  sizeof(float) * width * height);

  memcpy (red_anterior,   red_input,   sizeof(float) * width * height);
  memcpy (green_anterior, green_input, sizeof(float) * width * height);
  memcpy (blue_anterior,  blue_input,  sizeof(float) * width * height);


  for (i=0; i<Niter; i++)
  {
    unsigned char *ured, *ugreen, *ublue;
    char imagen[100];

    /* Llevamos a cabo la iteracion para cada canal*/
    aan_ondas_un_canal (red,   red_output,   red_anterior,   width, height, dt);
    aan_ondas_un_canal (green, green_output, green_anterior, width, height, dt);
    aan_ondas_un_canal (blue,  blue_output,  blue_anterior,  width, height, dt);

    /* Copiamos el canal de entrada como canal anterior */
    memcpy (red_anterior,   red,   sizeof(float) * width * height);
    memcpy (green_anterior, green, sizeof(float) * width * height);
    memcpy (blue_anterior,  blue,  sizeof(float) * width * height);

    /* Guardamos el resultado en un fichero */
    sprintf(imagen, "imagen_1%05d.bmp", i);
    
    ured   = float_to_uchar (red_output,   width*height);
    ugreen = float_to_uchar (green_output, width*height);
    ublue  = float_to_uchar (blue_output,  width*height);

    ami_write_bmp (imagen, ured, ugreen, ublue, width, height);

    free (ured); free (ugreen); free (ublue);

    /* Copiamos el canal de salida a los canales de entrada para la
     * siguiente iteracion */
    memcpy (red,   red_output,   sizeof(float) * width * height);
    memcpy (green, green_output, sizeof(float) * width * height);
    memcpy (blue,  blue_output,  sizeof(float) * width * height);
  }

  /* Liberamos la memoria de los canales auxiliares */
  free (red); free (green); free (blue);
  free (red_anterior); free (green_anterior); free (blue_anterior);
}
コード例 #8
0
ファイル: 2_mascara_mod_gradiente.c プロジェクト: aruiz/AAN
int
main (int argc, char **argv)
{
	int w, h;
	unsigned char *red1, *green1, *blue1,
	              *red2, *green2, *blue2,
	              *red3, *green3, *blue3;
	              
	float         *fred1, *fgreen1, *fblue1,
	              *fred2, *fgreen2, *fblue2,
	              *fred3, *fgreen3, *fblue3,
	              *fred4, *fgreen4, *fblue4;
	
	float **u_x, **u_y;

	if (argc < 2)
	{
		fprintf (stderr, "Usage: %s <BMP file>\n", argv[0]);
		return -1;
	}
	/* Leemos el fichero dado por el primer argumento */	
	if (ami_read_bmp (argv[1], &red1, &green1, &blue1, &w, &h) < 0)
		return -1;
	
	ami_malloc2d (u_x, float, 3, 3);
	ami_malloc2d (u_y, float, 3, 3);

	/* Gradiente horizontal */
	u_x[0][0] = 0.25 * -(2.0 - sqrt(2.0));     u_x[0][1] = 0; u_x[0][2] = 0.25 * (2.0 - sqrt(2.0));
	u_x[1][0] = 0.25 * -2.0 * (sqrt(2.0) - 1); u_x[1][1] = 0; u_x[1][2] = 0.25 * 2.0 * (sqrt(2.0) - 1);
	u_x[2][0] = 0.25 * -(2.0 - sqrt(2.0));     u_x[2][1] = 0; u_x[2][2] = 0.25 * (2.0 - sqrt(2.0));
	
	/* Gradiente vertical */
	u_y[0][0] = 0.25 * -(2.0 - sqrt(2.0)); u_y[0][1] = 0.25 * -2.0 * (sqrt(2.0) - 1); u_y[0][2] = 0.25 * -(2.0-sqrt(2.0));
	u_y[1][0] = 0;                         u_y[1][1] = 0;                             u_y[1][2] = 0;
	u_y[2][0] = 0.25 *  (2.0 - sqrt(2.0)); u_y[2][1] = 0.25 *  2.0 * (sqrt(2.0) - 1); u_y[2][2] = 0.25 *  (2.0 - sqrt(2.0));
	
	/* Pasamos los canales a precision flotante */
	fred1   = uchar_to_float (red1,   w * h);
	fgreen1 = uchar_to_float (green1, w * h);
	fblue1  = uchar_to_float (blue1,  w * h);
	
	aan_normalizar_imagen_float (fred1, fgreen1, fblue1, w , h);
	
	fred2   = (float*) malloc (sizeof (float) * w * h);
	fgreen2 = (float*) malloc (sizeof (float) * w * h);
	fblue2  = (float*) malloc (sizeof (float) * w * h);
	
	fred3   = (float*) malloc (sizeof (float) * w * h);
	fgreen3 = (float*) malloc (sizeof (float) * w * h);
	fblue3  = (float*) malloc (sizeof (float) * w * h);
		
	/* Aplicamos ambos gradientes */
	aan_mascara_imagen (fred1, fgreen1, fblue1,
	                    fred2, fgreen2, fblue2,
	                    w, h, u_x);
	
	aan_mascara_imagen (fred1, fgreen1, fblue1,
	                    fred3, fgreen3, fblue3,
	                    w, h, u_y);

	/* Normalizamos ambas imagenes */
	aan_normalizar_imagen_float (fred2, fgreen2, fblue2, w , h);
	aan_normalizar_imagen_float (fred3, fgreen3, fblue3, w , h);
	
	/* Combinamos los resultados para hallar el modulo del gradiente */
	combinar (fred2, fred3, &fred4, w, h);
	combinar (fgreen2, fgreen3, &fgreen4, w, h);
	combinar (fblue2, fblue3, &fblue4, w, h);

	aan_normalizar_imagen_float (fred4, fgreen4, fblue4, w , h);

	/* Guardamos la imagen */
	red2   = float_to_uchar (fred4,   w * h);
	green2 = float_to_uchar (fgreen4, w * h);
	blue2  = float_to_uchar (fblue4,  w * h);
	
	aan_unir_canales_unsigned_char (red1,   red2,   &red3,   w, h);
	aan_unir_canales_unsigned_char (green1, green2, &green3, w, h);
	aan_unir_canales_unsigned_char (blue1,  blue2,  &blue3,  w, h);
	
	ami_write_bmp ("./2_mascara_mod_gradiente.bmp", red3, green3, blue3, w*2 + 4, h);

	/* Liberamos memoria */
	free (red2); free (green2); free (blue2);
	free (red3); free (green3); free (blue3);

	free (red1); free (green1); free (blue1);
	free (fred1); free (fgreen1); free (fblue1);
	free (fred2); free (fgreen2); free (fblue2);
	free (fred3); free (fgreen3); free (fblue3);
	free (fred4); free (fgreen4); free (fblue4);
	
	ami_free2d (u_x); 	ami_free2d (u_y);
	return 0;
}
コード例 #9
0
ファイル: 2_mascara_byn.c プロジェクト: aruiz/AAN
int
main (int argc, char **argv)
{
	int i, w, h;
	unsigned char *red1, *green1, *blue1,
	              *red2, *green2, *blue2,
	              *red3, *green3, *blue3;
	              
	float         *fred1, *fgreen1, *fblue1,
	              *fred2, *fgreen2, *fblue2;
	
	float **u_x, **u_y, **lap;

	if (argc < 2)
	{
		fprintf (stderr, "Usage: %s <BMP file>\n", argv[0]);
		return -1;
	}
	/* Leemos el fichero dado por el primer argumento */	
	if (ami_read_bmp (argv[1], &red1, &green1, &blue1, &w, &h) < 0)
		return -1;
	
	ami_malloc2d (u_x, float, 3, 3);
	ami_malloc2d (u_y, float, 3, 3);
	ami_malloc2d (lap, float, 3, 3);

	/* Gradiente horizontal */
	u_x[0][0] = 0.25 * -(2.0 - sqrt(2.0));     u_x[0][1] = 0; u_x[0][2] = 0.25 * (2.0 - sqrt(2.0));
	u_x[1][0] = 0.25 * -2.0 * (sqrt(2.0) - 1); u_x[1][1] = 0; u_x[1][2] = 0.25 * 2.0 * (sqrt(2.0) - 1);
	u_x[2][0] = 0.25 * -(2.0 - sqrt(2.0));     u_x[2][1] = 0; u_x[2][2] = 0.25 * (2.0 - sqrt(2.0));
	
	/* Gradiente vertical */
	u_y[0][0] = 0.25 * -(2.0 - sqrt(2.0)); u_y[0][1] = 0.25 * -2.0 * (sqrt(2.0) - 1); u_y[0][2] = 0.25 * -(2.0-sqrt(2.0));
	u_y[1][0] = 0;                         u_y[1][1] = 0;                             u_y[1][2] = 0;
	u_y[2][0] = 0.25 *  (2.0 - sqrt(2.0)); u_y[2][1] = 0.25 *  2.0 * (sqrt(2.0) - 1); u_y[2][2] = 0.25 *  (2.0 - sqrt(2.0));
	
	/* Pasamos los canales a precision flotante */
	fred1   = uchar_to_float (red1,   w * h);
	fgreen1 = uchar_to_float (green1, w * h);
	fblue1  = uchar_to_float (blue1,  w * h);

	aan_normalizar_imagen_float (fred1, fgreen1, fblue1, w , h);
	
	fred2   = (float*) malloc (sizeof (float) * w * h);
	fgreen2 = (float*) malloc (sizeof (float) * w * h);
	fblue2  = (float*) malloc (sizeof (float) * w * h);
	
	/* Usamos el gradiente horizontal en el canal verde */
	aan_mascara_canal (fgreen1, fgreen2, w, h, u_x);
	aan_mascara_canal (fred1, fred2, w, h, u_y);
	for (i=0; i < (w * h) ;i++)
		fblue2[i] = 127.0;

	red2   = float_to_uchar (fred2,   w * h);
	green2 = float_to_uchar (fgreen2, w * h);
	blue2  = float_to_uchar (fblue2,  w * h);
	
	aan_normalizar_imagen_float (fred2, fgreen2, fblue2, w , h);
	
	aan_unir_canales_unsigned_char (red1,   red2,   &red3,   w, h);
	aan_unir_canales_unsigned_char (green1, green2, &green3, w, h);
	aan_unir_canales_unsigned_char (blue1,  blue2,  &blue3,  w, h);
	
	ami_write_bmp ("./2_mascara_byn.bmp", red3, green3, blue3, w*2 + 4, h);

	/* Liberamos memoria */
	free (red2); free (green2); free (blue2);
	free (red3); free (green3); free (blue3);

	free (red1); free (green1); free (blue1);
	free (fred1); free (fgreen1); free (fblue1);
	free (fred2); free (fgreen2); free (fblue2);
	ami_free2d (u_x); ami_free2d (u_y);
	return 0;
}