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;
00065 int q;
00066
00067 int a;
00068 int b;
00069 int c;
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")
00089 return ColorMoment::GetMoment(p,q,degree1,degree2,0);
00090 if(band=="RB")
00091 return ColorMoment::GetMoment(p,q,degree1,0,degree2);
00092 if(band=="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
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
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
00273
00274
00275
00276
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
00321 }
00322
00323 }
00324 }
00325 }
00326
00327 #endif