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

GetColorChannels.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Feature_GetColorChannels_h
00002 #define Impala_Core_Feature_GetColorChannels_h
00003 
00004 #include "Core/Array/RGB2Intensity.h"
00005 #include "Core/Array/Rgb2Ooo.h"
00006 #include "Core/Array/RGB2rg.h"
00007 #include "Core/Array/ColorSpace.h"
00008 #include "Core/Array/ProjectRange.h"
00009 #include "Core/Array/PixSum.h"
00010 #include "Core/Array/PixMax.h"
00011 #include "Core/Array/Add.h"
00012 #include "Core/Array/Sub.h"
00013 #include "Core/Array/Div.h"
00014 #include "Core/Array/Mul.h"
00015 #include "Core/Array/MulVal.h"
00016 #include "Core/Array/AddVal.h"
00017 #include "Core/Array/Atan2.h"
00018 #include "Core/Array/ProjectParameterizedColor.h"
00019 #include "Core/Array/Element/Color.h"
00020 #include "Util/StringParser.h"
00021 
00022 #include <set>
00023 
00024 namespace Impala
00025 {
00026 namespace Core
00027 {
00028 namespace Feature
00029 {
00030 
00031 void
00032 Normalize(Array::Array2dScalarReal64* im)
00033 {
00034     Real64 maxVal = PixMax(im);
00035     if(abs(maxVal) < 0.000001)
00036         maxVal = 1.0;
00037     MulVal(im, im, 1. / maxVal);
00038 }
00039 
00040 std::vector<Array::Array2dScalarReal64*>
00041 GetColorChannels(Array::Array2dVec3Real64* input, String colorModel)
00042 {
00043     ILOG_FUNCTION(Impala.Core.Feature.GetColorChannels);
00044     ILOG_DEBUG("colorModel="<< colorModel);
00045     std::vector<Array::Array2dScalarReal64*> output;
00046     if((colorModel == "") || (colorModel == "no") ||
00047        (colorModel == "rg") || (colorModel == "hsv"))
00048     {
00049         Array::Array2dScalarReal64* imIntensity = 0;
00050         RGB2Intensity(imIntensity, input);
00051         // scale intensity to the range 0..1 instead of 0..255 so it is
00052         // comparable to Matlab
00053         Normalize(imIntensity);
00054         output.push_back(imIntensity);
00055     }
00056     if(colorModel == "rg")
00057     {
00058         Array::Array2dVec3Real64* rg = 0;
00059         RGB2rg(rg, input);
00060         Array::Array2dScalarReal64* r = 0;
00061         ProjectRange(r, rg, 1);
00062         output.push_back(r);
00063         Array::Array2dScalarReal64* g = 0;
00064         ProjectRange(g, rg, 2);
00065         output.push_back(g);
00066         delete rg;
00067     }
00068     if(colorModel == "opponent")
00069     {
00070         Array::Array2dVec3Real64* ooo = 0;
00071         Rgb2Ooo(ooo, input);
00072 
00073         Array::Array2dScalarReal64* intensity = 0;
00074         ProjectRange(intensity, ooo, 1);
00075         Normalize(intensity);
00076         output.push_back(intensity);
00077 
00078         Array::Array2dScalarReal64* redGreen = 0;
00079         ProjectRange(redGreen, ooo, 2);
00080         MulVal(redGreen, redGreen, 1 / 80.0);
00081         AddVal(redGreen, redGreen, 0.5);
00082         output.push_back(redGreen);
00083 
00084         Array::Array2dScalarReal64* blueYellow = 0;
00085         ProjectRange(blueYellow, ooo, 3);
00086         MulVal(blueYellow, blueYellow, 1 / 80.0);
00087         AddVal(blueYellow, blueYellow, 0.5);
00088         output.push_back(blueYellow);
00089         delete ooo;
00090     }
00091     if((colorModel == "w") || (colorModel == "c"))
00092     {
00093         Array::Array2dVec3Real64* ooo = 0;
00094         Rgb2Ooo(ooo, input);
00095 
00096         Array::Array2dScalarReal64* intensity = 0;
00097         ProjectRange(intensity, ooo, 1);
00098         Real64 maxVal = PixMax(intensity);
00099         if(abs(maxVal) < 0.000001)
00100             maxVal = 1.0;
00101         AddVal(intensity, intensity, 1.0);    // add 1 to prevent division by 0
00102         MulVal(intensity, intensity, 1 / maxVal);
00103         output.push_back(intensity);
00104 
00105         Array::Array2dScalarReal64* redGreen = 0;
00106         ProjectRange(redGreen, ooo, 2);
00107         Div(redGreen, redGreen, intensity);   // divide by intensity
00108         MulVal(redGreen, redGreen, 1 / 900.0);
00109         AddVal(redGreen, redGreen, 0.5);
00110         output.push_back(redGreen);
00111 
00112         Array::Array2dScalarReal64* blueYellow = 0;
00113         ProjectRange(blueYellow, ooo, 3);
00114         Div(blueYellow, blueYellow, intensity);   // divide by intensity
00115         MulVal(blueYellow, blueYellow, 1 / 900.0);
00116         AddVal(blueYellow, blueYellow, 0.5);
00117         output.push_back(blueYellow);
00118         delete ooo;
00119     }
00120     if(colorModel == "hsv")
00121     {
00122         /* Bosch CIVR 2007 */
00123         Array::Array2dVec3Real64* hsv = 0;
00124         ColorSpace(hsv, input, Array::Element::RGB, Array::Element::HSI);
00125 
00126         Array::Array2dScalarReal64* hue = 0;
00127         ProjectRange(hue, hsv, 1);
00128         MulVal(hue, hue, 1 / (2 * 3.14159265));
00129         output.push_back(hue);
00130 
00131         Array::Array2dScalarReal64* saturation = 0;
00132         ProjectRange(saturation, hsv, 2);
00133         output.push_back(saturation);
00134         delete hsv;
00135     }
00136     if(colorModel == "transformedcolor")
00137     {
00138         for (int d=1 ; d<=input->ElemSize() ; d++)
00139         {
00140             Array::Array2dScalarReal64* comp = 0;
00141             ProjectRange(comp, input, d);
00142             Real64 pixelCount = comp->CW() * comp->CH();
00143             Real64 mu = PixSum(comp) / pixelCount;
00144             AddVal(comp, comp, -mu);
00145             Array::Array2dScalarReal64* stddev = 0;
00146             Mul(stddev, comp, comp);    // square it -> (x - mu)^2
00147             Real64 standardDeviation = sqrt(PixSum(stddev) / pixelCount);
00148             delete stddev;
00149             if(standardDeviation < 0.00001)
00150                 standardDeviation = 1.0;
00151             // scale [-2std,2std] to [-0.5,0.5]
00152             MulVal(comp, comp, (1.0 / standardDeviation) / 4.0);
00153             AddVal(comp, comp, 0.5);
00154             output.push_back(comp);
00155         }
00156     }
00157     if(colorModel == "rgb")
00158     {
00159         for(int channel=1 ; channel<=input->ElemSize() ; ++channel)
00160         {
00161             Array::Array2dScalarReal64* a = 0;
00162             ProjectRange(a, input, channel);
00163             output.push_back(a);
00164         }
00165     }
00166     if(colorModel.substr(0, 7) == "tunergb")
00167     {
00168         Array::Array2dVec3Real64* realImage = 0;
00169         MulVal(realImage, input, 1.0);
00170         Util::StringParser sp(colorModel.substr(7, colorModel.size()));
00171         while(!sp.TheEnd())
00172         {
00173             String colorChannel = sp.GetString('+', false);
00174             Util::StringParser sp2(colorChannel);
00175             Real64 a = sp2.GetDouble('x', true, true);
00176             Real64 b = sp2.GetDouble('x', true, true);
00177             Real64 c = sp2.GetDouble('x', true, true);
00178             Real64 d = sp2.GetDouble('x', true, true);
00179             Real64 e = sp2.GetDouble('x', true, true);
00180             Real64 f = sp2.GetDouble('x', true, true);
00181             Real64 g = sp2.GetDouble('x', false);
00182             Array::Array2dScalarReal64* channel = 0;
00183             ProjectParameterizedColor(channel, realImage, a, b, c, d, e, f, g);
00184             output.push_back(channel);
00185         }
00186         delete realImage;
00187     }
00188     if(colorModel.substr(0, 9) == "tunechan-")
00189     {
00190         Util::StringParser sp(colorModel.substr(9, colorModel.size()));
00191         std::set<String> channels;
00192         std::vector<String> orderedChannels;
00193         while(!sp.TheEnd())
00194         {
00195             String colorChannel = sp.GetString('-', false);
00196             channels.insert(colorChannel);
00197             orderedChannels.push_back(colorChannel);
00198         }
00199         if(channels.find("i") != channels.end())
00200         {
00201             // convert to intensity image
00202             Array::Array2dScalarReal64* intensity = 0;
00203             RGB2Intensity(intensity, input);
00204             Normalize(intensity);
00205             output.push_back(intensity);
00206         }
00207         if(channels.find("r") != channels.end())
00208         {
00209             Array::Array2dScalarReal64* r = 0;
00210             ProjectRange(r, input, 1);
00211             output.push_back(r);
00212         }
00213         if(channels.find("g") != channels.end())
00214         {
00215             Array::Array2dScalarReal64* g = 0;
00216             ProjectRange(g, input, 2);
00217             output.push_back(g);
00218         }
00219         if(channels.find("b") != channels.end())
00220         {
00221             Array::Array2dScalarReal64* b = 0;
00222             ProjectRange(b, input, 3);
00223             output.push_back(b);
00224         }
00225         if((channels.find("rg") != channels.end()) ||
00226            (channels.find("rb") != channels.end()) ||
00227            (channels.find("rm") != channels.end()) ||
00228            (channels.find("ry") != channels.end()) ||
00229            (channels.find("gb") != channels.end()) ||
00230            (channels.find("gy") != channels.end()))
00231         {
00232             Array::Array2dScalarReal64* r = 0;
00233             ProjectRange(r, input, 1);
00234             Array::Array2dScalarReal64* g = 0;
00235             ProjectRange(g, input, 2);
00236             Array::Array2dScalarReal64* b = 0;
00237             ProjectRange(b, input, 3);
00238             if(channels.find("rg") != channels.end())
00239             {
00240                 Array::Array2dScalarReal64* rg = 0;
00241                 Sub(rg, r, g);
00242                 output.push_back(rg);
00243             }
00244             if(channels.find("rb") != channels.end())
00245             {
00246                 Array::Array2dScalarReal64* rb = 0;
00247                 Sub(rb, r, b); 
00248                 output.push_back(rb);
00249             }
00250             if(channels.find("gb") != channels.end())
00251             {
00252                 Array::Array2dScalarReal64* gb = 0;
00253                 Sub(gb, g, b); 
00254                 output.push_back(gb);
00255             }
00256             if(channels.find("rm") != channels.end())
00257             {
00258                 Array::Array2dScalarReal64* rm = 0;
00259                 Add(rm, r, g); 
00260                 output.push_back(rm);
00261             }
00262             if(channels.find("ry") != channels.end())
00263             {
00264                 Array::Array2dScalarReal64* ry = 0;
00265                 Add(ry, r, b); 
00266                 output.push_back(ry);
00267             }
00268             if(channels.find("gy") != channels.end())
00269             {
00270                 Array::Array2dScalarReal64* gy = 0;
00271                 Add(gy, g, b); 
00272                 output.push_back(gy);
00273             }
00274             delete r;
00275             delete g;
00276             delete b;
00277         }
00278         if(channels.find("o1") != channels.end() ||
00279            channels.find("o2") != channels.end())
00280         {
00281             Array::Array2dVec3Real64* ooo = 0;
00282             Rgb2Ooo(ooo, input);
00283             if(channels.find("o1") != channels.end())
00284             {
00285                 Array::Array2dScalarReal64* redGreen = 0;
00286                 ProjectRange(redGreen, ooo, 2);
00287                 MulVal(redGreen, redGreen, 1 / 80.0);
00288                 AddVal(redGreen, redGreen, 0.5);
00289                 output.push_back(redGreen);
00290             }
00291             if(channels.find("o2") != channels.end())
00292             {
00293                 Array::Array2dScalarReal64* blueYellow = 0;
00294                 ProjectRange(blueYellow, ooo, 3);
00295                 MulVal(blueYellow, blueYellow, 1 / 80.0);
00296                 AddVal(blueYellow, blueYellow, 0.5);
00297                 output.push_back(blueYellow);
00298             }
00299             delete ooo;
00300         }
00301         if(channels.find("c1") != channels.end() ||
00302            channels.find("c2") != channels.end())
00303         {
00304             Array::Array2dVec3Real64* ooo = 0;
00305             Rgb2Ooo(ooo, input);
00306             /* first channel: intensity (0..270) */
00307             Array::Array2dScalarReal64* intensity = 0;
00308             ProjectRange(intensity, ooo, 1);
00309             Real64 maxVal = PixMax(intensity);
00310             if(abs(maxVal) < 0.000001)
00311                 maxVal = 1.0;
00312             AddVal(intensity, intensity, 1.0);
00313             MulVal(intensity, intensity, 1 / maxVal);
00314             if(channels.find("c1") != channels.end())
00315             {
00316                 Array::Array2dScalarReal64* redGreen = 0;
00317                 ProjectRange(redGreen, ooo, 2);
00318                 Div(redGreen, redGreen, intensity);   // divide by intensity
00319                 MulVal(redGreen, redGreen, 1 / 900.0);
00320                 AddVal(redGreen, redGreen, 0.5);
00321                 output.push_back(redGreen);
00322             }
00323             if(channels.find("c2") != channels.end())
00324             {
00325                 Array::Array2dScalarReal64* blueYellow = 0;
00326                 ProjectRange(blueYellow, ooo, 3);
00327                 Div(blueYellow, blueYellow, intensity); // divide by intensity
00328                 MulVal(blueYellow, blueYellow, 1 / 900.0);
00329                 AddVal(blueYellow, blueYellow, 0.5);
00330                 output.push_back(blueYellow);
00331             }
00332             delete intensity;
00333             delete ooo;
00334         }
00335         
00336         if(channels.find("nr") != channels.end() ||
00337            channels.find("ng") != channels.end() ||
00338            channels.find("nb") != channels.end())
00339         {
00340             Array::Array2dVec3Real64* rg = 0;
00341             RGB2rg(rg, input);
00342             if(channels.find("nr") != channels.end())
00343             {
00344                 Array::Array2dScalarReal64* r = 0;
00345                 ProjectRange(r, rg, 1);
00346                 output.push_back(r);
00347             }
00348             if(channels.find("ng") != channels.end())
00349             {
00350                 Array::Array2dScalarReal64* g = 0;
00351                 ProjectRange(g, rg, 2);
00352                 output.push_back(g);
00353             }
00354             if(channels.find("nb") != channels.end())
00355             {
00356                 Array::Array2dScalarReal64* b = 0;
00357                 ProjectRange(b, rg, 3);
00358                 output.push_back(b);
00359             }
00360             delete rg;
00361         }
00362 
00363         if(channels.find("p1") != channels.end())
00364         {
00365             // polar coordinates arctan(R/G)
00366             Array::Array2dScalarReal64* r = 0;
00367             ProjectRange(r, input, 1);
00368             Array::Array2dScalarReal64* g = 0;
00369             ProjectRange(g, input, 2);
00370             Array::Array2dScalarReal64* ratio = 0;
00371             Atan2(ratio, r, g);
00372             output.push_back(ratio);
00373             delete r;
00374             delete g;
00375         }
00376         if(channels.find("p2") != channels.end())
00377         {
00378             // polar coordinates arctan(R/B)
00379             Array::Array2dScalarReal64* r = 0;
00380             ProjectRange(r, input, 1);
00381             Array::Array2dScalarReal64* b = 0;
00382             ProjectRange(b, input, 3);
00383             Array::Array2dScalarReal64* ratio = 0;
00384             Atan2(ratio, r, b);
00385             output.push_back(ratio);
00386             delete r;
00387             delete b;
00388         }
00389         if(channels.find("p3") != channels.end())
00390         {
00391             // polar coordinates arctan(G/B)
00392             Array::Array2dScalarReal64* g = 0;
00393             ProjectRange(g, input, 2);
00394             Array::Array2dScalarReal64* b = 0;
00395             ProjectRange(b, input, 3);
00396             Array::Array2dScalarReal64* ratio = 0;
00397             Atan2(ratio, g, b);
00398             output.push_back(ratio);
00399             delete g;
00400             delete b;
00401         }
00402         for(std::vector<String>::iterator iter = orderedChannels.begin(); 
00403             iter != orderedChannels.end(); iter++)
00404         {
00405             String chan = *iter;
00406             if(StringStartsWith(chan,"seed"))
00407             {
00408                 // we have a seed :)
00409                 Util::StringParser sp2(chan.substr(4,chan.size()));
00410                 String A = sp2.GetString(',', true);
00411                 String B = sp2.GetString(',', true);
00412                 String C = sp2.GetString(',', false);
00413                 Real64 a = 0;
00414                 Real64 b = 0;
00415                 Real64 c = 0;
00416                 if(A[0] == 'm')
00417                     a = -atof(A.substr(1,A.size()));
00418                 else
00419                     a = atof(A);
00420 
00421                 if(B[0] == 'm')
00422                     b = -atof(B.substr(1,B.size()));
00423                 else
00424                     b = atof(B);
00425 
00426                 if(C[0] == 'm')
00427                     c = -atof(C.substr(1,C.size()));
00428                 else
00429                     c = atof(C);
00430                     
00431                 ILOG_DEBUG("Seed a " << a << " b " << b << " c " << c);
00432                 Array::Array2dScalarReal64* channel = 0;
00433                 ProjectParameterizedColor(channel, input, a, b, c, 0, 0, 0, 1);
00434                 output.push_back(channel);
00435             }
00436         }
00437     }
00438     return output;
00439 }
00440 
00441 std::vector<Array::Array2dScalarReal64*>
00442 GetColorChannels(Array::Array2dVec3UInt8* inputInt, String colorModel)
00443 {
00444     Array::Array2dVec3Real64* input = 0;
00445     MulVal(input, inputInt, 1.0);
00446     std::vector<Array::Array2dScalarReal64*> output = 
00447                                   GetColorChannels(input, colorModel);
00448     delete input;
00449     return output;
00450 }
00451 
00452 } // namespace Koen
00453 } // namespace Sandbox
00454 } // namespace Impala
00455 
00456 #endif

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