Definition at line 39 of file RegionDescriptor.h. References Impala::Core::Array::Add(), Impala::Core::Array::AddVal(), Impala::Core::Array::Atan2(), Impala::Core::Array::Array2dTem< StorT, elemSize, ArithT >::CH(), Impala::Core::Array::ColorMoments(), CreateCircleMask(), Impala::Core::Array::Array2dTem< StorT, elemSize, ArithT >::CW(), Impala::Core::Array::Array2dTem< StorT, elemSize, ArithT >::ElemSize(), Impala::Util::Database::GetInstance(), Impala::CmdOptions::GetInstance(), Impala::CmdOptions::GetInt(), Impala::Core::Histogram::MakeHistogram1d(), Impala::Core::Array::Mul(), Impala::Core::Array::MulVal(), Impala::Core::Array::PixSum(), Impala::Core::Array::ProjectRange(), Impala::Core::Array::Resample(), Impala::Core::Array::Rgb2Ooo(), Impala::Core::Array::RGB2rg(), Impala::Core::Array::Sqrt(), and Impala::Core::Array::WriteRaw(). Referenced by CalculateRegionDescriptors(). 00042 { 00043 using namespace Impala::Core::Array; 00044 using namespace Impala::Core::Histogram; 00045 00046 /* note: ensure that vec is empty when you call this function */ 00047 //WriteRaw(src, String("src.raw"), false); 00048 00049 /* certain descriptors can only be computed over square images */ 00050 bool imgIsSquare = (src->CW() == src->CH()); 00051 int binCount = 15; 00052 Real64 uniformPatchSize = 61; // when making the src uniformly sized; resize to 61x61 00053 00054 /* support bin count changing */ 00055 CmdOptions& options = CmdOptions::GetInstance(); 00056 binCount = options.GetInt("descriptorBinCount"); 00057 00058 Array2dScalarReal64* circleMask = 0; 00059 if(useCircularMask) { 00060 if(!imgIsSquare) { 00061 std::cerr << "[ERROR] Using circularMask on a non-square source!" << std::endl; 00062 throw "Using circularMask on a non-square source!"; 00063 } 00064 circleMask = CreateCircleMask(src->CW()); 00065 } 00066 00067 if(descriptor == "opponenthistogram") { 00068 /***** OPPONENT COLOR HISTOGRAM *****/ 00069 vec.reserve(binCount * 3); 00070 00071 // color conversion 00072 Array2dVec3Real64* srcOpponent = 0; 00073 Rgb2Ooo(srcOpponent, src); 00074 //WriteRaw(srcOpponent, String("srcopp.raw"), false); 00075 00076 double lower[3] = {0, -70, -70}; 00077 double upper[3] = {270, 70, 70}; 00078 00079 if(useCircularMask) { 00080 AddVal(circleMask, circleMask, -1); 00081 MulVal(circleMask, circleMask, 1000); // now it is 0 in the circle and -1000 elsewhere 00082 } 00083 00084 for (int d=1 ; d<=src->ElemSize() ; d++) 00085 { 00086 Array2dScalarReal64* comp = 0; 00087 ProjectRange(comp, srcOpponent, d); 00088 00089 if(useCircularMask) { 00090 /* add them together, making values outside the circle very negative (i.e. an outlier) */ 00091 Add(comp, comp, circleMask); 00092 //WriteRaw(comp, String("x.raw"), false); 00093 } 00094 00095 Histogram1dTem<Real64> hist(lower[d-1], upper[d-1], binCount, 0); 00096 MakeHistogram1d(&hist, comp); 00097 hist.Normalize(); 00098 if(hist.TotalWeight() == 0) { 00099 /* debug code */ 00100 hist.Dump(true); 00101 std::cout << "[WARNING] Opponent color histogram 100% outliers: " << srcCenterX << " " << srcCenterY << std::endl; 00102 WriteRaw(comp, String("outlier.raw"), &Util::Database::GetInstance(), false); 00103 } 00104 delete comp; 00105 for(int i = 0; i < hist.Size(); i++) { 00106 vec.push_back(hist.Elem(i)); 00107 } 00108 } 00109 delete srcOpponent; 00110 } else if(descriptor == "nrghistogram") { 00111 /***** rgb HISTOGRAM (normalized rgb) *****/ 00112 vec.reserve(binCount * 2); 00113 00114 // color conversion 00115 Array2dVec3Real64* src_rg = 0; 00116 RGB2rg(src_rg, src); 00117 00118 double lower[3] = {0, 0, 0}; 00119 double upper[3] = {1, 1, 1}; 00120 00121 if(useCircularMask) { 00122 AddVal(circleMask, circleMask, -1); 00123 MulVal(circleMask, circleMask, 1000); // now it is 0 in the circle and -1000 elsewhere 00124 } 00125 00126 for (int d=1 ; d<=2 ; d++) 00127 { 00128 Array2dScalarReal64* comp = 0; 00129 ProjectRange(comp, src_rg, d); 00130 00131 if(useCircularMask) { 00132 /* add them together, making values outside the circle very negative (i.e. an outlier) */ 00133 Add(comp, comp, circleMask); 00134 //WriteRaw(comp, String("x.raw"), false); 00135 } 00136 00137 Histogram1dTem<Real64> hist(lower[d-1], upper[d-1], binCount, 0); 00138 MakeHistogram1d(&hist, comp); 00139 hist.Normalize(); 00140 //hist.Dump(true); 00141 //std::cout << comp->CW() << std::endl; 00142 delete comp; 00143 for(int i = 0; i < hist.Size(); i++) { 00144 vec.push_back(hist.Elem(i)); 00145 } 00146 } 00147 delete src_rg; 00148 } else if(descriptor == "rgbhistogram") { 00149 /***** RGB HISTOGRAM *****/ 00150 vec.reserve(binCount * 3); 00151 00152 double lower[3] = {0, 0, 0}; 00153 double upper[3] = {256, 256, 256}; 00154 00155 if(useCircularMask) { 00156 AddVal(circleMask, circleMask, -1); 00157 MulVal(circleMask, circleMask, 1000); // now it is 0 in the circle and -1000 elsewhere 00158 } 00159 00160 for (int d=1 ; d<=src->ElemSize() ; d++) 00161 { 00162 Array2dScalarReal64* comp = 0; 00163 ProjectRange(comp, src, d); 00164 00165 if(useCircularMask) { 00166 /* add them together, making values outside the circle very negative (i.e. an outlier) */ 00167 Add(comp, comp, circleMask); 00168 //WriteRaw(comp, String("x.raw"), false); 00169 } 00170 00171 Histogram1dTem<Real64> hist(lower[d-1], upper[d-1], binCount, 0); 00172 MakeHistogram1d(&hist, comp); 00173 hist.Normalize(); 00174 //hist.Dump(true); 00175 //std::cout << comp->CW() << std::endl; 00176 delete comp; 00177 for(int i = 0; i < hist.Size(); i++) { 00178 vec.push_back(hist.Elem(i)); 00179 } 00180 } 00181 } else if(descriptor == "transformedcolorhistogram") { 00182 /***** TRANSFORMED RGB HISTOGRAM *****/ 00183 vec.reserve(binCount * 3); 00184 00185 double lower[3] = {-2, -2, -2}; 00186 double upper[3] = { 2, 2, 2}; 00187 00188 for (int d=1 ; d<=src->ElemSize() ; d++) 00189 { 00190 Array2dScalarReal64* comp = 0; 00191 ProjectRange(comp, src, d); 00192 00193 Real64 pixelCount = comp->CW() * comp->CH(); 00194 if(useCircularMask) { 00195 /* make values outside the circle zero */ 00196 Mul(comp, comp, circleMask); 00197 pixelCount = PixSum(circleMask); 00198 } 00199 00200 Real64 mu = PixSum(comp) / pixelCount; 00201 AddVal(comp, comp, -mu); 00202 if(useCircularMask) { 00203 /* make values outside the circle zero */ 00204 Mul(comp, comp, circleMask); 00205 } 00206 //std::cout << "0-mean: " << mu << " " << PixSum(comp) << " " << PixSum(comp) / pixelCount << std::endl; 00207 00208 Array2dScalarReal64* stddev = 0; 00209 Mul(stddev, comp, comp); // square it -> (x - mu)^2 00210 if(useCircularMask) { 00211 /* make values outside the circle zero */ 00212 Mul(stddev, stddev, circleMask); 00213 } 00214 Real64 standardDeviation = sqrt(PixSum(stddev) / pixelCount); 00215 MulVal(comp, comp, 1.0 / standardDeviation); 00216 //std::cout << PixSum(comp) / pixelCount << std::endl; 00217 00218 Histogram1dTem<Real64> hist(lower[d-1], upper[d-1], binCount, 0); 00219 MakeHistogram1d(&hist, comp); 00220 hist.Normalize(); 00221 //hist.Dump(true); 00222 delete comp; 00223 delete stddev; 00224 for(int i = 0; i < hist.Size(); i++) { 00225 vec.push_back(hist.Elem(i)); 00226 } 00227 } 00228 // } else if(descriptor == "nu-colormoments") { 00229 // /***** non-uniform COLOR MOMENTS *****/ 00230 // ColorMoments cm; 00231 // cm.GetMoments(vec, src, 0, 2, useCircularMask, circleMask, false); 00232 // } else if(descriptor == "nu-spatialcolormoments") { 00233 // /***** non-uniform SPATIAL COLOR MOMENTS *****/ 00234 // ColorMoments cm; 00235 // cm.GetMoments(vec, src, 1, 2, useCircularMask, circleMask, false); 00236 // } else if(descriptor == "nupv-colormoments") { 00237 // /***** non-uniform position-variant COLOR MOMENTS *****/ 00238 // ColorMoments cm; 00239 // cm.SetCoordinateShift(srcCenterX, srcCenterY); 00240 // cm.GetMoments(vec, src, 0, 2, useCircularMask, circleMask, false); 00241 // } else if(descriptor == "nupv-spatialcolormoments") { 00242 // /***** non-uniform position-variant SPATIAL COLOR MOMENTS *****/ 00243 // ColorMoments cm; 00244 // cm.SetCoordinateShift(srcCenterX, srcCenterY); 00245 // cm.GetMoments(vec, src, 1, 2, useCircularMask, circleMask, false); 00246 // } else if(descriptor == "colormoments") { 00247 // /***** COLOR MOMENTS *****/ 00248 // Array2dVec3UInt8* uniformSrc = 0; 00249 // Resample(uniformSrc, src, uniformPatchSize, uniformPatchSize); 00250 // if(useCircularMask) delete circleMask; 00251 // circleMask = CreateCircleMask(uniformSrc->CW()); 00252 // 00253 // ColorMoments cm; 00254 // cm.GetMoments(vec, uniformSrc, 0, 2, useCircularMask, circleMask, false); 00255 // delete uniformSrc; 00256 } else if(descriptor == "colormoments") { 00257 /***** SPATIAL COLOR MOMENTS *****/ 00258 Array2dVec3UInt8* uniformSrc = 0; 00259 Resample(uniformSrc, src, uniformPatchSize, uniformPatchSize); 00260 if(useCircularMask) delete circleMask; 00261 circleMask = CreateCircleMask(uniformSrc->CW()); 00262 00263 ColorMoments cm; 00264 cm.GetMoments(vec, uniformSrc, 1, 2, useCircularMask, circleMask, false); 00265 delete uniformSrc; 00266 // } else if(descriptor == "spatialcolormoments3") { 00267 // /***** SPATIAL COLOR MOMENTS up to degree 3 *****/ 00268 // Array2dVec3UInt8* uniformSrc = 0; 00269 // Resample(uniformSrc, src, uniformPatchSize, uniformPatchSize); 00270 // if(useCircularMask) delete circleMask; 00271 // circleMask = CreateCircleMask(uniformSrc->CW()); 00272 // 00273 // ColorMoments cm; 00274 // cm.GetMoments(vec, uniformSrc, 1, 3, useCircularMask, circleMask, false); 00275 // delete uniformSrc; 00276 } else if(descriptor == "colormomentinvariants") { 00277 /***** COLOR MOMENT INVARIANTS *****/ 00278 Array2dVec3UInt8* uniformSrc = 0; 00279 Resample(uniformSrc, src, uniformPatchSize, uniformPatchSize); 00280 if(useCircularMask) delete circleMask; 00281 circleMask = CreateCircleMask(uniformSrc->CW()); 00282 00283 ColorMoments cm; 00284 cm.GetInvariants(vec, uniformSrc, useCircularMask, circleMask, false); 00285 delete uniformSrc; 00286 } else if(descriptor == "huehistogram") { 00287 /***** HUE DESCRIPTOR *****/ 00288 /* by Joost van de Weijer, ECCV2006. Not included: Gaussian weighting mask */ 00289 00290 // default to the setting used by the paper 00291 if(binCount == 15) binCount = 37; 00292 00293 //H=atan2((patches_R+patches_G-2*patches_B),sqrt(3)*(patches_R-patches_G))+pi; 00294 Array2dScalarReal64* H = 0; 00295 00296 Array2dScalarReal64* R = 0; 00297 Array2dScalarReal64* G = 0; 00298 Array2dScalarReal64* B = 0; 00299 ProjectRange(R, src, 1); 00300 ProjectRange(G, src, 2); 00301 ProjectRange(B, src, 3); 00302 00303 Array2dScalarReal64* X = 0; 00304 Add(X, R, G); 00305 MulVal(B, B, -1); 00306 Add(X, X, B); 00307 Add(X, X, B); 00308 Array2dScalarReal64* Y = 0; 00309 MulVal(G, G, -1); 00310 Add(Y, R, G); 00311 MulVal(Y, Y, sqrt(3.0)); 00312 Atan2(H, X, Y); 00313 Real64 myPI = 3.1415927; 00314 AddVal(H, H, myPI); 00315 delete X; X = 0; 00316 delete Y; Y = 0; 00317 00318 /* reset to correct values */ 00319 ProjectRange(R, src, 1); 00320 ProjectRange(G, src, 2); 00321 ProjectRange(B, src, 3); 00322 00323 //saturation=sqrt(2/3*(patches_R.^2+patches_G.^2+patches_B.^2-patches_R.*(patches_G+patches_B)-patches_G.*patches_B)+0.01); 00324 Array2dScalarReal64* Saturation = 0; 00325 // patches_R.^2+patches_G.^2+patches_B.^2 00326 Array2dScalarReal64* R2 = 0; 00327 Array2dScalarReal64* G2 = 0; 00328 Array2dScalarReal64* B2 = 0; 00329 Mul(R2, R, R); 00330 Mul(G2, G, G); 00331 Mul(B2, B, B); 00332 Add(X, R2, G2); 00333 Add(X, X, B2); 00334 delete R2; delete G2; delete B2; 00335 00336 // previous-patches_R.*(patches_G+patches_B) 00337 Add(Y, G, B); 00338 Mul(Y, R, Y); 00339 MulVal(Y, Y, -1); 00340 Add(X, X, Y); 00341 00342 // -patches_G.*patches_B 00343 Mul(Y, G, B); 00344 MulVal(Y, Y, -1); 00345 Add(X, X, Y); 00346 00347 MulVal(X, X, 2.0 / 3.0); 00348 AddVal(X, X, 0.01); 00349 Sqrt(Saturation, X); 00350 00351 delete R; delete G; delete B; delete X; delete Y; 00352 00353 Histogram1dTem<Real64> hist(0, 2 * myPI, binCount, 0); 00354 if(useCircularMask) { 00355 Mul(Saturation, Saturation, circleMask); // everything not in the mask will not be included 00356 } 00357 MakeHistogram1d(&hist, H, Saturation); 00358 hist.Normalize(); 00359 //hist.Dump(true); 00360 for(int i = 0; i < hist.Size(); i++) { 00361 vec.push_back(hist.Elem(i)); 00362 } 00363 delete H; delete Saturation; 00364 00365 } else { 00366 std::cerr << "[ERROR] Invalid descriptor name: " << descriptor << std::endl; 00367 throw "Invalid descriptor name"; 00368 } 00369 if(circleMask) delete circleMask; 00370 }
Here is the call graph for this function:
|