00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Image/Rectangle.H"
00039 #include "CUDA/CudaImage.H"
00040 #include "Util/Assert.H"
00041 #include "CUDA/cudadefs.h"
00042 #include "CUDA/CudaMathOps.H"
00043 #include "CUDA/CudaLowPass.H"
00044 #include "CUDA/CudaShapeOps.H"
00045 #include "CUDA/CudaCutPaste.H"
00046 #include "CUDA/CudaKernels.H"
00047 #include "CUDA/CudaConvolutions.H"
00048 #include "CUDA/CudaNorm.H"
00049 #include "CudaFilterOps.H"
00050 #include "CudaDevices.H"
00051 #include "Util/Timer.H"
00052 #include "wrap_c_cuda.h"
00053
00054
00055 CudaImage<float> cudaOrientedFilter(const CudaImage<float>& src, const float k,
00056 const float theta, const float intensity)
00057 {
00058 double kx = double(k) * cos((theta + 90.0) * M_PI / 180.0);
00059 double ky = double(k) * sin((theta + 90.0) * M_PI / 180.0);
00060 MemoryPolicy mp = src.getMemoryPolicy();
00061 int dev = src.getMemoryDevice();
00062 Dims tile = CudaDevices::getDeviceTileSize1D(dev);
00063 CudaImage<float> re(src.getDims(), NO_INIT, mp, dev);
00064 CudaImage<float> im(src.getDims(), NO_INIT, mp, dev);
00065
00066 cuda_c_orientedFilter(src.getCudaArrayPtr(),re.getCudaArrayPtr(),im.getCudaArrayPtr(),(float)kx,(float)ky,intensity,src.getWidth(),src.getHeight(),tile.sz());
00067
00068 re = cudaLowPass9(re);
00069 im = cudaLowPass9(im);
00070
00071 return cudaQuadEnergy(re, im);
00072 }
00073
00074
00075
00076 CudaImage<float> cudaCenterSurround(const CudaImage<float>& center, const CudaImage<float>& surround,
00077 const bool absol)
00078 {
00079 ASSERT(center.initialized() && surround.initialized());
00080 ASSERT(center.getMemoryDevice() == surround.getMemoryDevice());
00081
00082 const int lw = center.getWidth(), lh = center.getHeight();
00083 const int sw = surround.getWidth(), sh = surround.getHeight();
00084
00085 if (sw > lw || sh > lh) LFATAL("center must be larger than surround");
00086
00087 MemoryPolicy mp = center.getMemoryPolicy();
00088 int dev = center.getMemoryDevice();
00089 Dims tile = CudaDevices::getDeviceTileSize1D(dev);
00090
00091
00092 CudaImage<float> result(center.getDims(), NO_INIT, mp, dev);
00093
00094
00095 if(absol)
00096 cuda_c_centerSurroundAbs(center.getCudaArrayPtr(), surround.getCudaArrayPtr(), result.getCudaArrayPtr(), lw, lh, sw, sh, tile.sz());
00097 else
00098 cuda_c_centerSurroundClamped(center.getCudaArrayPtr(), surround.getCudaArrayPtr(), result.getCudaArrayPtr(), lw, lh, sw, sh, tile.sz());
00099
00100
00101 cudaInplaceAttenuateBorders(result, result.getDims().max() / 20);
00102
00103
00104 return result;
00105
00106 }
00107
00108
00109 void cudaCenterSurround(const CudaImage<float>& center, const CudaImage<float>& surround,
00110 CudaImage<float>& pos, CudaImage<float>& neg)
00111 {
00112
00113 const int lw = center.getWidth(), lh = center.getHeight();
00114 const int sw = surround.getWidth(), sh = surround.getHeight();
00115
00116 if (sw > lw || sh > lh) LFATAL("center must be larger than surround");
00117
00118 MemoryPolicy mp = center.getMemoryPolicy();
00119 int dev = center.getMemoryDevice();
00120 Dims tile = CudaDevices::getDeviceTileSize1D(dev);
00121
00122
00123 pos = CudaImage<float>(center.getDims(), NO_INIT,mp,dev);
00124 neg = CudaImage<float>(center.getDims(), NO_INIT,mp,dev);
00125
00126 cuda_c_centerSurroundDirectional(center.getCudaArrayPtr(), surround.getCudaArrayPtr(), pos.getCudaArrayPtr(), neg.getCudaArrayPtr(),
00127 lw,lh,sw,sh,tile.sz());
00128
00129 cudaInplaceAttenuateBorders(pos, pos.getDims().max() / 20);
00130 cudaInplaceAttenuateBorders(neg, neg.getDims().max() / 20);
00131 }
00132
00133
00134
00135 CudaImage<float> cudaDoubleOpp(const CudaImage<float>& cplus, const CudaImage<float>& cminus,
00136 const CudaImage<float>& splus, const CudaImage<float>& sminus)
00137 {
00138 ASSERT(cplus.isSameSize(cminus)); ASSERT(splus.isSameSize(sminus));
00139
00140
00141
00142 CudaImage<float> cdiff = cplus;
00143 cdiff -= cminus;
00144
00145
00146 CudaImage<float> sdiff = splus;
00147 sdiff -= sminus;
00148
00149
00150 return cudaCenterSurround(cdiff, sdiff, true);
00151 }
00152
00153
00154
00155 CudaImage<float> cudaCenterSurroundAbsDownScaleNormalize(const CudaImage<float>& center, const CudaImage<float>& surround,
00156 const bool absol, int newWidth, int newHeight, float mi, float ma, int nIter, float weakness)
00157 {
00158
00159
00160 ASSERT(center.initialized() && surround.initialized());
00161 ASSERT(center.getMemoryDevice() == surround.getMemoryDevice());
00162
00163 const int lw = center.getWidth(), lh = center.getHeight();
00164 const int sw = surround.getWidth(), sh = surround.getHeight();
00165
00166 if (sw > lw || sh > lh) LFATAL("center must be larger than surround");
00167
00168 MemoryPolicy mp = center.getMemoryPolicy();
00169 int dev = center.getMemoryDevice();
00170 Dims tile = CudaDevices::getDeviceTileSize(dev);
00171
00172
00173
00174 CudaImage<float> result(center.getDims(), NO_INIT, mp, dev);
00175
00176
00177 const int attBorder = std::max(lw, lh)/20;
00178
00179 cuda_c_centerSurroundAbsAttenuate(center.getCudaArrayPtr(), surround.getCudaArrayPtr(), result.getCudaArrayPtr(), lw, lh, sw, sh, attBorder, tile.w(), tile.h());
00180
00181 result = cudaDownSize(result, newWidth, newHeight);
00182 cudaInplaceRectify(result);
00183
00184
00185 if (mi != 0.0F || ma != 0.0F) cudaInplaceNormalize(result, mi, ma);
00186
00187
00188
00189
00190 const int w = result.getWidth();
00191 const int h = result.getHeight();
00192 int siz = std::max(w, h);
00193 int maxhw = std::max(0, std::min(w, h) / 2 - 1);
00194
00195
00196 CudaImage<float> maxim = CudaImage<float>(1,1,NO_INIT,mp,dev);
00197
00198
00199
00200
00201 float esig = (float(siz) * FANCYESIG) * 0.01F;
00202 float isig = (float(siz) * FANCYISIG) * 0.01F;
00203 CudaImage<float> gExc = cudaGaussian(mp,dev,FANCYCOEX/(esig*sqrt(2.0*M_PI)) * weakness, esig, maxhw);
00204 CudaImage<float> gInh = cudaGaussian(mp,dev,FANCYCOIN/(isig*sqrt(2.0*M_PI)) * weakness, isig, maxhw);
00205
00206 for (int i = 0; i < nIter; ++i)
00207 {
00208
00209 CudaImage<float> excit = cudaSepFilter(result, gExc, gExc, CONV_BOUNDARY_CLEAN);
00210 CudaImage<float> inhib = cudaSepFilter(result, gInh, gInh, CONV_BOUNDARY_CLEAN);
00211
00212
00213 excit -= inhib;
00214 cudaGetMax(result, maxim);
00215
00216 result += excit;
00217
00218 result += cudaGetScalar(maxim)*(-0.01F * FANCYINHI) ;
00219
00220 cudaInplaceRectify(result);
00221
00222
00223 }
00224
00225
00226 return result;
00227
00228 }
00229
00230
00231
00232 CudaImage<float> cudaSpatialPoolMax(const CudaImage<float>& src, const int si, const int sj,
00233 const int sti, const int stj)
00234 {
00235 const int w = src.getWidth(), h = src.getHeight();
00236 MemoryPolicy mp = src.getMemoryPolicy();
00237 int dev = src.getMemoryDevice();
00238 Dims tile = CudaDevices::getDeviceTileSize(dev);
00239
00240
00241
00242 CudaImage<float> buf1(src.getSize(),1, NO_INIT,mp,dev);
00243 CudaImage<float> buf2(src.getSize(),1, NO_INIT,mp,dev);
00244 int res_w = (int)ceil((float)w / (float)si);
00245 int res_h = (int)ceil((float)h / (float)sj);
00246 CudaImage<float> result(res_w,res_h,NO_INIT,mp,dev);
00247 cuda_c_spatialPoolMax(src.getCudaArrayPtr(),result.getCudaArrayPtr(),buf1.getCudaArrayPtr(),buf2.getCudaArrayPtr(),w,h,si,sj,sti,stj,tile.w(),tile.h());
00248 return result;
00249 }
00250
00251