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

ColorMoments.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Array_ColorMoments_h
00002 #define Impala_Core_Array_ColorMoments_h
00003 
00004 #include <vector>
00005 #include "Core/Array/Arrays.h"
00006 #include "Core/Array/ArraySet.h"
00007 #include "Core/Array/Rgb2Ooo.h"
00008 #include "Core/Array/Set.h"
00009 #include "Core/Array/PixSum.h"
00010 #include "Core/Array/Add.h"
00011 #include "Core/Array/Sub.h"
00012 #include "Core/Array/Div.h"
00013 #include "Core/Array/Mul.h"
00014 #include "Core/Array/Norm2.h"
00015 #include "Core/Array/Threshold.h"
00016 #include "Core/Array/RecGabor.h"
00017 #include "Core/Array/RecGauss.h"
00018 #include "Core/Array/PixStat.h"
00019 #include "Core/Array/WritePng.h"
00020 #include "Core/Array/PrintData.h"
00021 #include "Core/Array/ProjectRange.h"
00022 
00023 namespace Impala
00024 {
00025 namespace Core
00026 {
00027 namespace Array
00028 {
00029 class ColorMoment {
00030 public:
00031 
00032     ColorMoment(int x,int y,int r, int g,int b, Real64 val,ColorMoment* n=NULL):
00033     p(x),q(y),a(r),b(g),c(b),value(val),next(n)
00034     {
00035     }
00036 
00037     static Real64 GetMoment(int p,int q,int a, int b, int c)
00038     {
00039         ColorMoment* out=first;
00040         while(out!=NULL){
00041             if ((out->p == p)&&
00042                 (out->q == q)&&
00043                 (out->a == a)&&
00044                 (out->b == b)&&
00045                 (out->c == c))
00046                 break;
00047             else
00048                 out=out->next;
00049         }   
00050         if(out!=NULL)
00051             return out->value;
00052         else
00053             return 0;
00054     }
00055     static void Clean(){
00056         ColorMoment* out=first;
00057         while(out!=NULL){
00058             ColorMoment* n=out->next;
00059             delete out;
00060             out=n;
00061         }
00062         first=NULL;
00063     }
00064     int p;  //power of x |
00065     int q;  //power of y |=>these two give the order of the Moment
00066 
00067     int a;  //power of R |
00068     int b;  //power of G |
00069     int c;  //power of B |=>these 3 give the degree of the Moment
00070 
00071     Real64 value;
00072     ColorMoment* next;
00073     static ColorMoment* first;
00074 };
00075 ColorMoment* ColorMoment::first=NULL;
00076 
00077 inline Real64 SB(int p, int q, char band,int degree){
00078     if(band=='R')
00079         return ColorMoment::GetMoment(p,q,degree,0,0);
00080     if(band=='G')
00081         return ColorMoment::GetMoment(p,q,0,degree,0);
00082     if(band=='B')
00083         return ColorMoment::GetMoment(p,q,0,0,degree);
00084     return 0;
00085 }
00086 
00087 inline Real64 DB(int p, int q, std::string band,int degree1,int degree2){
00088     if(band=="RG")//RG
00089         return ColorMoment::GetMoment(p,q,degree1,degree2,0);
00090     if(band=="RB")//RB
00091         return ColorMoment::GetMoment(p,q,degree1,0,degree2);
00092     if(band=="GB")//GB
00093         return ColorMoment::GetMoment(p,q,0,degree1,degree2);
00094     return 0;
00095 }
00096 
00097 Real64 B02(char band){
00098     return (SB(0 ,0,band,0)*SB(0,0,band,2))/(SB(0,0,band,1)*SB(0,0,band,1));
00099 }
00100 
00101 Real64 B12(char band){
00102     Real64 res = 
00103     SB(1 ,0,band,1)*SB(0,1,band,2)*SB(0,0,band,0)+
00104     SB(1 ,0,band,2)*SB(0,1,band,0)*SB(0,0,band,1)+
00105     SB(1,0,band,0)*SB(0,1,band,1)*SB(0,0,band,2)-
00106     SB(1,0,band,0)*SB(0,1,band,2)*SB(0,0,band,1)-
00107     SB(1,0,band,1)*SB(0,1,band,0)*SB(0,0,band,2)-
00108     SB(1,0,band,2)*SB(0,1,band,1)*SB(0,0,band,0);
00109 
00110     res/=(SB(0,0,band,2)*SB(0,0,band,1)*SB(0,0,band,0));
00111     return res;
00112 }
00113 
00114 Real64 C02(std::string band){
00115     return (DB(0,0,band,1,1)*DB(0,0,band,0,0))/(DB(0,0,band,0,1)*DB(0,0,band,1,0));
00116 }
00117 
00118 Real64 C02tilde(std::string band){
00119     return (DB(0,0,band,2,0)*DB(0,0,band,0,2))/(DB(0,0,band,1,1)*DB(0,0,band,1,1));
00120 }
00121 
00122 Real64 C11(std::string band){
00123     return((DB(1,0,band,1,0)*DB(0,1,band,0,1)*DB(0,0,band,0,0) +
00124             DB(1,0,band,0,1)*DB(0,1,band,0,0)*DB(0,0,band,1,0) +
00125             DB(1,0,band,0,0)*DB(0,1,band,1,0)*DB(0,0,band,0,1) - 
00126             DB(1,0,band,0,0)*DB(0,1,band,0,1)*DB(0,0,band,1,0) - 
00127             DB(1,0,band,1,0)*DB(0,1,band,0,0)*DB(0,0,band,0,1) -
00128             DB(1,0,band,0,1)*DB(0,1,band,1,0)*DB(0,0,band,0,0) )/
00129            (DB(0,0,band,1,0)*DB(0,0,band,0,1)*DB(0,0,band,0,0)));
00130 }
00131 Real64 C12_1(std::string band){
00132     return((DB(1,0,band,1,0)*DB(0,1,band,1,1)*DB(0,0,band,0,0) +
00133             DB(1,0,band,1,1)*DB(0,1,band,0,0)*DB(0,0,band,1,0) +
00134             DB(1,0,band,0,0)*DB(0,1,band,1,0)*DB(0,0,band,1,1) - 
00135             DB(1,0,band,0,0)*DB(0,1,band,1,1)*DB(0,0,band,1,0) - 
00136             DB(1,0,band,1,0)*DB(0,1,band,0,0)*DB(0,0,band,1,1) -
00137             DB(1,0,band,1,1)*DB(0,1,band,1,0)*DB(0,0,band,0,0) )/
00138            (DB(0,0,band,1,1)*DB(0,0,band,1,0)*DB(0,0,band,0,0)));
00139 
00140 }
00141 Real64 C12_2(std::string band){
00142     return((DB(1,0,band,0,1)*DB(0,1,band,1,1)*DB(0,0,band,0,0) +
00143             DB(1,0,band,1,1)*DB(0,1,band,0,0)*DB(0,0,band,0,1) +
00144             DB(1,0,band,0,0)*DB(0,1,band,0,1)*DB(0,0,band,1,1) - 
00145             DB(1,0,band,0,0)*DB(0,1,band,1,1)*DB(0,0,band,0,1) - 
00146             DB(1,0,band,0,1)*DB(0,1,band,0,0)*DB(0,0,band,1,1) -
00147             DB(1,0,band,1,1)*DB(0,1,band,0,1)*DB(0,0,band,0,0) )/
00148            (DB(0,0,band,1,1)*DB(0,0,band,0,1)*DB(0,0,band,0,0)));
00149 }
00150 Real64 C12_3(std::string band){
00151     return((DB(1,0,band,1,0)*DB(0,1,band,0,2)*DB(0,0,band,0,0) +
00152             DB(1,0,band,0,2)*DB(0,1,band,0,0)*DB(0,0,band,1,0) +
00153             DB(1,0,band,0,0)*DB(0,1,band,1,0)*DB(0,0,band,0,2) - 
00154             DB(1,0,band,0,0)*DB(0,1,band,0,2)*DB(0,0,band,1,0) - 
00155             DB(1,0,band,1,0)*DB(0,1,band,0,0)*DB(0,0,band,0,2) -
00156             DB(1,0,band,0,2)*DB(0,1,band,1,0)*DB(0,0,band,0,0) )/
00157            (DB(0,0,band,1,0)*DB(0,0,band,0,2)*DB(0,0,band,0,0)));
00158 }
00159 
00160 Real64 C12_4(std::string band){
00161     return((DB(1,0,band,2,0)*DB(0,1,band,0,1)*DB(0,0,band,0,0) +
00162             DB(1,0,band,0,1)*DB(0,1,band,0,0)*DB(0,0,band,2,0) +
00163             DB(1,0,band,0,0)*DB(0,1,band,2,0)*DB(0,0,band,0,1) - 
00164             DB(1,0,band,0,0)*DB(0,1,band,0,1)*DB(0,0,band,2,0) - 
00165             DB(1,0,band,2,0)*DB(0,1,band,0,0)*DB(0,0,band,0,1) -
00166             DB(1,0,band,0,1)*DB(0,1,band,2,0)*DB(0,0,band,0,0) )/
00167            (DB(0,0,band,2,0)*DB(0,0,band,0,1)*DB(0,0,band,0,0)));
00168 }
00169 
00170 
00171 inline void
00172 ColorMoments(Array2dScalarReal64*& CMInvariants,Array2dVec3UInt8* rgb,
00173             int order,int degree,bool blur=true,double sigma=10.0)
00174 {
00175 
00176     Real64 TotalPixels=rgb->W()*rgb->H();
00177     ArraySet<Array2dScalarReal64>* X=new ArraySet<Array2dScalarReal64>(order+1);
00178     ArraySet<Array2dScalarReal64>* Y=new ArraySet<Array2dScalarReal64>(order+1);
00179     
00180     ArraySet<Array2dScalarReal64>* R=new ArraySet<Array2dScalarReal64>(degree+1);
00181     ArraySet<Array2dScalarReal64>* G=new ArraySet<Array2dScalarReal64>(degree+1);
00182     ArraySet<Array2dScalarReal64>* B=new ArraySet<Array2dScalarReal64>(degree+1);
00183     
00184     X->Array(0)=new Array2dScalarReal64(rgb->W(),rgb->H(),0,0);
00185     Y->Array(0)=new Array2dScalarReal64(rgb->W(),rgb->H(),0,0);
00186     R->Array(0)=new Array2dScalarReal64(rgb->W(),rgb->H(),0,0);
00187     G->Array(0)=new Array2dScalarReal64(rgb->W(),rgb->H(),0,0);
00188     B->Array(0)=new Array2dScalarReal64(rgb->W(),rgb->H(),0,0);
00189 
00190     //Oth order/degree values are all 1;
00191     SetVal(X->Array(0),1);
00192     SetVal(Y->Array(0),1);
00193     SetVal(R->Array(0),1);
00194     SetVal(G->Array(0),1);
00195     SetVal(B->Array(0),1);
00196 
00197     //1st order/degree values are same with corresponding vectors
00198     X->Array(1)=new Array2dScalarReal64(rgb->W(),rgb->H(),0,0);
00199     Y->Array(1)=new Array2dScalarReal64(rgb->W(),rgb->H(),0,0);
00200     for(int i=0;i<rgb->W();i++){
00201         for(int j=0;j<rgb->H();j++){
00202             X->Array(1)->SetValue(i,i,j);
00203             Y->Array(1)->SetValue(j,i,j);
00204         }
00205     }
00206     ProjectRange(R->Array(1),rgb,1);
00207     ProjectRange(G->Array(1),rgb,2);
00208     ProjectRange(B->Array(1),rgb,3);
00209     
00210     if(blur){
00211         Array2dScalarReal64* tmp=0;
00212         RecGauss(tmp,R->Array(1),sigma,sigma,0,0,1);
00213         Set(R->Array(1),tmp);
00214         delete tmp;tmp=0;
00215         RecGauss(tmp,G->Array(1),sigma,sigma,0,0,1);
00216         Set(G->Array(1),tmp);
00217         delete tmp;tmp=0;
00218         RecGauss(tmp,B->Array(1),sigma,sigma,0,0,1);
00219         Set(B->Array(1),tmp);
00220         delete tmp;tmp=0;
00221     }
00222 
00223     for(int o=2;o<=order;o++){
00224         Mul(X->Array(o),X->Array(o-1),X->Array(1));
00225         Mul(Y->Array(o),Y->Array(o-1),Y->Array(1));
00226     }
00227     for(int d=2;d<=degree;d++){
00228         Mul(R->Array(d),R->Array(d-1),R->Array(1));
00229         Mul(G->Array(d),G->Array(d-1),G->Array(1));
00230         Mul(B->Array(d),B->Array(d-1),B->Array(1));
00231     }
00232     ColorMoment* last=0;
00233     for(int o=0;o<=order;o++){
00234         for (int p=0;p<=o;p++){
00235             for (int q=0;q<=o;q++){
00236                 if( p+q == o)
00237                     for(int d=0;d<=degree;d++){
00238                         for(int r=0;r<=d;r++){
00239                             for(int g=0;g<=d;g++){
00240                                 for(int b=0;b<=d;b++){
00241                                     if(r+g+b==d){
00242                                         Array2dScalarReal64* m = 0;
00243                                         Set(m,R->Array(r));
00244                                         if(g!=0)
00245                                             Mul(m,m,G->Array(g));
00246                                         if(b!=0)
00247                                             Mul(m,m,B->Array(b));
00248                                         if(p!=0)
00249                                             Mul(m,m,X->Array(p));
00250                                         if(q!=0)
00251                                             Mul(m,m,Y->Array(q));
00252                                         Real64 Moment=PixSum(m)/TotalPixels;
00253                                         delete m;
00254                                         ColorMoment* cm = new ColorMoment(p,q,r,g,b,Moment,NULL);
00255                                         if(ColorMoment::first==NULL)
00256                                             ColorMoment::first=cm;
00257                                         if(last){
00258                                             last->next=cm;
00259                                         }
00260                                         last=cm;
00261                                     }
00262                                 }
00263                             }
00264                         }
00265                     }
00266             }
00267         }
00268     }
00269     ColorMoment* m=ColorMoment::first;
00270 
00271     int count=1;
00272 //    while(m){
00273 //        std::cout<<count++<<". "<<m->p<<" "<<m->q<<" "<<m->a<<" "<<m->b<<" "<<m->c<<" : "<<m->value<<std::endl;
00274 //        m=m->next;
00275 //    }
00276     //moment CMInvariants//
00277     if(CMInvariants==0){
00278         CMInvariants=new Array2dScalarReal64(24,1,0,0);
00279     }
00280 
00281     int i=0;
00282    CMInvariants->SetValue(B02('R'),i++,0);
00283     CMInvariants->SetValue(B02('G'),i++,0);
00284     CMInvariants->SetValue(B02('B'),i++,0);
00285     CMInvariants->SetValue(C02("RG"),i++,0);
00286     CMInvariants->SetValue(C02("RB"),i++,0);
00287     CMInvariants->SetValue(C02("GB"),i++,0);
00288     CMInvariants->SetValue(C02tilde("RG"),i++,0);
00289     CMInvariants->SetValue(C02tilde("RB"),i++,0);
00290     CMInvariants->SetValue(C02tilde("GB"),i++,0);
00291 
00292     CMInvariants->SetValue(C11("RG"),i++,0);
00293     CMInvariants->SetValue(C11("RB"),i++,0);
00294     CMInvariants->SetValue(C11("GB"),i++,0);
00295     CMInvariants->SetValue(B12('R'),i++,0);
00296     CMInvariants->SetValue(B12('G'),i++,0);
00297     CMInvariants->SetValue(B12('B'),i++,0);
00298     CMInvariants->SetValue(C12_1("RG"),i++,0);
00299     CMInvariants->SetValue(C12_1("RB"),i++,0);
00300     CMInvariants->SetValue(C12_1("GB"),i++,0);
00301     CMInvariants->SetValue(C12_2("RG"),i++,0);
00302     CMInvariants->SetValue(C12_2("RB"),i++,0);
00303     CMInvariants->SetValue(C12_2("GB"),i++,0);
00304     
00305     CMInvariants->SetValue(C12_3("RG"),i++,0);
00306     CMInvariants->SetValue(C12_3("GB"),i++,0);
00307     CMInvariants->SetValue(C12_4("RB"),i++,0);
00308 
00309     ColorMoment::Clean();
00310     for(int o=0;o<=order;o++){
00311         delete X->Array(o);
00312         delete Y->Array(o);
00313     }
00314     for(int d=0;d<=degree;d++){
00315         delete R->Array(d);
00316         delete G->Array(d);
00317         delete B->Array(d);
00318     }
00319     delete X,Y,R,G,B;
00320     //PrintData(CMInvariants,false);
00321 }
00322 
00323 } // namespace Array
00324 } // namespace Core
00325 } // namespace Impala
00326 
00327 #endif

Generated on Fri Mar 19 09:30:44 2010 for ImpalaSrc by  doxygen 1.5.1