00001
00002 template<class Numeric>
00003 std::ostream& operator<<(std::ostream& out, const std::vector<Numeric>& vector){
00004 for(uint i = 0; i < vector.size(); i++){
00005 out << vector[i] << " ";
00006 }
00007 return out;
00008 }
00009
00010 template<class Numeric>
00011 std::vector<Numeric> convolve1D(const std::vector<Numeric>& _source, const std::vector<Numeric>& _kernel, int _offset, ConvolutionPadding _padding, ConvolutionResult _resultType){
00012 _resultType = (_padding == CIRCULAR) ? SAME : _resultType;
00013 bool inverted = (_source.size() < _kernel.size());
00014 const std::vector<Numeric>& source = (inverted) ? _kernel : _source;
00015 const std::vector<Numeric>& kernel = (inverted) ? _source : _kernel;
00016 unsigned int size = _source.size() + (_resultType == FULL) * (_kernel.size() - 1);
00017 std::vector<Numeric> result(size);
00018
00019 unsigned int i = 0;
00020 for( ; i < result.size(); i++){
00021 result[i] = 0;
00022
00023 int j = (int)i - (int)kernel.size() + 1 ;
00024 for(; j <= (int)i && j < _offset; j++){
00025 Numeric pad = 0;
00026 switch(_padding) {
00027 case ZERO:
00028 pad = 0; break;
00029 case SPECULAR:
00030 pad = source[_offset - j]; break;
00031 case CIRCULAR:
00032 pad = source[source.size() + j -_offset]; break;
00033 }
00034 result[i] += pad * kernel[i - j];
00035 }
00036
00037 for( ; j <= (int)i && j < (int)source.size() + _offset; j++){
00038 result[i] += source[j - _offset] * kernel[i - j];
00039 }
00040
00041 for( ; j <= (int)i; j++){
00042 Numeric pad = 0;
00043 switch (_padding){
00044 case ZERO:
00045 pad = 0; break;
00046 case SPECULAR:
00047 pad = source[2*source.size() - 1 - j + _offset]; break;
00048 case CIRCULAR:
00049 pad = source[j - _offset -source.size()]; break;
00050 }
00051 result[i] += pad * kernel[i - j];
00052 }
00053 }
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 return result;
00073 }
00074
00075 template<class Numeric>
00076 std::vector<Numeric> besselKernel1D(Numeric _sigma, unsigned int _kernelSize){
00077 unsigned int size = (_kernelSize % 2) ? _kernelSize : _kernelSize + 1;
00078 std::vector<Numeric> result(size);
00079 Numeric accumulator = 0;
00080
00081 for(unsigned int i = 0; i < size; i++){
00082 result[i] = exp(_sigma) * boost::math::cyl_bessel_i(i - 0.5*(size-1),_sigma);
00083 accumulator += result[i];
00084 }
00085
00086 for(unsigned int i = 0; i < size; i++){
00087 result[i] = result[i] / accumulator;
00088 }
00089
00090 return result;
00091 }
00092
00093 template<class Numeric>
00094 std::vector<Numeric> gaussianKernel1D(Numeric sigma, unsigned int _kernelSize){
00095 unsigned int size = (_kernelSize % 2) ? _kernelSize : _kernelSize + 1;
00096 std::vector<Numeric> result(size);
00097 Numeric accumulator = 0;
00098
00099 for(unsigned int i = 0; i < size; i++){
00100 Numeric x = i - 0.5*(size-1);
00101 result[i] = exp(-x*x/(2*sigma));
00102 accumulator += result[i];
00103 }
00104
00105 for(unsigned int i = 0; i < size; i++){
00106 result[i] = result[i] / accumulator;
00107 }
00108
00109 return result;
00110 }