void convolve(cv::Mat_<float> &im, const int axis, const float* kernel) { if(axis >= im.dims) throw std::invalid_argument("Matrix dimension is too small to convolve along this axis"); assert(im.isContinuous()); Convolver co(im.size[axis]); unsigned long int step = im.step1(axis); //whatever the real dimension, we fall back to a 3d situation where the axis of interest is y //and either x or z can be of size 1 int nbplanes = 1; for(int d=0; d<axis; ++d) nbplanes *= im.size[d]; int planestep = im.total()/nbplanes; //for each plane for(int i=0; i<nbplanes; ++i) //for each line for(size_t j=0; j<step; ++j) co(reinterpret_cast<float*>(im.data) + i*planestep + j, step, kernel); }
std::vector<float> get_spectrum_1d(const cv::Mat_<float> &im, const int axis, const bool windowing) { if(axis >= im.dims) throw std::invalid_argument("Matrix dimension is too small to compute the spectrum along this axis"); assert(im.isContinuous()); Convolver co(im.size[axis]); if(windowing) co.set_hanning(); std::vector<float> spectrum(co.fourier_size()); std::vector<double> tot(co.fourier_size(), 0.0); std::vector<std::complex<double> > totf(co.fourier_size(), 0.0); unsigned long int step = im.step1(axis); //whatever the real dimension, we fall back to a 3d situation where the axis of interest is y //and either x or z can be of size 1 int nbplanes = 1; for(int d=0; d<axis; ++d) nbplanes *= im.size[d]; int planestep = im.total()/nbplanes; //for each plane for(int i=0; i<nbplanes; ++i) { //for each line for(size_t j=0; j<step; ++j) { co.spectrum(reinterpret_cast<float* const>(im.data) + i*planestep + j, step, &spectrum[0]); for(size_t u=0; u<spectrum.size(); ++u) tot[u] += spectrum[u]; for(size_t u=0; u<spectrum.size(); ++u) totf[u] += co.get_fourier()[u]; } } const double icount = 1.0 / (nbplanes * step); for(size_t i=0; i<tot.size(); ++i) spectrum[i] = tot[i]*icount - std::norm(totf[i]*icount); return spectrum; }