Exemple #1
0
static void
render_to_surface (const RENDER * render, SNDFILE *infile, int samplerate, sf_count_t filelen, cairo_surface_t * surface)
{
	float ** mag_spec = NULL ; // Indexed by [w][h]

	spectrum *spec ;
	double max_mag = 0.0 ;
	int width, height, w, speclen ;

	if (render->border)
	{	width = lrint (cairo_image_surface_get_width (surface) - LEFT_BORDER - RIGHT_BORDER) ;
		height = lrint (cairo_image_surface_get_height (surface) - TOP_BORDER - BOTTOM_BORDER) ;
		}
	else
	{	width = render->width ;
		height = render->height ;
		}

	if (width < 1)
	{	printf ("Error : 'width' parameter must be >= %d\n",
			render->border ? (int) (LEFT_BORDER + RIGHT_BORDER) + 1 : 1) ;
		exit (1) ;
		} ;

	if (height < 1)
	{	printf ("Error : 'height' parameter must be >= %d\n",
			render->border ? (int) (TOP_BORDER + BOTTOM_BORDER) + 1 : 1) ;
		exit (1) ;
		} ;

	/*
	** Choose a speclen value, the spectrum length.
	** The FFT window size is twice this.
	*/
	if (render->fft_freq != 0.0)
		/* Choose an FFT window size of 1/fft_freq seconds of audio */
		speclen = (samplerate / render->fft_freq + 1) / 2 ;
	else
		/* Long enough to represent frequencies down to 20Hz. */
		speclen = height * (samplerate / 20 / height + 1) ;

	/* Find the nearest fast value for the FFT size. */
	{	int d ;	/* difference */

		for (d = 0 ; /* Will terminate */ ; d++)
		{	/* Logarithmically, the integer above is closer than
			** the integer below, so prefer it to the one below.
			*/
			if (is_good_speclen (speclen + d))
			{	speclen += d ;
				break ;
				}
			/* FFT length must also be >= the output height,
			** otherwise repeated pixel rows occur in the output.
			*/
			if (speclen - d >= height && is_good_speclen (speclen - d))
			{	speclen -= d ;
				break ;
				}
			}
		}

	mag_spec = calloc (width, sizeof (float *)) ;
	if (mag_spec == NULL)
	{	printf ("%s : Not enough memory.\n", __func__) ;
		exit (1) ;
		} ;
	for (w = 0 ; w < width ; w++)
	{	if ((mag_spec [w] = calloc (height, sizeof (float))) == NULL)
		{	printf ("%s : Not enough memory.\n", __func__) ;
			exit (1) ;
			} ;
		} ;

	spec = create_spectrum (speclen, render->window_function) ;

	if (spec == NULL)
	{	printf ("%s : line %d : create plan failed.\n", __FILE__, __LINE__) ;
		exit (1) ;
		} ;

	for (w = 0 ; w < width ; w++)
	{	double single_max ;

		read_mono_audio (infile, filelen, spec->time_domain, 2 * speclen, w, width) ;

		single_max = calc_magnitude_spectrum (spec) ;
		max_mag = MAX (max_mag, single_max) ;

		interp_spec (mag_spec [w], height, spec->mag_spec, speclen, render, samplerate) ;
		} ;

	destroy_spectrum (spec) ;

	if (render->border)
	{	RECT heat_rect ;

		heat_rect.left = 12 ;
		heat_rect.top = TOP_BORDER + TOP_BORDER / 2 ;
		heat_rect.width = 12 ;
		heat_rect.height = height - TOP_BORDER / 2 ;

		render_spectrogram (surface, render->spec_floor_db, mag_spec, max_mag, LEFT_BORDER, TOP_BORDER, width, height, render->gray_scale) ;

		render_heat_map (surface, render->spec_floor_db, &heat_rect, render->gray_scale) ;

		render_spect_border (surface, render->filename, LEFT_BORDER, width, filelen / (1.0 * samplerate), TOP_BORDER, height, render->min_freq, render->max_freq, render->log_freq) ;
		render_heat_border (surface, render->spec_floor_db, &heat_rect) ;
		}
	else
		render_spectrogram (surface, render->spec_floor_db, mag_spec, max_mag, 0, 0, width, height, render->gray_scale) ;

	for (w = 0 ; w < width ; w++)
		free (mag_spec [w]) ;
	free (mag_spec) ;

	return ;
} /* render_to_surface */
int
main(int argc, char **argv)
{
	//int nt;			/* number of frequency samples per trace */
  int nfft;   /* For computing the FFT */
	//float dw;		/* time sampling interval */
	//int i1;			/* time sample index */
  //int log;   /* Check if the trace has had a log applied (for mie scattering) */
  int j;     /* Other indices */
  const double eps = 1.e-32;
  kiss_fftr_cfg forw, invs;

  /* Variables for Jons example */
  float *spectrum  = NULL;
  float *rspectrum = NULL;
  complex *fft     = NULL;
  int n            = 64;
  int nw           = n/2+1;
  float o1         = -M_PI/2;
  float d1         = M_PI/n;

  nfft = n;

	/* hook up getpar */
	initargs(argc, argv);
	//requestdoc(1);
  requestdoc(0); // For now (testing), stdin is not used

  /* Allocating memory */
  spectrum  = ealloc1float((n+1));
  rspectrum = ealloc1float((n/2+1));
  fft       = alloc1complex(nfft/2+1);
  forw      = kiss_fftr_alloc(nfft,0,NULL,NULL);
  invs      = kiss_fftr_alloc(nfft,1,NULL,NULL);
  if(NULL == forw || NULL == invs)
    err("KISS FFT allocation error");
  memset( (void *) tr.data, 0, (n+1) * FSIZE);

  tr.dt = d1;
  tr.f1 = o1;
  tr.ns = n;
  create_spectrum(n, o1, d1, spectrum);

  /* Squaring the spectrum */
  j = n/2;
  for(int i = 0; i < nw; i++, j++) {
    rspectrum[i] = spectrum[j]*spectrum[j];
    tr.data[i] = rspectrum[i];
  }

 
  fprintf(stderr, "Created input: \n"); 
  for(int i = 0; i < nw; i++) {
    fprintf(stderr, "i=%d input=%f\n",i,rspectrum[i]);
  }
  fprintf(stderr, "\n");

  // Take the log and create a complex type
  //fprintf(stderr, "Log of spectrum: \n"); 
  for(int i = 0; i < nw; i++) {
    fft[i] = cmplx(log(rspectrum[i]+eps)/nfft,0.);
  }
  //for(int i = 0; i < nw; i++) {
  //  fprintf(stderr, "i=%d real=%f imag=%f\n",i,fft[i].r,fft[i].i);
  //}
  //fprintf(stderr, "\n");

  // Find the inverse FFT
  kiss_fftri(invs,(const kiss_fft_cpx *) fft, tr.data);

  tr.data[0]      *= 0.5;
  tr.data[nfft/2] *= 0.5;
  for(int i=1+nfft/2; i < nfft; i++) {
    tr.data[i] = 0;
  }

  kiss_fftr(forw, tr.data, (kiss_fft_cpx *) fft);

  for(int i=0; i < nw; i++) {
    fft[i] = crmul(cwp_cexp(fft[i]),1./nfft);
  }

  kiss_fftri(invs,(const kiss_fft_cpx *) fft, tr.data);

  float dt = 0.004;
  for(int i = 0; i < nfft; i++) {
    fprintf(stderr, "i=%d t=%f output=%f\n", i, o1+dt*i, tr.data[i]);
  }

  puttr(&tr);
	return(CWP_Exit());
}
Exemple #3
0
int main(int argc, char **argv){

  int opcion;	//Opcion para el getopt
  int vflag=0, rflag=0, nflag=0, glfag=0, iflag=0, mflag=0, oflag=0;  //Flags para el getopt
  float r=0.5, g=1.0;
  int n=2;
  string nombreImagen;
  string nombreMascara;
  string nombreSalida = "output.png";
  Mat imagen, padded, complexImg, filter, filterAux, imagenSalida, filterSalida, imagenFrecuencias, imagenFrecuenciasSinOrden, imagenHSV;
  Mat complexAux;
  Mat salida;
  Mat imagenPasoBaja;
  Mat mascara;
  vector<Mat> canales;

  while((opcion=getopt(argc, argv, "vr:n:g:i:o:m:")) !=-1 ){

    switch(opcion){

      case 'v':
        vflag=1;
      break;

      case 'r':
        rflag=1;
        r=atof(optarg);
        if(r<0 || r>1){
          cout << "Valor de 'r' introducido invalido" << endl;
          exit(-1);
        }
      break;

      case 'n':
        nflag=1;
        n = atoi(optarg);
        if(n<0 || n>10){
          cout << "Valor de 'n' introducido invalido" << endl;
          exit(-1);
        }
      break;

      case 'g':
        glfag=1;
        g = atof(optarg);
        if(g<0.0 || g>5.0){
          cout << "Valor de 'g' introducido invalido" << endl;
          exit(-1);
        }
      break;

      case 'i':
        iflag=1;
        nombreImagen = optarg;
      break;

      case 'm':
        mflag=1;
        nombreMascara=optarg;
      break;

      case 'o':
        oflag=1;
        nombreSalida=optarg;
      break;
    	
    	
    	case '?':
     	   //Algo ha ido mal
     	   help();
     	   exit(-1);
        break;

    	default:
    		help();
     		exit(-1);
        break;
      }

   }

   //Primero cargaremos la imagen



   if(iflag==1){
    imagen = imread(nombreImagen, CV_LOAD_IMAGE_ANYDEPTH);
    if(imagen.empty()){
      cout << "Imagen especificada invalida" << endl;
      exit(-1);
    }else{
      cout << "Imagen cargada con exito" << endl;
      if(vflag==1){
        namedWindow("Imagen", CV_WINDOW_AUTOSIZE);
        imshow("Imagen", imagen);
        waitKey(0);
        destroyWindow("Imagen");
      }
    }
  }else{
    cout << "La imagen es necesaria" << endl;
    exit(-1);
   }

   //Calculamos r
   r=(r)*(sqrt(pow((imagen.rows),2.0)+pow((imagen.cols),2.0))/2);

   int M = getOptimalDFTSize(imagen.rows);
   int N = getOptimalDFTSize(imagen.cols);


   //Miramos si tiene mascara para cargarla
  if(mflag==1){
    //Cargamos la mascara
    mascara = imread(nombreMascara, 0);
    if(mascara.empty()){
      cout << "Mascara especificada invalida" << endl;
      exit(-1);
    }else{
	cout << "Mascara cargada con exito" << endl;
	   }
  }


   //Ahora miramos los canales para hacer cosas distintas dependiendo

   if(imagen.channels()==1){
    //Imagen monocromatica

    imagen.convertTo(imagenPasoBaja,CV_32F, 1.0/255.0);
    copyMakeBorder(imagenPasoBaja, padded, 0, M-imagenPasoBaja.rows, 0, N - imagenPasoBaja.cols, BORDER_CONSTANT, Scalar::all(0));
    Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
    merge(planes, 2, complexImg);

    dft(complexImg, complexImg);
    filter = complexImg.clone();
    filterAux = complexImg.clone();
    complexAux = complexImg.clone();
    shiftDFT(complexImg);
    shiftDFT(complexAux);

    butterworth(filter, r, n);
    butterworth(filterAux, r, 0);
    mulSpectrums(complexImg, filter, complexImg, 0);
    mulSpectrums(complexAux, filterAux, complexAux, 0);
    shiftDFT(complexImg);
    shiftDFT(complexAux);

    //Falta hacer lo de poder mostrarla
    imagenFrecuencias = create_spectrum(complexImg);
    imagenFrecuenciasSinOrden = create_spectrum(complexAux);

    //Hacemos la inversa
    idft(complexImg, complexImg, DFT_SCALE);
    split(complexImg, planes);
    normalize(planes[0], imagenSalida, 0, 1, CV_MINMAX);
    split(filter, planes);
    normalize(planes[0], filterSalida, 0, 1, CV_MINMAX);

   salida = imagenPasoBaja.clone();
    if(mflag==1){
      //Con mascara procesaremos pixel por pixel
      //Recorremos la imagen
      for(int i=0; i<imagen.rows; i++){
        for(int j=0; j<imagen.cols;j++){
          if(mascara.at<uchar>(i,j)!=0){
            salida.at<float>(i,j) = (g+1)*(imagenPasoBaja.at<float>(i,j)) - (g*imagenSalida.at<float>(i,j));
          }
        }
      }
    }else{
      //Sin mascara lo haremos de forma inmediata
      for(int i=0; i<imagen.rows; i++){
        for(int j=0; j<imagen.cols;j++){
            salida.at<float>(i,j) = ((g+1)*imagenPasoBaja.at<float>(i,j)) - (g*imagenSalida.at<float>(i,j));
        }
      }
    }

    salida.convertTo(salida, CV_8U, 255.0, 0.0);

    if(vflag==1){
      imshow("Imagen final", salida);
      imshow("Filtro Butterworth", filterSalida);
      imshow("Espectro", imagenFrecuencias);
      imshow("Espectro de imagen sin orden", imagenFrecuenciasSinOrden);
      waitKey(0);
    }

   }else{
    //Spliteamos la imagen en canales
    cvtColor(imagen, imagenHSV, CV_BGR2HSV);
    split(imagenHSV, canales);
    Mat temporal;
    canales[2].convertTo(imagenPasoBaja, CV_32F, 1.0/255.0);
    copyMakeBorder(imagenPasoBaja, padded, 0, M-imagenPasoBaja.rows, 0, N - imagenPasoBaja.cols, BORDER_CONSTANT, Scalar::all(0));
    Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
    merge(planes, 2, complexImg);

    dft(complexImg, complexImg);

    filter = complexImg.clone();

    shiftDFT(complexImg);

    butterworth(filter, r, n);
    mulSpectrums(complexImg, filter, complexImg, 0);
    shiftDFT(complexImg);

    //Falta hacer lo de poder mostrarla
    imagenFrecuencias = create_spectrum(complexImg);

    //Hacemos la inversa
    idft(complexImg, complexImg, DFT_SCALE);
    split(complexImg, planes);
    normalize(planes[0], imagenSalida, 0, 1, CV_MINMAX);
    split(filter, planes);
    normalize(planes[0], filterSalida, 0, 1, CV_MINMAX);

    Mat salida = imagen.clone();
    canales[2] = imagenPasoBaja.clone();
    if(mflag==1){
      //Con mascara
      for(int i=0; i<canales[2].rows; i++){
        for(int j=0; j<canales[2].cols;j++){
          if(mascara.at<uchar>(i,j)!=0){
            canales[2].at<float>(i,j) = ((g+1)*imagenPasoBaja.at<float>(i,j)) - (g*imagenSalida.at<float>(i,j));
          }
        }
      }
    }else{
      //Sin mascara
      for(int i=0; i<canales[2].rows; i++){
        for(int j=0; j<canales[2].cols;j++){
            canales[2].at<float>(i,j) = ((g+1)*imagenPasoBaja.at<float>(i,j)) - (g*imagenSalida.at<float>(i,j));
        }
      }
    }

    canales[2].convertTo(canales[2], CV_8U, 255.0, 0.0);
    merge(canales, salida);
    cvtColor(salida, salida, CV_HSV2BGR);

    salida.convertTo(salida, CV_8U, 255.0, 0.0);

    if(vflag==1){
      imshow("Imagen final", salida);
      imshow("Filtro Butterworth", filterSalida);
      imshow("Espectro", imagenFrecuencias);
      imshow("Espectro de imagen sin orden", imagenFrecuenciasSinOrden);
      waitKey(0);
    }


   }
   //Y escribimos la imagen a fichero
   imwrite(nombreSalida, salida);

return 0;

}