Go to the documentation of this file.00001
00013 #ifndef FeatureImage_H
00014 #define FeatureImage_H
00015
00016 #include <vector>
00017 #include <cstdlib>
00018
00019 #include "SingleElementImage.h"
00020 #include "Feature.h"
00021 #include "GrayLevelImage8.h"
00022
00027 namespace puma2 {
00028
00048 template <typename T> class FeatureImage : public SingleElementImage<T> {
00049
00050 private:
00051
00063 void createMask(int radius, bool **(&mask));
00064
00065 public:
00066
00077 FeatureImage(int x = 0, int y = 0)
00078 : SingleElementImage<T>(x,y) {}
00079
00098 FeatureImage(int x, int y, FeatureImage * m, int xo, int yo)
00099 : SingleElementImage<T>(x,y,m,xo,yo) {}
00100
00104 virtual ~FeatureImage() {}
00105
00106
00118 Feature<T> getGlobalMaximum();
00119
00120
00133 std::vector<Feature<T> > getGlobalMaxima(int n);
00134
00135
00146 Feature<T> getGlobalMinimum();
00147
00148
00161 std::vector<Feature<T> > getGlobalMinima(int n);
00162
00163
00180 std::vector<Feature<T> > getLocalMinima(int n, T threhold, int radius);
00181
00182
00198 std::vector<Feature<T> > getLocalMinima(T thresh, int radius);
00199
00200
00217 std::vector<Feature<T> > getLocalMaxima(int n, T threshold, int radius);
00218
00219
00235 std::vector<Feature<T> > getLocalMaxima(T threshold, int radius);
00236
00237
00243 virtual GrayLevelImage8 getGrayLevelImageRepresentation() = 0;
00244
00245 };
00246
00247
00248
00249
00250
00251 template <typename T> Feature<T> FeatureImage<T>::getGlobalMaximum()
00252 {
00253 int h = this->getHeight();
00254 int w = this->getWidth();
00255
00256 Feature<T> max;
00257
00258 max.x = 0;
00259 max.y = 0;
00260 max.val = &(this->c0[0][0]);
00261
00262 for (int y = 0; y < h; ++y)
00263 {
00264 for (int x = 0; x < w; ++x)
00265 {
00266 T *tmp = &(this->c0[y][x]);
00267 if ( (*max.val) < (*tmp) )
00268 {
00269 max.x = x;
00270 max.y = y;
00271 max.val = tmp;
00272 }
00273 }
00274 }
00275
00276 return max;
00277 }
00278
00279
00280
00281
00282
00283 template <typename T> std::vector<Feature<T> > FeatureImage<T>::getGlobalMaxima(int n)
00284 {
00285 int h = this->getHeight();
00286 int w = this->getWidth();
00287
00288 assert (w*h >= n);
00289
00290 std::vector<Feature<T> > maxima;
00291 maxima.resize(n);
00292
00293
00294
00295
00296 std::vector<bool> isSet(n,false);
00297
00298 for (int y = 0; y < h; ++y)
00299 {
00300 for (int x = 0; x < w; ++x)
00301 {
00302 T *tmp = &(this->c0[y][x]);
00303 if ( !isSet[0] || ( (*maxima[0].val) < *tmp ) )
00304 {
00305 int i=1;
00306 while ( (i < n) && (!isSet[i] || ( *maxima[i].val) < *tmp ) )
00307 ++i;
00308 --i;
00309 for (int j=0; j<i; ++j)
00310 {
00311 maxima[j].x = maxima[j+1].x;
00312 maxima[j].y = maxima[j+1].y;
00313 maxima[j].val = maxima[j+1].val;
00314 }
00315 maxima[i].x = x;
00316 maxima[i].y = y;
00317 maxima[i].val = tmp;
00318 isSet [i] = true;
00319 }
00320 }
00321 }
00322
00323 return maxima;
00324 }
00325
00326
00327
00328
00329
00330 template <typename T> Feature<T> FeatureImage<T>::getGlobalMinimum()
00331 {
00332 int h = this->getHeight();
00333 int w = this->getWidth();
00334
00335 Feature<T> min;
00336
00337 min.x = 0;
00338 min.y = 0;
00339 min.val = &(this->c0[0][0]);
00340 for (int y = 0; y < h; ++y) {
00341 for (int x = 0; x < w; ++x)
00342 {
00343 T *tmp = &(this->c0[y][x]);
00344 if ( *tmp < (*min.val) )
00345 {
00346 min.x = x;
00347 min.y = y;
00348 min.val = tmp;
00349 }
00350 }
00351 }
00352
00353 return min;
00354 }
00355
00356
00357
00358
00359
00360 template <typename T> std::vector<Feature<T> > FeatureImage<T>::getGlobalMinima(int n)
00361 {
00362 int h = this->getHeight();
00363 int w = this->getWidth();
00364
00365 assert (w*h >= n);
00366
00367 std::vector<Feature<T> > minima;
00368 minima.resize(n);
00369
00370
00371
00372
00373 std::vector<bool> isSet(n,false);
00374
00375 for (int y=0; y<h; ++y)
00376 {
00377 for (int x=0; x<w; ++x)
00378 {
00379 T *tmp = &(this->c0[y][x]);
00380 if ( !isSet[0] || ( *tmp < (*minima[0].val) ) )
00381 {
00382 int i=1;
00383 while ( (i < n) && (!isSet[i] || *tmp < (*minima[i].val) ) )
00384 ++i;
00385 for (int j = --i; j > 0; --j)
00386 {
00387 minima[j-1].x = minima[j].x;
00388 minima[j-1].y = minima[j].y;
00389 minima[j-1].val = minima[j].val;
00390 }
00391 minima[i].x = x;
00392 minima[i].y = y;
00393 minima[i].val = tmp;
00394 isSet [i] = true;
00395 }
00396 }
00397 }
00398
00399 return minima;
00400 }
00401
00402
00403
00404
00405
00406
00407 template <typename T> std::vector<Feature<T> > FeatureImage<T>::getLocalMaxima(int n,
00408 T thresh, int radius)
00409 {
00410 int h = this->getHeight();
00411 int w = this->getWidth();
00412
00413 assert (w*h >= n);
00414
00415 std::vector<Feature<T> > maxima;
00416 maxima.resize(n);
00417
00418
00419 bool **mask;
00420 createMask(radius, mask);
00421
00422
00423
00424
00425
00426 std::vector<bool> isSet(n,false);
00427
00428
00429 for (int y = 0; y < h; ++y)
00430 {
00431 for (int x=0; x<w; ++x)
00432 {
00433 bool isMax = true;
00434 T * val = &(this->c0[y][x]);
00435 for (int i = -radius; ( i <= radius ) && isMax; ++i)
00436 {
00437 for (int j = -radius; (j <= radius) && isMax; ++j)
00438 {
00439 if ( (mask[i][j]) && ( j!= 0 || i != 0) &&
00440 ( y + i >= 0 && y + i < h ) &&
00441 ( x + j >= 0 && x + j < w ) )
00442 isMax &= ( *val >= this->c0[y+i][x+j] && *val > thresh);
00443 }
00444 }
00445 if (isMax)
00446 {
00447 T *tmp = &(this->c0[y][x]);
00448 if ( !isSet[0] || ( (*maxima[0].val) < *tmp ) )
00449 {
00450 int i=1;
00451 while ( (i < n) && (!isSet[i] || (*maxima[i].val) < *tmp ))
00452 ++i;
00453 --i;
00454 for (int j=0; j<i; ++j)
00455 {
00456 maxima[j].x = maxima[j+1].x;
00457 maxima[j].y = maxima[j+1].y;
00458 maxima[j].val = maxima[j+1].val;
00459 }
00460 maxima[i].x = x;
00461 maxima[i].y = y;
00462 maxima[i].val = tmp;
00463 isSet [i] = true;
00464 }
00465 }
00466 }
00467 }
00468
00469 return maxima;
00470 }
00471
00472
00473
00474
00475
00476
00477 template <typename T> std::vector<Feature<T> > FeatureImage<T>::getLocalMaxima(T thresh,
00478 int radius)
00479 {
00480 int h = this->getHeight();
00481 int w = this->getWidth();
00482
00483
00484 bool **mask;
00485 createMask(radius, mask);
00486
00487 std::vector<Feature<T> > maxima;
00488
00489 for (int y = 0; y < h; ++y)
00490 {
00491 for (int x = 0; x < w; ++x)
00492 {
00493 bool isMax = true;
00494 T * val = &(this->c0[y][x]);
00495 for (int i = -radius; (i <= radius) && isMax; ++i)
00496 {
00497 for (int j = -radius; (j <= radius) && isMax; ++j)
00498 {
00499 if ( (mask[i][j]) && (j != 0 || i != 0) &&
00500 (y + i >= 0 && y + i < h) &&
00501 (x + j >= 0 && x + j < w))
00502 isMax &= (*val >= this->c0[ y + i ][ x + j ] &&
00503 *val > thresh);
00504 }
00505 }
00506 if (isMax)
00507 {
00508 Feature<T> feat;
00509 feat.x = x;
00510 feat.y = y;
00511 feat.val = &(this->c0[y][x]);
00512 maxima.push_back(feat);
00513 }
00514 }
00515 }
00516
00517 return maxima;
00518 }
00519
00520
00521
00522
00523
00524
00525 template <typename T> std::vector<Feature<T> > FeatureImage<T>::getLocalMinima(int n,
00526 T thresh, int radius)
00527 {
00528 int h = this->getHeight();
00529 int w = this->getWidth();
00530
00531 assert (w*h >= n);
00532
00533 std::vector<Feature<T> > minima;
00534 minima.resize(n);
00535
00536
00537 bool **mask;
00538 createMask(radius, mask);
00539
00540
00541
00542
00543
00544 std::vector<bool> isSet(n,false);
00545
00546
00547 for (int y = 0; y < h; ++y)
00548 {
00549 for (int x = 0; x < w; ++x)
00550 {
00551 bool isMin = true;
00552 T * val = &(this->c0[y][x]);
00553 for (int i = -radius; (i <= radius) && isMin; ++i)
00554 {
00555 for (int j = -radius; (j <= radius) && isMin; ++j)
00556 {
00557 if ( (mask[i][j]) && (j != 0 || i != 0) &&
00558 (y + i >= 0 && y + i < h) &&
00559 (x + j >= 0 && x + j < w))
00560 isMin &= (*val <= this->c0[ y + i ][ x + j ] &&
00561 *val < thresh);
00562 }
00563 }
00564 if (isMin) {
00565 T *tmp = &(this->c0[y][x]);
00566 if ( !isSet[0] || ( (*minima[0].val) > *tmp ) )
00567 {
00568 int i=1;
00569 while ( (i < n) && (!isSet[i] || (*minima[i].val) > *tmp ) )
00570 ++i;
00571 --i;
00572 for (int j = 0; j < i; ++j)
00573 {
00574 minima[j].x = minima[ j + 1 ].x;
00575 minima[j].y = minima[ j + 1 ].y;
00576 minima[j].val = minima[ j + 1 ].val;
00577 }
00578 minima[i].x = x;
00579 minima[i].y = y;
00580 minima[i].val = tmp;
00581 isSet [i] = true;
00582 }
00583 }
00584 }
00585 }
00586
00587 return minima;
00588 }
00589
00590
00591
00592
00593
00594 template <typename T> std::vector<Feature<T> > FeatureImage<T>::getLocalMinima(T thresh,
00595 int radius)
00596 {
00597 int h = this->getHeight();
00598 int w = this->getWidth();
00599
00600 std::vector<Feature<T> > minima;
00601
00602
00603 bool **mask;
00604 createMask(radius, mask);
00605
00606 for (int y = 0; y < h; ++y)
00607 {
00608 for (int x = 0; x < w; ++x)
00609 {
00610 bool isMin = true;
00611 T * val = &(this->c0[y][x]);
00612 for (int i = -radius; (i <= radius) && isMin; ++i)
00613 {
00614 for (int j = -radius; (j <= radius) && isMin; ++j)
00615 {
00616 if ( (mask[i][j]) && (j != 0 || i != 0) &&
00617 (y + i>= 0 && y + i < h) && (x + j >= 0 && x + j < w))
00618 isMin &= (*val <= this->c0[y+i][x+j] && *val < thresh);
00619 }
00620 }
00621 if (isMin)
00622 {
00623 Feature<T> feat;
00624 feat.x = x;
00625 feat.y = y;
00626 feat.val = &(this->c0[y][x]);
00627 minima.push_back(feat);
00628 }
00629 }
00630 }
00631
00632 return minima;
00633 }
00634
00635
00636
00637
00638
00639
00640 template <typename T> void FeatureImage<T>::createMask(int radius, bool **(&mask))
00641 {
00642 int size = 2*radius+1;
00643 int radius21 = radius * radius + 1;
00644
00645 mask = (bool**) calloc(size, sizeof(bool*)) + radius;
00646
00647 for(int y = -radius; y <= radius; ++y)
00648 {
00649 *(mask+y) = (bool*) calloc(size, sizeof(bool)) + radius;
00650 for (int x = -radius; x <= radius; ++x)
00651 {
00652 if (radius21 >= x * x + y * y)
00653 mask[y][x] = true;
00654 else
00655 mask[y][x] = false;
00656 }
00657 }
00658 }
00659
00660 }
00661
00662 #endif