00001
00002
00003 #include "config.h"
00004 #include "Convolution.h"
00005
00006 #ifdef HAVE_LIBFFTW
00007 #include "fftwlib.h"
00008 #endif
00009
00010 #define RANGE(i, j, sy, sx) ( (i>=0) && (j>=0) && (i<sy) && (j<sx) )
00011
00012 template void Convolution< int >(Image< int > &input1, Image< int > &input2, Image< int > &output);
00013 template void Convolution< byte >(Image< byte > &input1, Image< byte > &input2, Image< byte > &output);
00014 template void Convolution< float >(Image< float > &input1, Image< float > &input2, Image< float > &output);
00015
00016 template< class T >
00017 void Convolution(Image< T > &input1, Image< T > &input2, Image< T > &output)
00018 {
00019 #ifdef HAVE_LIBFFTW
00020 if (typeid(T) == typeid(float)) {
00021 T *data = NULL;
00022 try {
00023 data = (T *)calloc(input1.getSize(), sizeof(T));
00024 Assert<Fatal_error>(data);
00025 }
00026 catch(Fatal_error e) { e.print("Unable to allocate memory"); }
00027 if ((input1.getWidth()!= input2.getWidth()) &&
00028 (input1.getHeight()!= input2.getHeight())) {
00029 ERROR("Cannot convolve float images with different size");
00030 }
00031
00032 _convolve((float *)(input1.getPixels()),(float *)(input2.getPixels()),
00033 input1.getWidth(), input1.getHeight(), (float *)(data));
00034 output.setPixels(input1.getWidth(), input1.getHeight(), data);
00035 free(data);
00036 }
00037 else
00038 #endif
00039 {
00040 int wi = input1.getWidth(), hi = input1.getHeight(),
00041 wk = input2.getWidth(), hk = input2.getHeight();
00042 int wk2 = wk>>1, hk2 = hk>>1, kk, mm;
00043 T *data = NULL;
00044 try {
00045 data = (T *)calloc(input1.getSize(), sizeof(T));
00046 Assert<Fatal_error>(data);
00047 }
00048 catch(Fatal_error e) { e.print("Unable to allocate memory"); }
00049
00050 for(int i=0; i<hi;i++)
00051 for(int j=0;j<wi;j++) {
00052 for(int k=-hk2;k<hk2;k++)
00053 for(int m=-wk2;m<wk2;m++) {
00054
00055 kk = i + k; mm = j + m;
00056 if(kk<0) kk = i - k;
00057 else if(kk>=hi) kk -= hi;
00058 if(mm<0) mm = j - m;
00059 else if(mm>=wi) mm -= wi;
00060 data[i*wi+j] += (input2)[k+hk2][m+wk2] *
00061 (input1)[kk][mm];
00062 }
00063 }
00064 output.setPixels(wi, hi, data);
00065 free(data);
00066 }
00067 }
00068
00069
00070