static std::shared_ptr<FeatureChannels_> idftFeatures( const std::shared_ptr<FeatureChannels_>& features) { std::shared_ptr<FeatureChannels_> res(new FeatureChannels_()); for (int i = 0; i < NUMBER_OF_CHANNELS; ++i) { idft(features->channels[i], res->channels[i], cv::DFT_REAL_OUTPUT | cv::DFT_SCALE, 0); } return res; }
/// Compute the match between two WaveformAtAPointFT /// NOTE: in python, the values for timeOffset, phaseOffset, and match are /// also part of the return value (even though Match returns void), e.g.: /// timeOffset, phaseOffset, match = Match(...) void WaveformAtAPointFT::Match(const WaveformAtAPointFT& B, const std::vector<double>& InversePSD, double& timeOffset, double& phaseOffset, double& match) const { /// \param[in] B WaveformAtAPointFT to compute match with /// \param[in] InversePSD Spectrum used to weight contributions by frequencies to match /// \param[out] timeOffset Time offset (in seconds) between the waveforms /// \param[out] phaseOffset Phase offset used between the waveforms /// \param[out] match Match between the two waveforms const unsigned int n = NFreq(); // Only positive frequencies are stored in t const unsigned int N = 2*(n-1); // But this is how many there really are if(!IsNormalized() || !B.IsNormalized()) { cerr << "\n\nWARNING!!! Matching non-normalized WaveformAtAPointFT objects. WARNING!!!\n" << endl; } if(n != B.NFreq() || n != InversePSD.size()) { cerr << "Waveform sizes, " << n << " and " << B.NFreq() << ", are not compatible with InversePSD size, " << InversePSD.size() << "." << endl; throw(GWFrames_VectorSizeMismatch); } const double eps = 1e-8; const double df = F(1)-F(0); const double df_B = B.F(1)-B.F(0); const double rel_diff_df = std::fabs(1 - df/df_B); if(rel_diff_df > eps) { cerr << "Waveform frequency steps, " << df << " and " << df_B << ", are not compatible in Match: rel_diff="<< rel_diff_df << endl; throw(GWFrames_VectorSizeMismatch); } // s1 s2* = (a1 + i b1) (a2 - i b2) = (a1 a2 + b1 b2) + i(b1 a2 - a1 b2) WU::WrapVecDoub data(2*N); for(unsigned int i=0; i<n; ++i) { data.real(i) = (Re(i)*B.Re(i)+Im(i)*B.Im(i))*InversePSD[i]; data.imag(i) = (Im(i)*B.Re(i)-Re(i)*B.Im(i))*InversePSD[i]; } idft(data); unsigned int maxi=0; double maxmag = std::sqrt(sqr(data.real(0)) + sqr(data.imag(0))); for(unsigned int i=1; i<N; ++i) { const double mag = std::sqrt(sqr(data.real(i)) + sqr(data.imag(i))); if(mag>maxmag) { maxmag = mag; maxi = int(i); } } // note: assumes N is even and N >= maxi timeOffset = (maxi<N/2 ? double(maxi)/(N*df) : -double(N-maxi)/(N*df)); phaseOffset = atan2(data.imag(maxi), data.real(maxi))/2.0; /// The return from ifft is just the bare FFT sum, so we multiply by /// df to get the continuum-analog FT. This is correct because the /// input data (re,im) are the continuum-analog data, rather than /// just the return from the bare FFT sum. See, e.g., Eq. (A.33) /// [as opposed to Eq. (A.35)] of my (Mike Boyle's) thesis: /// <http://thesis.library.caltech.edu/143>. match = 4.0*df*maxmag; return; }
int main() { scanf("%d",&C);scanf("%c",&ch);a.clear();b.clear(); for (int i=1;i<=C;i++){a.p_b(0);b.p_b(0);} for (int i=1;i<=C;i++){scanf("%c",&ch);a[C-i]=ch-48;}scanf("%c",&ch); for (int i=1;i<=C;i++){scanf("%c",&ch);b[C-i]=ch-48;} L=0,N=1;while ((N>>1)<C) N*=2,++L; while (a.size()<N) a.p_b(0);while (b.size()<N) b.p_b(0); /*core*/a=dft(a);b=dft(b);for (int i=0;i<N;i++) a[i]=(LL)a[i]*b[i]%bigp;a=idft(a); for (int i=0;i<N;i++){a[i+1]=(a[i+1]+a[i]/10);a[i]%=10;} len=N-1;while ((len>1)&&(a[len]==0)) --len; for (int i=len;i>=0;i--) printf("%d",a[i]);printf("\n"); }
// argv[1] = source name; argv[2] = destination name; argv[3] = reality check name int main( int argc, char *argv[] ) { // Input valdiation if( argc != 4 ) { printf( "\nError: expecting three file name arguments ( src_name, dst_name, rl_name )\n\n" ) ; return 0 ; } // Read src_name and compute dft. Store result in dst_name dft( read_img( argv[0], argv[1] ), argv[2] ) ; // Read dst_name (dft of src_name) and compute idft. Store result in rl_name idft( read_img( argv[0], argv[2] ), argv[3] ) ; return 0 ; }
void spectralResidualSaliencyMap( const Mat_<float> &image, Mat_<float> &saliencyMap, int avgFilterSize, float gaussianSigma, int downSamplingMaxDim) { // down sampling of the image to a size smaller than 64x64 Size newSize = image.cols > image.rows ? Size(downSamplingMaxDim, image.rows * downSamplingMaxDim / image.cols) : Size(image.cols * downSamplingMaxDim / image.rows, downSamplingMaxDim); Mat downSampled8b; resize(image, downSampled8b, newSize); Mat downSampled = Mat_<float>(downSampled8b) / 255.; imshow("downSampled", downSampled); vector<Mat> planes; planes.push_back(downSampled); planes.push_back(Mat::zeros(newSize, CV_32FC1)); Mat downSampledComplex(newSize, CV_32FC2); merge(planes, downSampledComplex); // compute its residual // first compute its spectrum Mat fourierSpectrum; cout<<"computing residual"<<endl; dft(downSampledComplex, fourierSpectrum, DFT_COMPLEX_OUTPUT); Mat parts[2]; split(fourierSpectrum, parts); // apply log scaling // first normalize the range of values to nonnegative values double spectrumMin; minMaxLoc(parts[0], &spectrumMin); parts[0] = parts[0] - spectrumMin + 1; Mat logSpectrum; log(parts[0], logSpectrum); showScaled("spectrum", parts[0]); showScaled("logSpectrum", logSpectrum); Mat logSpectrumParts[] = {logSpectrum, parts[1]}; Mat fullLogSpectrum, invDFTLog; merge(logSpectrumParts, 2, fullLogSpectrum); idft(fullLogSpectrum, invDFTLog, DFT_REAL_OUTPUT); showScaled("invDFTLog", invDFTLog); Mat filteredSpectrum; Mat avgFilter = Mat::ones(avgFilterSize, avgFilterSize, CV_32FC1) / (avgFilterSize * avgFilterSize); filter2D(logSpectrum, filteredSpectrum, -1, avgFilter); Mat residual = logSpectrum - filteredSpectrum; // turn the spectrum back to an image, with some filtering Mat exponentiated(residual.rows, residual.cols, CV_32FC2); Mat unfilteredOutput(downSampled.rows, downSampled.cols, CV_32FC2); Mat squared; // exponentiating the coefficients manually, because opencv sucks at complex // arithmetic for (int i = 0; i < residual.rows; i++) { for (int j = 0; j < residual.cols; j++) { complex<float> coeff(residual.at<float>(i,j), parts[1].at<float>(i,j)); complex<float> expCoeff = exp(coeff); exponentiated.at<Vec2f>(i,j)[0] = expCoeff.real(); exponentiated.at<Vec2f>(i,j)[1] = expCoeff.imag(); } } cout<<"running inverse dft"<<endl; idft(exponentiated, unfilteredOutput, DFT_SCALE); Mat unfilteredParts[2]; split(unfilteredOutput, unfilteredParts); pow(unfilteredParts[0], 2, squared); GaussianBlur(squared, saliencyMap, Size(0,0), gaussianSigma); }
int mri( float* img, float complex* f, float* mask, float lambda, int N1, int N2) { int i, j; float complex* f0 = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dx = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dy = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dx_new = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dy_new = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dtildex = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dtildey = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* u_fft2 = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* u = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* fftmul = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* Lap = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* diff = (float complex*) calloc(N1*N2,sizeof(float complex)); float sum = 0; for(i=0; i<N1; i++) for(j=0; j<N2; j++) sum += (SQR(crealf(f(i,j))/N1) + SQR(cimagf(f(i,j))/N1)); float normFactor = 1.f/sqrtf(sum); float scale = sqrtf(N1*N2); for(i=0; i<N1; i++) { for(j=0; j<N2; j++) { f(i, j) = f(i, j)*normFactor; f0(i, j) = f(i, j); } } Lap(N1-1, N2-1) = 0.f; Lap(N1-1, 0) = 1.f; Lap(N1-1, 1) = 0.f; Lap(0, N2-1) = 1.f; Lap(0, 0) = -4.f; Lap(0, 1) = 1.f; Lap(1, N2-1) = 0.f; Lap(1, 0) = 1.f; Lap(1, 1) = 0.f; float complex *w1; float complex *w2; float complex *buff; dft_init(&w1, &w2, &buff, N1, N2); dft(Lap, Lap, w1, w2, buff, N1, N2); for(i=0;i<N1;i++) for(j=0;j<N2;j++) fftmul(i,j) = 1.0/((lambda/Gamma1)*mask(i,j) - Lap(i,j) + Gamma2); int OuterIter,iter; for(OuterIter= 0; OuterIter<MaxOutIter; OuterIter++) { for(iter = 0; iter<MaxIter; iter++) { for(i=0;i<N1;i++) for(j=0;j<N2;j++) diff(i,j) = dtildex(i,j)-dtildex(i,(j-1)>=0?(j-1):0) + dtildey(i,j)- dtildey((i-1)>=0?(i-1):0,j) ; dft(diff, diff, w1, w2, buff, N1, N2); for(i=0;i<N1;i++) for(j=0;j<N2;j++) u_fft2(i,j) = fftmul(i,j)*(f(i,j)*lambda/Gamma1*scale-diff(i,j)+Gamma2*u_fft2(i,j)) ; idft(u, u_fft2, w1, w2, buff, N1, N2); for(i=0;i<N1;i++) { for(j=0;j<N2;j++) { float tmp; float Thresh=1.0/Gamma1; dx(i,j) = u(i,j<(N2-1)?(j+1):j)-u(i,j)+dx(i,j)-dtildex(i,j) ; dy(i,j) = u(i<(N1-1)?(i+1):i,j)-u(i,j)+dy(i,j)-dtildey(i,j) ; tmp = sqrtf(SQR(crealf(dx(i,j)))+SQR(cimagf(dx(i,j))) + SQR(crealf(dy(i,j)))+SQR(cimagf(dy(i,j)))); tmp = max(0,tmp-Thresh)/(tmp+(tmp<Thresh)); dx_new(i,j) =dx(i,j)*tmp; dy_new(i,j) =dy(i,j)*tmp; dtildex(i,j) = 2*dx_new(i,j) - dx(i,j); dtildey(i,j) = 2*dy_new(i,j) - dy(i,j); dx(i,j) = dx_new(i,j); dy(i,j) = dy_new(i,j); } } } for(i=0;i<N1;i++) { for(j=0;j<N2;j++) { f(i,j) += f0(i,j) - mask(i,j)*u_fft2(i,j)/scale; } } } for(i=0; i<N1; i++) { for(j=0; j<N2; j++) { img(i, j) = sqrt(SQR(crealf(u(i, j))) + SQR(cimagf(u(i, j)))); } } free(w1); free(w2); free(buff); return 0; }
Image *ImageProcessing::convolve(Image *input_image, Image *kernel) { ///Check if the input image is valid if (!input_image || !kernel) return 0x00; ///Get the range of the input image Color *range = new Color[2]; range = input_image->range(); //std::cout << range[0] << std::endl; //std::cout << range[1] << std::endl; ///Kernel size is 2k + 1 int kernel_half_sizex = (kernel->getWidth() - 1)/2; int kernel_half_sizey = (kernel->getHeight() - 1)/2; ///Make the image into a square int max_dim = std::max(input_image->getWidth(), input_image->getHeight()); Image *squared_input_image = new Image(max_dim, max_dim, 0.0f, 0.0f, 0.0f,1.0f); for (int y=0;y<input_image->getHeight();y++) { for (int x=0;x<input_image->getWidth();x++) { squared_input_image->setPixel(x,y,input_image->getPixel(x,y)); } } Image * padded_input_image = padImage(squared_input_image, kernel_half_sizex, kernel_half_sizey); ///Perform the DFT on the image fftw_complex *dft_image_red = dft(padded_input_image, 0, false, -1, -1); fftw_complex *dft_image_green = dft(padded_input_image, 1, false, -1, -1); fftw_complex *dft_image_blue = dft(padded_input_image, 2, false, -1, -1); ///Perform the DFT on the kernel. Make sure the padding is set to 0 and it's the same size as the image fftw_complex *dft_kernel_red = dft(kernel, 0, true, padded_input_image->getWidth(), padded_input_image->getHeight()); fftw_complex *dft_kernel_green = dft(kernel, 1, true, padded_input_image->getWidth(), padded_input_image->getHeight()); fftw_complex *dft_kernel_blue = dft(kernel, 2, true, padded_input_image->getWidth(), padded_input_image->getHeight()); ///Multiply the two together for (int k=0,y=0;y<padded_input_image->getHeight();y++) { for (int x=0;x<padded_input_image->getWidth();x++,k++) { float red_val1 = dft_image_red[k][0] * dft_kernel_red[k][0] - dft_image_red[k][1] * dft_kernel_red[k][1]; float red_val2 = dft_image_red[k][0] * dft_kernel_red[k][1] + dft_image_red[k][1] * dft_kernel_red[k][0]; dft_image_red[k][0] = red_val1; dft_image_red[k][1] = red_val2; float green_val1 = dft_image_green[k][0] * dft_kernel_green[k][0] - dft_image_green[k][1] * dft_kernel_green[k][1]; float green_val2 = dft_image_green[k][0] * dft_kernel_green[k][1] + dft_image_green[k][1] * dft_kernel_green[k][0]; dft_image_green[k][0] = green_val1; dft_image_green[k][1] = green_val2; float blue_val1 = dft_image_blue[k][0] * dft_kernel_blue[k][0] - dft_image_blue[k][1] * dft_kernel_blue[k][1]; float blue_val2 = dft_image_blue[k][0] * dft_kernel_blue[k][1] + dft_image_blue[k][1] * dft_kernel_blue[k][0]; dft_image_blue[k][0] = blue_val1; dft_image_blue[k][1] = blue_val2; } } ///Perform the inverse DFT on the multiplication result fftw_complex *idft_image_red = idft(dft_image_red, padded_input_image->getWidth(), padded_input_image->getHeight()); fftw_complex *idft_image_green = idft(dft_image_green, padded_input_image->getWidth(), padded_input_image->getHeight()); fftw_complex *idft_image_blue = idft(dft_image_blue, padded_input_image->getWidth(), padded_input_image->getHeight()); ///Convert to Image format Image *padded_output_image = copy(idft_image_red, 0, padded_input_image->getWidth(), padded_input_image->getHeight(), 0x00); copy(idft_image_green, 1, padded_input_image->getWidth(), padded_input_image->getHeight(), padded_output_image); copy(idft_image_blue, 2, padded_input_image->getWidth(), padded_input_image->getHeight(), padded_output_image); //Unpad the image Image *squared_output_image = unpadImage(padded_output_image, kernel_half_sizex, kernel_half_sizey); Image *output_image = new Image(input_image->getWidth(), input_image->getHeight()); for (int y=0;y<output_image->getHeight();y++) { for (int x=0;x<output_image->getWidth();x++) { output_image->setPixel(x,y,squared_output_image->getPixel(x,y)); } } output_image->normalize(); output_image->normalize(range); fftw_free(dft_image_red); fftw_free(dft_image_green); fftw_free(dft_image_blue); fftw_free(dft_kernel_red); fftw_free(dft_kernel_green); fftw_free(dft_kernel_blue); fftw_free(idft_image_red); fftw_free(idft_image_green); fftw_free(idft_image_blue); delete padded_input_image; delete padded_output_image; delete squared_input_image; delete squared_output_image; delete [] range; return output_image; }
int mri( float* img, float complex* f, float* mask, float lambda, int N1, int N2) { int i, j; float complex* f0 = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dx = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dy = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dx_new = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dy_new = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dtildex = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dtildey = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* u_fft2 = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* u = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* fftmul = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* Lap = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* diff = (float complex*) calloc(N1*N2,sizeof(float complex)); float sum = 0; float scale = sqrtf(N1*N2); Lap(N1-1, N2-1) = 0.f; Lap(N1-1, 0) = 1.f; Lap(N1-1, 1) = 0.f; Lap(0, N2-1) = 1.f; Lap(0, 0) = -4.f; Lap(0, 1) = 1.f; Lap(1, N2-1) = 0.f; Lap(1, 0) = 1.f; Lap(1, 1) = 0.f; float complex *w1; float complex *w2; float complex *buff; double lambdaGamma1 = lambda/Gamma1; double lambdaGamma1Scale = lambda/Gamma1*scale; float Thresh=1.0/Gamma1; MPI_Datatype mpi_complexf; MPI_Type_contiguous(2, MPI_FLOAT, &mpi_complexf); MPI_Type_commit(&mpi_complexf); int np, rank; MPI_Comm_size(MPI_COMM_WORLD ,&np); MPI_Comm_rank(MPI_COMM_WORLD ,&rank); int chunksize = N1/np; int start = rank * chunksize; int cnt[np]; int disp[np]; for (i = 0 ; i < np - 1; i ++) { cnt[i] = chunksize * N2 ; disp[i] = chunksize * i * N2; } cnt[i] = (chunksize + N1%np) * N2; disp[i] = chunksize * i * N2; if (rank == np - 1) chunksize += N1%np; int end = start + chunksize; for(i=start; i<chunksize; i++) for(j=0; j<N2; j++) sum += (SQR(crealf(f(i,j))/N1) + SQR(cimagf(f(i,j))/N1)); MPI_Allreduce(&sum, &sum, 1, MPI_FLOAT, MPI_SUM, MPI_COMM_WORLD); float normFactor = 1.f/sqrtf(sum); for(i=0; i<N1; i++) { for(j=0; j<N2; j++) { f(i, j) = f(i, j)*normFactor; f0(i, j) = f(i, j); } } dft_init(&w1, &w2, &buff, N1, N2); dft(Lap, Lap, w1, w2, buff, N1, N2, start, end, cnt, disp, mpi_complexf, rank); MPI_Status *status; for(i=start;i<end;i++) for(j=0;j<N2;j++) fftmul(i,j) = 1.0/((lambda/Gamma1)*mask(i,j) - Lap(i,j) + Gamma2); int OuterIter,iter; for(OuterIter= 0; OuterIter<MaxOutIter; OuterIter++) { for(iter = 0; iter<MaxIter; iter++) { for(i=start;i<end;i++) for(j=0;j<N2;j++) diff(i,j) = dtildex(i,j)-dtildex(i,(j-1)>=0?(j-1):0) + dtildey(i,j)- dtildey((i-1)>=0?(i-1):0,j) ; dft(diff, diff, w1, w2, buff, N1, N2, start, end, cnt, disp, mpi_complexf, rank); for(i=start;i<end;i++) { for(j=0;j<N2;j++) { u_fft2(i,j) = fftmul(i,j)*(f(i,j)*lambdaGamma1Scale-diff(i,j)+Gamma2*u_fft2(i,j)) ; if (iter == MaxIter - 1) f(i,j) += f0(i,j) - mask(i,j)*u_fft2(i,j)/scale; } } idft(u, u_fft2, w1, w2, buff, N1, N2, start, end, cnt, disp, mpi_complexf, rank); //MPI_Allgatherv(u + disp[rank], cnt[rank], mpi_complexf, u, cnt, disp, mpi_complexf, MPI_COMM_WORLD); if (rank == np - 1) MPI_Send(u + disp[rank], N2, mpi_complexf, rank - 1, 0, MPI_COMM_WORLD); else if (rank == 0) MPI_Recv(u + disp[rank] + cnt[rank], N2, mpi_complexf, rank + 1, 0, MPI_COMM_WORLD, status); else { MPI_Recv(u + disp[rank] + cnt[rank], N2, mpi_complexf, rank + 1, 0, MPI_COMM_WORLD, status); MPI_Send(u + disp[rank], N2, mpi_complexf, rank - 1, 0, MPI_COMM_WORLD); } for(i=start;i<end;i++) { for(j=0;j<N2;j++) { float tmp; dx(i,j) = u(i,j<(N2-1)?(j+1):j)-u(i,j)+dx(i,j)-dtildex(i,j) ; dy(i,j) = u(i<(N1-1)?(i+1):i,j)-u(i,j)+dy(i,j)-dtildey(i,j) ; tmp = sqrtf(SQR(crealf(dx(i,j)))+SQR(cimagf(dx(i,j))) + SQR(crealf(dy(i,j)))+SQR(cimagf(dy(i,j)))); tmp = max(0,tmp-Thresh)/(tmp+(tmp<Thresh)); dx_new(i,j) =dx(i,j)*tmp; dy_new(i,j) =dy(i,j)*tmp; dtildex(i,j) = 2*dx_new(i,j) - dx(i,j); dtildey(i,j) = 2*dy_new(i,j) - dy(i,j); dx(i,j) = dx_new(i,j); dy(i,j) = dy_new(i,j); } } //MPI_Allgatherv(dtildey + disp[rank], cnt[rank], mpi_complexf, dtildey, cnt, disp, mpi_complexf, MPI_COMM_WORLD); if (rank == np - 1) MPI_Recv(dtildey + disp[rank] - N2, N2, mpi_complexf, rank - 1, 0, MPI_COMM_WORLD, status); else if (rank == 0) MPI_Send(dtildey + disp[rank] + cnt[rank] - N2, N2, mpi_complexf, rank + 1, 0, MPI_COMM_WORLD); else { MPI_Recv(dtildey + disp[rank] - N2, N2, mpi_complexf, rank - 1, 0, MPI_COMM_WORLD, status); MPI_Send(dtildey + disp[rank] + cnt[rank] - N2, N2, mpi_complexf, rank + 1, 0, MPI_COMM_WORLD); } } } for(i=start; i<end; i++) { for(j=0; j<N2; j++) { img(i, j) = sqrt(SQR(crealf(u(i, j))) + SQR(cimagf(u(i, j)))); } } MPI_Gatherv(img + disp[rank], cnt[rank], MPI_FLOAT, img, cnt, disp, MPI_FLOAT, 0, MPI_COMM_WORLD); free(w1); free(w2); free(buff); MPI_Finalize(); if (rank > 0) exit(0); return 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; }