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()); }
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; }