00001 #ifndef Impala_Core_Feature_LaplacianDetector_h
00002 #define Impala_Core_Feature_LaplacianDetector_h
00003
00004 #include "Basis/Timer.h"
00005 #include "Core/Array/Laplacian.h"
00006 #include "Core/Feature/PointDescriptorTable.h"
00007 #include "Core/Table/Sort.h"
00008
00009
00010 namespace Impala
00011 {
00012 namespace Core
00013 {
00014 namespace Feature
00015 {
00016
00017
00018 template<class SrcArrayT>
00019 PointDescriptorTable*
00020 LaplacianDetection(SrcArrayT* imIntensity,
00021 bool useRecGauss, Real64 precision)
00022 {
00023 ILOG_VAR(Core.Feature.LaplacianDetection);
00024 PointDescriptorTable* output = new PointDescriptorTable();
00025 using namespace Impala::Core::Array;
00026 std::vector<Real64> precomputeScales;
00027 std::vector<Array2dScalarReal64*> cache;
00028 for(int i = 0; i < 21; i++)
00029 {
00030 Real64 sigma = pow(sqrt(sqrt(Real64(2))),i) * 0.8;
00031 precomputeScales.push_back(sigma);
00032 Array2dScalarReal64* tmp = 0;
00033 Laplacian(tmp, imIntensity, sigma, 1, useRecGauss, precision);
00034 cache.push_back(tmp);
00035
00036 ILOG_DEBUG("Computing Laplacian scale: " << sigma);
00037 }
00038
00039 int borderIgnoreSize = 5;
00040 for(int i = 1; i < 20; i++)
00041 {
00042 Geometry::InterestPointList pointList;
00043 Array2dScalarReal64* imPrev = cache[i-1];
00044 Array2dScalarReal64* im = cache[i];
00045 Array2dScalarReal64* imNext = cache[i+1];
00046 for(int x = borderIgnoreSize; x < im->CW() - borderIgnoreSize; x++)
00047 {
00048 for(int y = borderIgnoreSize; y < im->CH() - borderIgnoreSize; y++)
00049 {
00050 Real64 v = im->Val(x, y);
00051 if(fabs(v) < 0.001) continue;
00052 if((v >= im->Val(x, y+1)) &&
00053 (v >= im->Val(x+1, y)) &&
00054 (v >= im->Val(x, y-1)) &&
00055 (v >= im->Val(x-1, y)) &&
00056 (v >= im->Val(x+1, y+1)) &&
00057 (v >= im->Val(x-1, y-1)) &&
00058 (v >= im->Val(x-1, y+1)) &&
00059 (v >= im->Val(x+1, y-1)) &&
00060 (v >= imPrev->Val(x, y)) &&
00061 (v >= imPrev->Val(x, y+1)) &&
00062 (v >= imPrev->Val(x+1, y)) &&
00063 (v >= imPrev->Val(x, y-1)) &&
00064 (v >= imPrev->Val(x-1, y)) &&
00065 (v >= imPrev->Val(x+1, y+1)) &&
00066 (v >= imPrev->Val(x-1, y-1)) &&
00067 (v >= imPrev->Val(x-1, y+1)) &&
00068 (v >= imPrev->Val(x+1, y-1)) &&
00069 (v >= imNext->Val(x, y)) &&
00070 (v >= imNext->Val(x, y+1)) &&
00071 (v >= imNext->Val(x+1, y)) &&
00072 (v >= imNext->Val(x, y-1)) &&
00073 (v >= imNext->Val(x-1, y)) &&
00074 (v >= imNext->Val(x+1, y+1)) &&
00075 (v >= imNext->Val(x-1, y-1)) &&
00076 (v >= imNext->Val(x-1, y+1)) &&
00077 (v >= imNext->Val(x+1, y-1)))
00078 {
00079
00080 output->Add(x, y, precomputeScales[i], 0, v);
00081 } else if((v <= im->Val(x, y+1)) &&
00082 (v <= im->Val(x+1, y)) &&
00083 (v <= im->Val(x, y-1)) &&
00084 (v <= im->Val(x-1, y)) &&
00085 (v <= im->Val(x+1, y+1)) &&
00086 (v <= im->Val(x-1, y-1)) &&
00087 (v <= im->Val(x-1, y+1)) &&
00088 (v <= im->Val(x+1, y-1)) &&
00089 (v <= imPrev->Val(x, y)) &&
00090 (v <= imPrev->Val(x, y+1)) &&
00091 (v <= imPrev->Val(x+1, y)) &&
00092 (v <= imPrev->Val(x, y-1)) &&
00093 (v <= imPrev->Val(x-1, y)) &&
00094 (v <= imPrev->Val(x+1, y+1)) &&
00095 (v <= imPrev->Val(x-1, y-1)) &&
00096 (v <= imPrev->Val(x-1, y+1)) &&
00097 (v <= imPrev->Val(x+1, y-1)) &&
00098 (v <= imNext->Val(x, y)) &&
00099 (v <= imNext->Val(x, y+1)) &&
00100 (v <= imNext->Val(x+1, y)) &&
00101 (v <= imNext->Val(x, y-1)) &&
00102 (v <= imNext->Val(x-1, y)) &&
00103 (v <= imNext->Val(x+1, y+1)) &&
00104 (v <= imNext->Val(x-1, y-1)) &&
00105 (v <= imNext->Val(x-1, y+1)) &&
00106 (v <= imNext->Val(x+1, y-1)))
00107 {
00108
00109 output->Add(x, y, precomputeScales[i], 0, v);
00110 }
00111 }
00112 }
00113 }
00114 for(int i = 0; i < cache.size(); i++)
00115 {
00116 delete cache[i];
00117 }
00118 return output;
00119 }
00120
00121
00122 template<class SrcArrayT>
00123 PointDescriptorTable*
00124 LaplacianDetector(SrcArrayT* input,
00125 bool useRecGauss=true, Real64 precision=3.0)
00126 {
00127 ILOG_VAR(Core.Feature.LaplacianDetector);
00128 using namespace Impala::Core::Array;
00129 Timer timer;
00130
00131
00132 Array2dScalarReal64* imIntensity = 0;
00133 RGB2Gray(imIntensity, input);
00134
00135
00136 PointDescriptorTable* output = LaplacianDetection(imIntensity,
00137 useRecGauss, precision);
00138
00139 ILOG_INFO("Laplacian detector found " << output->Size() << " points; " <<
00140 timer.SplitTimeStr());
00141
00142 delete imIntensity;
00143
00144
00145
00146
00147
00148
00149
00150
00151 SortOnColumn5(output, false);
00152 return output;
00153 }
00154
00155 }
00156 }
00157 }
00158
00159 #endif