Home || Architecture || Video Search || Visual Search || Scripts || Applications || 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 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:


Generated on Fri Mar 19 11:08:32 2010 for ImpalaSrc by  doxygen 1.5.1