ColorSegmenter.C

00001 
00002 
00003 #include "BeoSub/ColorSegmenter.H"
00004 
00005 
00006 ColorSegmenter::ColorSegmenter(){
00007 
00008 
00009    debugmode = false;
00010   setup = false;
00011   color.resize(4,0.0F);
00012   std.resize(4,0.0F);
00013   norm.resize(4,0.0F);
00014   adapt.resize(4,0.0F);
00015   lowerBound.resize(4,0.0F);
00016   upperBound.resize(4,0.0F);
00017   candidate_color = "none";
00018   Hz = 0.0F;
00019   fps = 0.0F;
00020   res = 0.0F;
00021 
00022   int wi = 320/4;
00023   int hi = 240/4;
00024 
00025 
00026   width = 320;
00027   height = 240;
00028   segmenter = new segmentImageTrackMC<float,unsigned int, 4> (width*height);
00029 
00030   segmenter->SITsetFrame(&wi,&hi);
00031 
00032   segmenter->SITsetCircleColor(0,255,0);
00033   segmenter->SITsetBoxColor(255,255,0,0,255,255);
00034   segmenter->SITsetUseSmoothing(false,10);
00035 
00036 
00037   segmenter->SITtoggleCandidateBandPass(false);
00038   segmenter->SITtoggleColorAdaptation(false);
00039 }
00040 
00041 ColorSegmenter::~ColorSegmenter(){
00042 }
00043 
00044 
00045 void ColorSegmenter::setupColorSegmenter(const char* inputColor, bool debug){
00046  debugmode = debug;
00047  //for now just allow it orange
00048  //candidate_color = inputColor;
00049  //inputColor = "Orange";
00050  // canidate_color = inputColor;
00051 
00052  //if(!strcmp(candidate_color, "Orange")){
00053     setupOrange();
00054     // }
00055     // else{
00056     // printf("Cannot setup decoder without a color to decode! exiting...\n");
00057     // return;
00058     // }
00059 
00060   segmenter->SITsetTrackColor(&color,&std,&norm,&adapt,&upperBound,&lowerBound);
00061 
00062   //if(debugmode){
00063     wini.reset(new XWindow(Dims(width, height), 0, 0, "test-input window"));
00064     wini->setPosition(0, 0);
00065     wino.reset(new XWindow(Dims(width, height), 0, 0, "test-output window"));
00066     wino->setPosition(width+10, 0);
00067     //}
00068 
00069 
00070   setup = true;
00071 }
00072 
00073 void ColorSegmenter::setupOrange() {
00074 
00075   colorConf.openFile("colortrack.conf", true);
00076 
00077   PixRGB<float> P1(colorConf.getItemValueF("ORANGE_R"),
00078                    colorConf.getItemValueF("ORANGE_G"),
00079                    colorConf.getItemValueF("ORANGE_B"));
00080 
00081   PixH2SV1<float> ORANGE(P1);
00082 
00083   color[0] = ORANGE.H1(); color[1] = ORANGE.H2(); color[2] = ORANGE.S(); color[3] = ORANGE.V();
00084 
00085   //! +/- tollerance value on mean for track
00086   std[0] = colorConf.getItemValueF("ORNG_std0");
00087   std[1] = colorConf.getItemValueF("ORNG_std1");
00088   std[2] = colorConf.getItemValueF("ORNG_std2");
00089   std[3] = colorConf.getItemValueF("ORNG_std3");
00090 
00091   //! normalizer over color values (highest value possible)
00092   norm[0] = colorConf.getItemValueF("ORNG_norm0");
00093   norm[1] = colorConf.getItemValueF("ORNG_norm1");
00094   norm[2] = colorConf.getItemValueF("ORNG_norm2");
00095   norm[3] = colorConf.getItemValueF("ORNG_norm3");
00096 
00097   //! how many standard deviations out to adapt, higher means less bias
00098   adapt[0] = colorConf.getItemValueF("ORNG_adapt0");
00099   adapt[1] = colorConf.getItemValueF("ORNG_adapt1");
00100   adapt[2] = colorConf.getItemValueF("ORNG_adapt2");
00101   adapt[3] = colorConf.getItemValueF("ORNG_adapt3");
00102 
00103   //! highest value for color adaptation possible (hard boundry)
00104   upperBound[0] = color[0] + colorConf.getItemValueF("ORNG_up0");
00105   upperBound[1] = color[1] + colorConf.getItemValueF("ORNG_up1");
00106   upperBound[2] = color[2] + colorConf.getItemValueF("ORNG_up2");
00107   upperBound[3] = color[3] + colorConf.getItemValueF("ORNG_up3");
00108 
00109   //! lowest value for color adaptation possible (hard boundry)
00110   lowerBound[0] = color[0] - colorConf.getItemValueF("ORNG_lb0");
00111   lowerBound[1] = color[1] - colorConf.getItemValueF("ORNG_lb1");
00112   lowerBound[2] = color[2] - colorConf.getItemValueF("ORNG_lb2");
00113   lowerBound[3] = color[3] - colorConf.getItemValueF("ORNG_lb3");
00114 }
00115 
00116     /*
00117 //true test with frame 3498
00118 float ColorSegmenter::oldisolateOrange(Image< PixRGB<byte> > &inputImage,  Image<byte> &outputImage)
00119 {
00120 
00121   readConfig colorConf;
00122   colorConf.openFile("colortrack.conf", false);
00123 
00124   int orangeCount = 0;
00125 
00126   Image<PixRGB<byte> >::iterator iptr = inputImage.beginw();
00127   Image<byte>::iterator          optr = outputImage.beginw();
00128   Image<PixRGB<byte> >::iterator stop = inputImage.endw();
00129 
00130   float tR = colorConf.getItemValueF("ORANGE_stdR");//70.0;
00131   float tG = colorConf.getItemValueF("ORANGE_stdG");//200.0;
00132   float tB = colorConf.getItemValueF("ORANGE_stdB");//128.0;
00133 
00134   float R = colorConf.getItemValueF("ORANGE_R");//255;
00135   float G = colorConf.getItemValueF("ORANGE_G");//198;
00136   float B = colorConf.getItemValueF("ORANGE_B");//0;
00137 
00138 
00139         //for average
00140         float totalHue = 0.0;
00141         int numTotal = 0;
00142 
00143         //orange as a hue
00144         float pure_orange_hue =  60*(((G/255)-(B/255))/((R/255)-(B/255)))+0;
00145         float orange_hue = 60*(((tB/255)-(tR/255))/((tG/255) - (tR/255)))+120;
00146         //orange saturation (of HSL)
00147         float orange_sat = ((200.0/255.0)-(70/255.0))/(2.0-(270.0/255.0));//using tR,tG,tB, R,B,G gives '1'
00148         std::cout<<"orange hue is: "<<orange_hue<<std::endl;
00149         std::cout<<"orange saturation(purity) is: "<<orange_sat<<std::endl;
00150         std::cout<<"orange HSV saturation is: "<<(1.0-70.0/200.0)<<std::endl;
00151 //  LINFO("orange values (RGB):(std RGB): %f, %f, %f: %f, %f, %f", R, G, B, tR, tG, tB);
00152   while (iptr != stop)
00153     {
00154         float hue = 0.0;
00155         float s = 0.0; //saturation
00156       float avgR = (*iptr).red();
00157       float avgG = (*iptr).green();
00158       float avgB = (*iptr).blue();
00159         float r = avgR/255;
00160         float g = avgG/255;
00161         float b = avgB/255;
00162 
00163 
00164 
00165 
00166         //do conversion to HSV to find the hue
00167         float max = 0;
00168         float min = 1;
00169         //find max
00170         if(r > max) { max = r;}
00171         if(g > max) { max = g;}
00172         if(b > max) { max = b;}
00173         //find min
00174         if(r < min){min = r;}
00175         if(g < min){min = g;}
00176         if(b < min){min = b;}
00177 
00178         //do conversion to find hue
00179         if(max == min) {hue = 0.0;}
00180         else if(max == r && g >= b) {hue = 60.0*((g-b)/(max - min)) + 0.0;}
00181         else if(max == r && g < b) {hue = 60.0*((g-b)/(max - min)) + 360.0;}
00182         else if(max == g) {hue =  60.0*((b-r)/(max-min))+120.0;}
00183         else if(max == b) {hue = 60.0*((r-g)/(max-min))+240.0;}
00184 
00185 
00186         //for average calculation
00187         totalHue += hue;
00188         numTotal++;
00189 
00190         //find saturation
00191         if(max){s = max;}
00192         if(max != 0){s = 1 - min/max;}
00193         //std::cout<<" "<<hue;
00194         if(hue == orange_hue)//result:get spects here and there
00195         {
00196           //(*optr) = (byte)255;  // orange
00197           //orangeCount++;
00198         }
00199         if(hue == pure_orange_hue)//result:nothing
00200         {
00201           //(*optr) = (byte)255;  // orange
00202           //orangeCount++;
00203         }
00204         //to reason these numbers 145 is about the value of orange hue
00205         //pretty good but with spects, "s != 1" gets rid of specs, but also takes out some of the pipe
00206         //value of 120 to 145 seems best
00207         //using 130 as min makes it less accurate
00208         //using a higher max does not seem to make a difference
00209         //probably because of the colors involved here
00210         if(!(120<hue && hue<146) &&
00211         s != 1)
00212         {
00213         //std::cout<<" "<<s;
00214           (*optr) = (byte)255;  // orange
00215          orangeCount++;
00216         }
00217 
00218       //float avg = (avgR+avgG+avgB)/3.0;
00219       //float sigma = pow(avgR - avg, 2.) + pow(avgG - avg, 2.) + pow(avgB - avg, 2.);
00220       //float stdDev = sqrt( (1./3.) * sigma );
00221 
00222         //result: pretty good but is confused by highlights
00223       if (avgR > R - tR && avgR < R + tR &&
00224           avgG > G - tG && avgG < G + tG &&
00225           avgB > B - tB && avgB < B + tB   )
00226         {
00227           (*optr) = (byte)255;  // orange
00228           orangeCount++;
00229         }
00230 //       else
00231 //         {
00232 //           //if(outputImage.coordsOk(i,j)){
00233 //           //(*optr) = (byte)0; //not orange
00234 //           //}
00235 //         }
00236 
00237       iptr++; optr++;
00238     }
00239 
00240         std::cout<<"average hue was "<<totalHue/numTotal<<std::endl;
00241   return float(orangeCount)/float( (inputImage.getHeight() * inputImage.getWidth()));
00242 }
00243 
00244 
00245     */
00246 
00247 
00248 
00249 //true test with frame 3498
00250 float ColorSegmenter::isolateOrange(Image< PixRGB<byte> > &inputImage,  Image<byte> &outputImage)
00251 {
00252   Image< PixRGB<byte> > tempImage(inputImage);
00253   Image<PixH2SV2<float> > h2svImage(tempImage);
00254 
00255   readConfig colorConf;
00256   colorConf.openFile("colortrack.conf", false);
00257 
00258   int orangeCount = 0;
00259 
00260   Image<PixRGB<byte> >::iterator iptr = inputImage.beginw();
00261   Image<byte>::iterator          optr = outputImage.beginw();
00262   Image<PixRGB<byte> >::iterator stop = inputImage.endw();
00263 
00264   float tR = colorConf.getItemValueF("ORANGE_stdR");//70.0;
00265   float tG = colorConf.getItemValueF("ORANGE_stdG");//200.0;
00266   float tB = colorConf.getItemValueF("ORANGE_stdB");//128.0;
00267 
00268   float R = colorConf.getItemValueF("ORANGE_R");//255;
00269   float G = colorConf.getItemValueF("ORANGE_G");//198;
00270   float B = colorConf.getItemValueF("ORANGE_B");//0;
00271 
00272 
00273   //for average
00274   float totalHue = 0.0;
00275   int numTotal = 0;
00276 
00277   //orange as a hue
00278   float pure_orange_hue =  60*(((G/255)-(B/255))/((R/255)-(B/255)))+0;
00279   float orange_hue = 60*(((tB/255)-(tR/255))/((tG/255) - (tR/255)))+120;
00280   //orange saturation (of HSL)
00281   float orange_sat = ((200.0/255.0)-(70/255.0))/(2.0-(270.0/255.0));//using tR,tG,tB, R,B,G gives '1'
00282 
00283   std::cout<<"orange hue is: "<<orange_hue<<std::endl;
00284   std::cout<<"orange saturation(purity) is: "<<orange_sat<<std::endl;
00285   std::cout<<"orange HSV saturation is: "<<(1.0-70.0/200.0)<<std::endl;
00286   //  LINFO("orange values (RGB):(std RGB): %f, %f, %f: %f, %f, %f", R, G, B, tR, tG, tB);
00287 
00288   while (iptr != stop)
00289     {
00290       float hue = 0.0;
00291       float s = 0.0; //saturation
00292       float avgR = (*iptr).red();
00293       float avgG = (*iptr).green();
00294       float avgB = (*iptr).blue();
00295       float r = avgR/255;
00296       float g = avgG/255;
00297       float b = avgB/255;
00298 
00299 
00300 
00301 
00302       //do conversion to HSV to find the hue
00303       float max = 0;
00304       float min = 1;
00305       //find max
00306       if(r > max) { max = r;}
00307       if(g > max) { max = g;}
00308       if(b > max) { max = b;}
00309       //find min
00310       if(r < min){min = r;}
00311       if(g < min){min = g;}
00312       if(b < min){min = b;}
00313 
00314       //do conversion to find hue
00315       if(max == min) {hue = 0.0;}
00316       else if(max == r && g >= b) {hue = 60.0*((g-b)/(max - min)) + 0.0;}
00317       else if(max == r && g < b) {hue = 60.0*((g-b)/(max - min)) + 360.0;}
00318       else if(max == g) {hue =  60.0*((b-r)/(max-min))+120.0;}
00319       else if(max == b) {hue = 60.0*((r-g)/(max-min))+240.0;}
00320 
00321 
00322       //for average calculation
00323       totalHue += hue;
00324       numTotal++;
00325 
00326       //find saturation
00327       if(max){s = max;}
00328       if(max != 0){s = 1 - min/max;}
00329       //std::cout<<" "<<hue;
00330       if(hue == orange_hue)//result:get spects here and there
00331         {
00332           //(*optr) = (byte)255;  // orange
00333           //orangeCount++;
00334         }
00335       if(hue == pure_orange_hue)//result:nothing
00336         {
00337           //(*optr) = (byte)255;  // orange
00338           //orangeCount++;
00339         }
00340         //to reason these numbers 145 is about the value of orange hue
00341         //pretty good but with spects, "s != 1" gets rid of specs, but also takes out some of the pipe
00342         //value of 120 to 145 seems best
00343         //using 130 as min makes it less accurate
00344         //using a higher max does not seem to make a difference
00345         //probably because of the colors involved here
00346       if(!(120<hue && hue<146) &&
00347          s != 1)
00348         {
00349         //std::cout<<" "<<s;
00350           (*optr) = (byte)255;  // orange
00351           orangeCount++;
00352         }
00353 
00354       //float avg = (avgR+avgG+avgB)/3.0;
00355       //float sigma = pow(avgR - avg, 2.) + pow(avgG - avg, 2.) + pow(avgB - avg, 2.);
00356       //float stdDev = sqrt( (1./3.) * sigma );
00357 
00358         //result: pretty good but is confused by highlights
00359       if (avgR > R - tR && avgR < R + tR &&
00360           avgG > G - tG && avgG < G + tG &&
00361           avgB > B - tB && avgB < B + tB   )
00362         {
00363           (*optr) = (byte)255;  // orange
00364           orangeCount++;
00365         }
00366       //       else
00367       //         {
00368       //           //if(outputImage.coordsOk(i,j)){
00369       //           //(*optr) = (byte)0; //not orange
00370       //           //}
00371       //         }
00372       iptr++; optr++;
00373 
00374     }
00375 
00376       //display image to compare to what we get with the color segmenter
00377 
00378       Image<PixRGB<byte> > Aux;
00379       Aux.resize(100,450,true);
00380 
00381       /******************************************************************/
00382       // SEGMENT IMAGE ON EACH INPUT FRAME
00383 
00384       segmenter->SITtrackImageAny(h2svImage,&inputImage,&Aux,true);
00385 
00386       /* Retrieve and Draw all our output images */
00387       Image<byte> temp = quickInterpolate(segmenter->SITreturnCandidateImage(),4);
00388       //display for now for testing purposes
00389       //wini->drawImage(display);
00390       wino->drawImage(temp);
00391 
00392       std::cout<<"average hue was "<<totalHue/numTotal<<std::endl;
00393       return float(orangeCount)/float( (inputImage.getHeight() * inputImage.getWidth()));
00394 }
00395 
00396 
00397 
00398 
00399 
Generated on Sun May 8 08:04:33 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3