Home || Visual Search || Applications || Architecture || Important Messages || OGL || Src

void Impala::Core::Feature::ComputeRegionDescriptor ( std::vector< Real64 > &  vec,
Array::Array2dVec3UInt8 *  src,
String  descriptor,
bool  useCircularMask,
int  srcCenterX,
int  srcCenterY 
)

Definition at line 43 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::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::Persistency::RepositoryGetFile(), Impala::Core::Array::Resample(), Impala::Core::Array::Rgb2Ooo(), Impala::Core::Array::RGB2rg(), Impala::Core::Array::Sqrt(), and Impala::Core::Array::WriteRaw().

Referenced by CalculateRegionDescriptors().

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

Here is the call graph for this function:


Generated on Thu Jan 13 09:19:04 2011 for ImpalaSrc by  doxygen 1.5.1