Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

# Representations/Perception/ColorTable64.cpp

Go to the documentation of this file.

    00001 /**
    00002 * @file ColorTable64.cpp
    00003 * Implementation of class ColorTable64.
    00004 *
    00005 * @author <A href=mailto:juengel@informatik.hu-berlin.de>Matthias Jüngel</A>
    00006 */
    00007
    00008 #include "ColorTable64.h"
    00009 #include "Platform/GTAssert.h"
    00010
    00011 void ColorTable64::generateColorClassImage(const Image& image,
    00012     ColorClassImage& colorClassImage) const
    00013 {
    00014   colorClassImage.width = image.cameraInfo.resolutionWidth;
    00015   colorClassImage.height = image.cameraInfo.resolutionHeight;
    00016
    00017   for (register int y = 0; y < image.cameraInfo.resolutionHeight; y++) {
    00018     for (register int x = 0; x < image.cameraInfo.resolutionWidth; x++) {
    00019       colorClassImage.image[y][x]
    00020         = colorClasses[image.image[y][0][x]/4][image.image[y][1][x]/4][image.image[y][2][x]/4];
    00021     }
    00022   }
    00023 }
    00024
    00025 void ColorTable64::convert32Kto64(const unsigned char* c32k, unsigned char c64[64][64][64])
    00026 {
    00027   int c32pos;
    00028   unsigned char mask1, mask2;
    00029   for (int y=0; y<32; y++)
    00030     for (int u=0; u<64; u++)
    00031       for (int v=0; v<64; v++){
    00032         c32pos = ((y/4)<<12)|(u<<6)|v;
    00033         mask1 = 0x0f&c32k[c32pos];
    00034         mask2 = 0x0f&(c32k[c32pos]>>4);
    00035         c64[2*y][v][u] = mask1;
    00036         c64[2*y+1][v][u] = mask2;
    00037       }
    00038 }
    00039
    00040 void ColorTable64::generateHighResColorClassImage(const Image& image,
    00041     ColorClassImage& colorClassImage
    00042     ) const
    00043 {
    00044   colorClassImage.width = image.cameraInfo.resolutionWidth * 2;
    00045   colorClassImage.height = image.cameraInfo.resolutionHeight * 2;
    00046
    00047   for (register int y = 0; y < image.cameraInfo.resolutionHeight * 2; y++) {
    00048     for (register int x = 0; x < image.cameraInfo.resolutionWidth * 2; x++) {
    00049       colorClassImage.image[y][x] = colorClasses
    00050         [image.getHighResY(x, y)/4]
    00051         [image.image[y / 2][1][x / 2]/4]
    00052         [image.image[y / 2][2][x / 2]/4];
    00053     }
    00054   }
    00055 }
    00056
    00057 void ColorTable64::generateColorClassImage(const Image& image,
    00058     ColorClassImage& colorClassImage,
    00059     colorClass colorClass
    00060     ) const
    00061 {
    00062   colorClassImage.width = image.cameraInfo.resolutionWidth;
    00063   colorClassImage.height = image.cameraInfo.resolutionHeight;
    00064
    00065   for (register int y = 0; y < image.cameraInfo.resolutionHeight; y++) {
    00066     for (register int x = 0; x < image.cameraInfo.resolutionWidth; x++) {
    00067       if(colorClasses[image.image[y][0][x]/4][image.image[y][1][x]/4][image.image[y][2][x]/4] == colorClass)
    00068       {
    00069         colorClassImage.image[y][x] = colorClass;
    00070       }
    00071       else
    00072       {
    00073         colorClassImage.image[y][x] = noColor;
    00074       }
    00075     }
    00076   }
    00077 }
    00078
    00079 void ColorTable64::generateHighResColorClassImage(const Image& image,
    00080     ColorClassImage& colorClassImage,
    00081     colorClass colorClass
    00082     ) const
    00083 {
    00084   colorClassImage.width = image.cameraInfo.resolutionWidth * 2;
    00085   colorClassImage.height = image.cameraInfo.resolutionHeight * 2;
    00086
    00087   for (register int y = 0; y < image.cameraInfo.resolutionHeight * 2; y++) {
    00088     for (register int x = 0; x < image.cameraInfo.resolutionWidth * 2; x++) {
    00089       if(colorClasses
    00090         [image.getHighResY(x,y)/4]
    00091         [image.image[y / 2][1][x / 2]/4]
    00092         [image.image[y / 2][2][x / 2]/4]
    00093         == colorClass)
    00094       {
    00095         colorClassImage.image[y][x] = colorClass;
    00096       }
    00097       else
    00098       {
    00099         colorClassImage.image[y][x] = noColor;
    00100       }
    00101     }
    00102   }
    00103 }
    00104
    00105
    00106 ColorTable64::ColorTable64() : format(CT64)
    00107 {
    00108   clear();
    00109 }
    00110
    00111 ColorTable64::~ColorTable64() {}
    00112
    00113 void ColorTable64::addColorClass
    00114 (
    00115  colorClass colorClass,
    00116  unsigned char y,
    00117  unsigned char u,
    00118  unsigned char v
    00119  )
    00120 {
    00121   this->colorClasses[y/4][u/4][v/4] = colorClass;
    00122 }
    00123
    00124 void ColorTable64::addColorClass
    00125 (
    00126  colorClass colorClass,
    00127  unsigned char y,
    00128  unsigned char u,
    00129  unsigned char v,
    00130  unsigned char range
    00131  )
    00132 {
    00133   y /= 4;
    00134   u /= 4;
    00135   v /= 4;
    00136
    00137   if (y < range / 2) y = range / 2;
    00138   if (u < range / 2) u = range / 2;
    00139   if (v < range / 2) v = range / 2;
    00140
    00141   for(unsigned char currentY = y - range / 2; currentY < y - range / 2 + range && currentY < 64; currentY++)
    00142   {
    00143     for(unsigned char currentU = u - range / 2; currentU < u - range / 2 + range && currentU < 64; currentU++)
    00144     {
    00145       for(unsigned char currentV = v - range / 2; currentV < v - range / 2 + range && currentV < 64; currentV++)
    00146       {
    00147         ASSERT(currentY < 64);
    00148         ASSERT(currentU < 64);
    00149         ASSERT(currentV < 64);
    00150         this->colorClasses[currentY][currentU][currentV] = colorClass;
    00151       }
    00152     }
    00153   }
    00154 }
    00155
    00156 void ColorTable64::addCuboidToColorClass
    00157 (
    00158  colorClass colorClass,
    00159  unsigned char yMin,
    00160  unsigned char uMin,
    00161  unsigned char vMin,
    00162  unsigned char yMax,
    00163  unsigned char uMax,
    00164  unsigned char vMax
    00165  )
    00166 {
    00167   yMin /= 4; uMin /= 4; vMin /= 4;
    00168   yMax /= 4; uMax /= 4; vMax /= 4;
    00169
    00170   for(unsigned char currentY = yMin; currentY <= yMax; currentY++)
    00171   {
    00172     for(unsigned char currentU = uMin; currentU <= uMax; currentU++)
    00173     {
    00174       for(unsigned char currentV = vMin; currentV <= vMax; currentV++)
    00175       {
    00176         this->colorClasses[currentY][currentU][currentV] = colorClass;
    00177         ASSERT(currentY < 64);
    00178         ASSERT(currentU < 64);
    00179         ASSERT(currentV < 64);
    00180       }
    00181     }
    00182   }
    00183 }
    00184
    00185 void ColorTable64::removeColorClass
    00186 (
    00187  unsigned char y,
    00188  unsigned char u,
    00189  unsigned char v,
    00190  unsigned char range
    00191  )
    00192 {
    00193   y /= 4;
    00194   u /= 4;
    00195   v /= 4;
    00196
    00197   if (y < range / 2) y = range / 2;
    00198   if (u < range / 2) u = range / 2;
    00199   if (v < range / 2) v = range / 2;
    00200
    00201   for(unsigned char currentY = y - range / 2; currentY < y - range / 2 + range + 1 && currentY < 64; currentY++)
    00202   {
    00203     for(unsigned char currentU = u - range / 2; currentU < u - range / 2 + range + 1 && currentU < 64; currentU++)
    00204     {
    00205       for(unsigned char currentV = v - range / 2; currentV < v - range / 2 + range + 1 && currentV < 64; currentV++)
    00206       {
    00207         this->colorClasses[currentY][currentU][currentV] = noColor;
    00208       }
    00209     }
    00210   }
    00211 }
    00212
    00213
    00214 void ColorTable64::clearChannel(colorClass colorClass)
    00215 {
    00216   for (unsigned char y = 0; y < 64; y++)
    00217   {
    00218     for (unsigned char u = 0; u < 64; u++)
    00219     {
    00220       for (unsigned char v = 0; v < 64; v++)
    00221       {
    00222         if (colorClasses[y][u][v] == colorClass) colorClasses[y][u][v] = noColor;
    00223       }
    00224     }
    00225   }
    00226 }
    00227
    00228 void ColorTable64::clear()
    00229 {
    00230   for (unsigned char y = 0; y < 64; y++)
    00231   {
    00232     for (unsigned char u = 0; u < 64; u++)
    00233     {
    00234       for (unsigned char v = 0; v < 64; v++)
    00235       {
    00236         this->colorClasses[y][u][v] = noColor;
    00237       }
    00238     }
    00239   }
    00240 }
    00241
    00242 void ColorTable64::getBoxAroundColorClass(colorClass color,
    00243                                           Vector3<int>& pNear, Vector3<int>& pFar)
    00244 {
    00245   pNear = Vector3<int>(0,0,0);
    00246   pFar = Vector3<int>(255,255,255);
    00247   unsigned char y(0),u(0),v(0);
    00248   while(y<64)
    00249   {
    00250     u = 0;
    00251     while(u<64)
    00252     {
    00253       v = 0;
    00254       while(v<64)
    00255       {
    00256         if(colorClasses[y][u][v] == color)
    00257         {
    00258           Vector3<int> first(y,u,v);
    00259           pNear = first;
    00260           pFar = first;
    00261           v++;
    00262           goto expandBox;
    00263         }
    00264         v++;
    00265       }
    00266       u++;
    00267     }
    00268     y++;
    00269   }
    00270   return; //Return if the color has not been found
    00271   expandBox:
    00272   while(y<64)
    00273   {
    00274     u = 0;
    00275     while(u<64)
    00276     {
    00277       v = 0;
    00278       while(v<64)
    00279       {
    00280         if(colorClasses[y][u][v] == color)
    00281         {
    00282           Vector3<int> expand(y,u,v);
    00283           if(expand.x < pNear.x)
    00284           {
    00285             pNear.x = expand.x;
    00286           }
    00287           else if(expand.x > pFar.x)
    00288           {
    00289             pFar.x = expand.x;
    00290           }
    00291           if(expand.y < pNear.y)
    00292           {
    00293             pNear.y = expand.y;
    00294           }
    00295           else if(expand.y > pFar.y)
    00296           {
    00297             pFar.y = expand.y;
    00298           }
    00299           if(expand.z < pNear.z)
    00300           {
    00301             pNear.z = expand.z;
    00302           }
    00303           else if(expand.z > pFar.z)
    00304           {
    00305             pFar.y = expand.y;
    00306           }
    00307         }
    00308         v++;
    00309       }
    00310       u++;
    00311     }
    00312     y++;
    00313   }
    00314   pNear *= 4;
    00315   pFar *= 4;
    00316 }
    00317
    00318 Out& operator << (Out& stream, const ColorTable64& colorTable64)
    00319 {
    00320   // the old version of the streaming operator, can be used for converting
    00321   // old colortables to new ones (with the VC debugger)
    00322 //  stream.write(&colorTable64.colorClasses,sizeof(colorTable64.colorClasses));
    00323 //  return stream;
    00324
    00325
    00326   // the current color class in the color table
    00327   unsigned char currentColorClass = (unsigned char)(colorTable64.colorClasses[0][0][0]);
    00328
    00329   // the next color class to be compared with the last one
    00330   unsigned char nextColorClass;
    00331
    00332   // a pointer to the begin of the color table
    00333   const unsigned char* colorTable = (const unsigned char*)&colorTable64.colorClasses;
    00334
    00335   // the number of bytes in one sequence that have the same color class
    00336   int currentLength = 1;
    00337
    00338   for (unsigned int i=1;i<sizeof(colorTable64.colorClasses);i++)
    00339   {
    00340     nextColorClass = colorTable[i];
    00341
    00342     if (nextColorClass != currentColorClass)
    00343     {
    00344       stream << currentLength << currentColorClass;
    00345       currentColorClass = nextColorClass;
    00346       currentLength = 1;
    00347     }
    00348     else
    00349     {
    00350       currentLength++;
    00351     }
    00352   }
    00353   stream << currentLength << currentColorClass;
    00354
    00355   // write a 0 at the end of the stream as a marker for the In streaming operator
    00356   stream << (int)0;
    00357
    00358   return stream;
    00359 }
    00360
    00361 //~ In& operator>>(In& stream,ColorTable64& colorTable64)
    00362 //~ {
    00363   //~ // the old version of the streaming operator, can be used for converting
    00364   //~ // old colortables to new ones (with the VC debugger)
    00365 //~ //  stream.read(&colorTable64.colorClasses,sizeof(colorTable64.colorClasses));
    00366 //~ //  return stream;
    00367
    00368   //~ // a pointer to the begin of the color table
    00369   //~ unsigned char* colorTable = (unsigned char*)&colorTable64.colorClasses;
    00370
    00371   //~ // the current color class in the color table
    00372   //~ unsigned char currentColorClass;
    00373
    00374   //~ // the number of bytes in one sequence that have the same color class
    00375   //~ unsigned int currentLength;
    00376
    00377   //~ // the position in the color table
    00378   //~ unsigned int pos=0;
    00379
    00380   //~ while(pos < sizeof(colorTable64.colorClasses))
    00381   //~ {
    00382     //~ stream >> currentLength;
    00383     //~ if (currentLength == 0)
    00384       //~ if(!pos) // support for old format that contains table size
    00385         //~ stream >> currentLength >> currentLength; // skip length
    00386       //~ else
    00387         //~ break;
    00388     //~ stream >> currentColorClass;
    00389
    00390     //~ for (unsigned int i=0;i<=currentLength && i + pos < sizeof(colorTable64.colorClasses);i++)
    00391     //~ {
    00392       //~ colorTable[i+pos] = currentColorClass;
    00393       //~ if (i+pos > sizeof(colorTable64.colorClasses) - 1)
    00394         //~ break;;
    00395     //~ }
    00396
    00397     //~ pos += currentLength;
    00398   //~ }
    00399
    00400   //~ return stream;
    00401 //~ }
    00402
    00403
    00404 In& operator>>(In& stream,ColorTable64& colorTable64)
    00405 {
    00406   // the old version of the streaming operator, can be used for converting
    00407   // old colortables to new ones (with the VC debugger)
    00408 //  stream.read(&colorTable64.colorClasses,sizeof(colorTable64.colorClasses));
    00409 //  return stream;
    00410
    00411   // a pointer to the begin of the color table
    00412   unsigned char* colorTable;
    00413   unsigned int colorTableSize;
    00414   if (colorTable64.format == ColorTable64::CT32K)
    00415   {
    00416     colorTableSize = ColorTable64::CT32K_SIZE;
    00417     colorTable = new unsigned char[ColorTable64::CT32K_SIZE];
    00418   }
    00419   else
    00420   {
    00421     colorTableSize = ColorTable64::CT64_SIZE;
    00422     colorTable = (unsigned char*)&colorTable64.colorClasses;
    00423   }
    00424
    00425   // the current color class in the color table
    00426   unsigned char currentColorClass;
    00427
    00428   // the number of bytes in one sequence that have the same color class
    00429   unsigned int currentLength;
    00430
    00431   // the position in the color table
    00432   unsigned int pos=0;
    00433
    00434   while(pos < colorTableSize)
    00435   {
    00436     stream >> currentLength;
    00437     if (currentLength == 0)
    00438       if(!pos) // support for old format that contains table size
    00439         stream >> currentLength >> currentLength; // skip length
    00440       else
    00441         break;
    00442     stream >> currentColorClass;
    00443
    00444     for (unsigned int i=0;i<=currentLength && i + pos < colorTableSize; i++)
    00445     {
    00446       colorTable[i+pos] = currentColorClass;
    00447       if (i+pos > colorTableSize - 1)
    00448         break;
    00449     }
    00450
    00451     pos += currentLength;
    00452   }
    00453
    00454   if (colorTable64.format == ColorTable64::CT32K)
    00455   {
    00456     ColorTable64::convert32Kto64(colorTable, colorTable64.colorClasses);
    00457     delete [] colorTable;
    00458   }
    00459
    00460   return stream;
    00461 }
    00462 bool ColorTable64::hasXNeighbors(unsigned char y, unsigned char u, unsigned char v, int x, unsigned char cc[64][64][64])
    00463 {
    00464   int neighbours = 0;
    00465   unsigned char c = cc[y][u][v];
    00466   if (y > 0)
    00467   {
    00468     if (cc[y-1][u][v] == c)
    00469     {
    00470       neighbours++;
    00471     }
    00472   }
    00473   if (u > 0)
    00474   {
    00475     if (cc[y][u-1][v] == c)
    00476     {
    00477       neighbours++;
    00478     }
    00479   }
    00480   if (v > 0)
    00481   {
    00482     if (cc[y][u][v-1] == c)
    00483     {
    00484       neighbours++;
    00485     }
    00486   }
    00487   if (y < 63)
    00488   {
    00489     if (cc[y+1][u][v] == c)
    00490     {
    00491       neighbours++;
    00492     }
    00493   }
    00494   if (u < 63)
    00495   {
    00496     if (cc[y][u+1][v] == c)
    00497     {
    00498       neighbours++;
    00499     }
    00500   }
    00501   if (v < 63)
    00502   {
    00503     if (cc[y][u][v+1] == c)
    00504     {
    00505       neighbours++;
    00506     }
    00507   }
    00508   if (neighbours >= x)
    00509   {
    00510     return true;
    00511   }
    00512   else
    00513   {
    00514     return false;
    00515   }
    00516 }
    00517
    00518 unsigned char ColorTable64::getNeighborColor(unsigned char y, unsigned char u, unsigned char v, unsigned char cc[64][64][64])
    00519 {
    00520   unsigned char returnColor = cc[y][u][v];
    00521   if(returnColor != noColor)
    00522   {
    00523     return returnColor;
    00524   }
    00525   else
    00526   {
    00527     if (y > 0)
    00528     {
    00529       if (cc[y-1][u][v] != noColor)
    00530       {
    00531         returnColor = cc[y-1][u][v];
    00532       }
    00533     }
    00534     if (u > 0)
    00535     {
    00536       if (cc[y][u-1][v] != noColor)
    00537       {
    00538         returnColor = cc[y][u-1][v];
    00539       }
    00540     }
    00541     if (v > 0)
    00542     {
    00543       if (cc[y][u][v-1] != noColor)
    00544       {
    00545         returnColor = cc[y][u][v-1];
    00546       }
    00547     }
    00548     if (y < 63)
    00549     {
    00550       if (cc[y+1][u][v] != noColor)
    00551       {
    00552         returnColor = cc[y+1][u][v];
    00553       }
    00554     }
    00555     if (u < 63)
    00556     {
    00557       if (cc[y][u+1][v] != noColor)
    00558       {
    00559         returnColor = cc[y][u+1][v];
    00560       }
    00561     }
    00562     if (v < 63)
    00563     {
    00564       if (cc[y][u][v+1] != noColor)
    00565       {
    00566         returnColor = cc[y][u][v+1];
    00567       }
    00568     }
    00569     return returnColor;
    00570   }
    00571 }
    00572
    00573 void ColorTable64::shrink()
    00574 {
    00575   unsigned char cc2[64][64][64];
    00576   memcpy(cc2, colorClasses, sizeof(colorClasses));
    00577   unsigned char y,u,v;
    00578   for (y = 0; y < 64; y++)
    00579   {
    00580     for (u = 0; u < 64; u++)
    00581     {
    00582       for (v = 0; v < 64; v++)
    00583      {
    00584         if (!hasXNeighbors(y,u,v,6,cc2))
    00585         {
    00586           this->colorClasses[y][u][v] = noColor;
    00587         }
    00588       }
    00589     }
    00590   }
    00591 }
    00592
    00593 void ColorTable64::shrink(unsigned char color)
    00594 {
    00595   unsigned char cc2[64][64][64];
    00596   memcpy(cc2, colorClasses, sizeof(colorClasses));
    00597   unsigned char y,u,v;
    00598   for (y = 0; y < 64; y++)
    00599   {
    00600     for (u = 0; u < 64; u++)
    00601     {
    00602       for (v = 0; v < 64; v++)
    00603       {
    00604         if (!hasXNeighbors(y,u,v,6,cc2)&&cc2[y][u][v] == color)
    00605         {
    00606           this->colorClasses[y][u][v] = noColor;
    00607         }
    00608       }
    00609     }
    00610   }
    00611 }
    00612
    00613 void ColorTable64::grow()
    00614 {
    00615   unsigned char cc2[64][64][64];
    00616   memcpy(cc2, colorClasses, sizeof(colorClasses));
    00617   unsigned char y,u,v;
    00618   for (y = 0; y < 64; y++)
    00619   {
    00620     for (u = 0; u < 64; u++)
    00621     {
    00622       for (v = 0; v < 64; v++)
    00623       {
    00624         if (hasXNeighbors(y,u,v,1,cc2))
    00625         {
    00626           colorClasses[y][u][v] = getNeighborColor(y,u,v,cc2);
    00627         }
    00628       }
    00629     }
    00630   }
    00631 }
    00632
    00633 void ColorTable64::grow(unsigned char color)
    00634 {
    00635   unsigned char cc2[64][64][64];
    00636   memcpy(cc2, colorClasses, sizeof(colorClasses));
    00637   unsigned char y,u,v;
    00638   for (y = 0; y < 64; y++)
    00639   {
    00640     for (u = 0; u < 64; u++)
    00641     {
    00642       for (v = 0; v < 64; v++)
    00643       {
    00644         if (hasXNeighbors(y,u,v,1,cc2)&&getNeighborColor(y,u,v,cc2)==color)
    00645         {
    00646           colorClasses[y][u][v] = getNeighborColor(y,u,v,cc2);
    00647         }
    00648       }
    00649     }
    00650   }
    00651 }