00001
00002
00003
00004
00005
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;
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
00321
00322
00323
00324
00325
00326
00327 unsigned char currentColorClass = (unsigned char)(colorTable64.colorClasses[0][0][0]);
00328
00329
00330 unsigned char nextColorClass;
00331
00332
00333 const unsigned char* colorTable = (const unsigned char*)&colorTable64.colorClasses;
00334
00335
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
00356 stream << (int)0;
00357
00358 return stream;
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 In& operator>>(In& stream,ColorTable64& colorTable64)
00405 {
00406
00407
00408
00409
00410
00411
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
00426 unsigned char currentColorClass;
00427
00428
00429 unsigned int currentLength;
00430
00431
00432 unsigned int pos=0;
00433
00434 while(pos < colorTableSize)
00435 {
00436 stream >> currentLength;
00437 if (currentLength == 0)
00438 if(!pos)
00439 stream >> currentLength >> currentLength;
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 }