00001
00015 #ifndef _DLRCOMPUTERVISION_UTILITIES_H_
00016 #define _DLRCOMPUTERVISION_UTILITIES_H_
00017
00018 #include <dlrComputerVision/colorspaceConverter.h>
00019 #include <dlrComputerVision/image.h>
00020
00021 namespace dlr {
00022
00023 namespace computerVision {
00024
00071 template<ImageFormat FORMAT>
00072 bool
00073 associateColorComponents(
00074 Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>& inputArray,
00075 Image<FORMAT>& outputImage);
00076
00077
00098 template<ImageFormat FORMAT>
00099 Image<FORMAT>
00100 associateColorComponents(
00101 Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>& inputArray);
00102
00103
00125 template<ImageFormat OUTPUT_FORMAT, ImageFormat INPUT_FORMAT>
00126 Image<OUTPUT_FORMAT>
00127 convertColorspace(const Image<INPUT_FORMAT>& inputImage);
00128
00129
00176 template<ImageFormat FORMAT>
00177 bool
00178 dissociateColorComponents(
00179 Image<FORMAT>& inputImage,
00180 Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>& outputArray);
00181
00182
00205 template<ImageFormat FORMAT>
00206 Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>
00207 dissociateColorComponents(Image<FORMAT>& inputImage);
00208
00209
00239 template<ImageFormat Format>
00240 Image<Format>
00241 subsample(const Image<Format>& inputImage,
00242 size_t rowStep = 2,
00243 size_t columnStep = 2);
00244
00245
00268 template<ImageFormat InputFormat,
00269 ImageFormat OutputFormat,
00270 ImageFormat IntermediateFormat>
00271 Image<OutputFormat>
00272 supersample(const Image<InputFormat>& inputImage);
00273
00274
00289 template <class Type, ImageFormat FORMAT>
00290 Array2D<Type>
00291 toArray(const Image<FORMAT>& inputImage);
00292
00293 }
00294
00295 }
00296
00297
00298
00299
00300
00301 namespace dlr {
00302
00303 namespace computerVision {
00304
00306 namespace privateCode {
00307
00308
00309
00310
00311 template<ImageFormat Format, class ComponentType>
00312 inline bool
00313 associateColorComponents(
00314 Array2D<ComponentType>& inputArray,
00315 Image<Format>& outputImage)
00316 {
00317
00318 typedef typename ImageFormatTraits<Format>::PixelType PixelType;
00319 typedef typename Image<Format>::iterator ImageIterator;
00320 typedef typename Array2D<ComponentType>::iterator ArrayIterator;
00321
00322
00323 if(inputArray.columns()
00324 % ImageFormatTraits<Format>::getNumberOfComponents()
00325 != 0) {
00326 DLR_THROW(ValueException, "associateColorComponents()",
00327 "Input image must have a number of columns which is "
00328 "evenly divisible by the number of color components.");
00329 }
00330
00331
00332 size_t numberOfOutputColumns = inputArray.columns()
00333 / ImageFormatTraits<Format>::getNumberOfComponents();
00334
00335 bool returnValue;
00336 if(PixelType::isContiguous()) {
00337
00338 outputImage = Image<Format>(
00339 inputArray.rows(), numberOfOutputColumns,
00340 reinterpret_cast<PixelType*>(inputArray.data()));
00341 returnValue = true;
00342 } else {
00343 if(outputImage.rows() != inputArray.rows()
00344 || outputImage.columns() != numberOfOutputColumns) {
00345 outputImage = Image<Format>(
00346 inputArray.rows(), numberOfOutputColumns);
00347 }
00348 ArrayIterator arrayIterator = inputArray.begin();
00349 for(ImageIterator imageIterator = outputImage.begin();
00350 imageIterator != outputImage.end(); ++imageIterator) {
00351 imageIterator->copyFromIterator(arrayIterator);
00352 ++imageIterator;
00353 }
00354 returnValue = false;
00355 }
00356 return returnValue;
00357 }
00358
00359
00360
00361
00362
00363 template<>
00364 inline bool
00365 associateColorComponents(
00366 Array2D<bool>& inputArray,
00367 Image<GRAY1>& outputImage)
00368 {
00369 outputImage = inputArray;
00370 return true;
00371 }
00372
00373
00374 template<>
00375 inline bool
00376 associateColorComponents(Array2D<UnsignedInt8>& inputArray,
00377 Image<GRAY8>& outputImage)
00378 {
00379 outputImage = inputArray;
00380 return true;
00381 }
00382
00383
00384 template<>
00385 inline bool
00386 associateColorComponents(Array2D<UnsignedInt16>& inputArray,
00387 Image<GRAY16>& outputImage)
00388 {
00389 outputImage = inputArray;
00390 return true;
00391 }
00392
00393
00394 template<>
00395 inline bool
00396 associateColorComponents(Array2D<UnsignedInt32>& inputArray,
00397 Image<GRAY32>& outputImage)
00398 {
00399 outputImage = inputArray;
00400 return true;
00401 }
00402
00403
00404 template<>
00405 inline bool
00406 associateColorComponents(Array2D<Int16>& inputArray,
00407 Image<GRAY_SIGNED16>& outputImage)
00408 {
00409 outputImage = inputArray;
00410 return true;
00411 }
00412
00413
00414 template<>
00415 inline bool
00416 associateColorComponents(Array2D<Int32>& inputArray,
00417 Image<GRAY_SIGNED32>& outputImage)
00418 {
00419 outputImage = inputArray;
00420 return true;
00421 }
00422
00423
00424 template<>
00425 inline bool
00426 associateColorComponents(Array2D<Float32>& inputArray,
00427 Image<GRAY_FLOAT32>& outputImage)
00428 {
00429 outputImage = inputArray;
00430 return true;
00431 }
00432
00433
00434 template<>
00435 inline bool
00436 associateColorComponents(Array2D<Float64>& inputArray,
00437 Image<GRAY_FLOAT64>& outputImage)
00438 {
00439 outputImage = inputArray;
00440 return true;
00441 }
00442
00443
00444
00445 template<ImageFormat Format, class ComponentType>
00446 inline bool
00447 dissociateColorComponents(
00448 Image<Format>& inputImage,
00449 Array2D<ComponentType>& outputArray)
00450 {
00451
00452 typedef typename ImageFormatTraits<Format>::PixelType PixelType;
00453 typedef typename Image<Format>::iterator ImageIterator;
00454 typedef typename Array2D<ComponentType>::iterator ArrayIterator;
00455
00456
00457 size_t numberOfOutputColumns = inputImage.columns()
00458 * ImageFormatTraits<Format>::getNumberOfComponents();
00459
00460
00461 bool returnValue;
00462 if(PixelType::isContiguous()) {
00463 outputArray = Array2D<ComponentType>(
00464 inputImage.rows(), numberOfOutputColumns,
00465 reinterpret_cast<ComponentType*>(inputImage.data()));
00466 returnValue = true;
00467 } else {
00468 if(outputArray.rows() != inputImage.rows()
00469 || outputArray.columns() != numberOfOutputColumns) {
00470 outputArray = Array2D<ComponentType>(
00471 inputImage.rows(), numberOfOutputColumns);
00472 }
00473 ArrayIterator arrayIterator = outputArray.begin();
00474 for(ImageIterator imageIterator = inputImage.begin();
00475 imageIterator != inputImage.end(); ++imageIterator) {
00476 imageIterator->copyToIterator(arrayIterator);
00477 ++imageIterator;
00478 }
00479 returnValue = false;
00480 }
00481 return returnValue;
00482 }
00483
00484
00485
00486
00487 template<>
00488 inline bool
00489 dissociateColorComponents(Image<GRAY1>& inputImage,
00490 Array2D<bool>& outputArray)
00491 {
00492 outputArray = inputImage;
00493 return true;
00494 }
00495
00496
00497 template<>
00498 inline bool
00499 dissociateColorComponents(Image<GRAY8>& inputImage,
00500 Array2D<UnsignedInt8>& outputArray)
00501 {
00502 outputArray = inputImage;
00503 return true;
00504 }
00505
00506
00507 template<>
00508 inline bool
00509 dissociateColorComponents(Image<GRAY16>& inputImage,
00510 Array2D<UnsignedInt16>& outputArray)
00511 {
00512 outputArray = inputImage;
00513 return true;
00514 }
00515
00516
00517 template<>
00518 inline bool
00519 dissociateColorComponents(Image<GRAY32>& inputImage,
00520 Array2D<UnsignedInt32>& outputArray)
00521 {
00522 outputArray = inputImage;
00523 return true;
00524 }
00525
00526
00527 template<>
00528 inline bool
00529 dissociateColorComponents(Image<GRAY_SIGNED16>& inputImage,
00530 Array2D<Int16>& outputArray)
00531 {
00532 outputArray = inputImage;
00533 return true;
00534 }
00535
00536
00537 template<>
00538 inline bool
00539 dissociateColorComponents(Image<GRAY_SIGNED32>& inputImage,
00540 Array2D<Int32>& outputArray)
00541 {
00542 outputArray = inputImage;
00543 return true;
00544 }
00545
00546
00547 template<>
00548 inline bool
00549 dissociateColorComponents(Image<GRAY_FLOAT32>& inputImage,
00550 Array2D<Float32>& outputArray)
00551 {
00552 outputArray = inputImage;
00553 return true;
00554 }
00555
00556
00557 template<>
00558 inline bool
00559 dissociateColorComponents(Image<GRAY_FLOAT64>& inputImage,
00560 Array2D<Float64>& outputArray)
00561 {
00562 outputArray = inputImage;
00563 return true;
00564 }
00565
00566 }
00568
00569
00570
00571
00572 template<ImageFormat FORMAT>
00573 bool
00574 associateColorComponents(
00575 Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>& inputArray,
00576 Image<FORMAT>& outputImage)
00577 {
00578 return privateCode::associateColorComponents(inputArray, outputImage);
00579 }
00580
00581
00582
00583
00584
00585
00586 template<ImageFormat FORMAT>
00587 Image<FORMAT>
00588 associateColorComponents(
00589 Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>& inputArray)
00590 {
00591 typedef typename ImageFormatTraits<FORMAT>::PixelType PixelType;
00592 if(!PixelType::isContiguous()) {
00593 DLR_THROW(dlr::LogicException, "associateColorComponents()",
00594 "The deprecated single-argument version of "
00595 "associateColorComponents() can only be use with "
00596 "contiguous pixel types.");
00597 }
00598
00599 Image<FORMAT> outputImage;
00600 associateColorComponents(inputArray, outputImage);
00601 return outputImage;
00602 }
00603
00604
00605
00606
00607 template<ImageFormat OUTPUT_FORMAT, ImageFormat INPUT_FORMAT>
00608 Image<OUTPUT_FORMAT>
00609 convertColorspace(const Image<INPUT_FORMAT>& inputImage)
00610 {
00611 Image<OUTPUT_FORMAT> outputImage(
00612 inputImage.rows(), inputImage.columns());
00613 ColorspaceConverter<INPUT_FORMAT, OUTPUT_FORMAT> converter;
00614 std::transform(inputImage.begin(), inputImage.end(),
00615 outputImage.begin(), converter);
00616 return outputImage;
00617 }
00618
00619
00620
00621
00622 template<ImageFormat FORMAT>
00623 bool
00624 dissociateColorComponents(
00625 Image<FORMAT>& inputImage,
00626 Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>& outputArray)
00627 {
00628 return privateCode::dissociateColorComponents(inputImage, outputArray);
00629 }
00630
00631
00632
00633
00634
00635
00636 template<ImageFormat FORMAT>
00637 Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>
00638 dissociateColorComponents(Image<FORMAT>& inputImage)
00639 {
00640 typedef typename ImageFormatTraits<FORMAT>::PixelType PixelType;
00641 if(!PixelType::isContiguous()) {
00642 DLR_THROW(dlr::LogicException, "dissociateColorComponents()",
00643 "The deprecated single-argument version of "
00644 "dissociateColorComponents() can only be use with "
00645 "contiguous pixel types.");
00646 }
00647 Array2D<typename ImageFormatTraits<FORMAT>::ComponentType> outputArray;
00648 dissociateColorComponents(inputImage, outputArray);
00649 return outputArray;
00650 }
00651
00652
00653
00654
00655 template<ImageFormat Format>
00656 Image<Format>
00657 subsample(const Image<Format>& inputImage,
00658 size_t rowStep,
00659 size_t columnStep)
00660 {
00661
00662 if(inputImage.size() == 0) {
00663 return Image<Format>();
00664 }
00665 if(rowStep == 0) {
00666 rowStep = 1;
00667 }
00668 if(columnStep == 0) {
00669 columnStep = 1;
00670 }
00671
00672
00673
00674 Image<Format> outputImage((inputImage.rows() - 1) / rowStep + 1,
00675 (inputImage.columns() - 1) / columnStep + 1);
00676 for(size_t outputRowIndex = 0; outputRowIndex < outputImage.rows();
00677 ++outputRowIndex) {
00678 Array1D<typename Image<Format>::PixelType> inputRow =
00679 inputImage.row(rowStep * outputRowIndex);
00680 Array1D<typename Image<Format>::PixelType> outputRow =
00681 outputImage.row(outputRowIndex);
00682 size_t inputColumnIndex = 0;
00683 for(size_t outputColumnIndex = 0;
00684 outputColumnIndex < outputImage.columns();
00685 ++outputColumnIndex) {
00686 outputRow[outputColumnIndex] = inputRow[inputColumnIndex];
00687 inputColumnIndex += columnStep;
00688 }
00689 }
00690 return outputImage;
00691 }
00692
00693
00694
00695
00696 template<ImageFormat InputFormat,
00697 ImageFormat OutputFormat,
00698 ImageFormat IntermediateFormat>
00699 Image<OutputFormat>
00700 supersample(const Image<InputFormat>& inputImage)
00701 {
00702 Image<OutputFormat> outputImage(inputImage.rows() * 2 - 1,
00703 inputImage.columns() * 2 - 1);
00704 ColorspaceConverter<InputFormat, OutputFormat> converter0;
00705 ColorspaceConverter<InputFormat, IntermediateFormat> converter1;
00706 ColorspaceConverter<IntermediateFormat, OutputFormat> converter2;
00707
00708
00709 typename ImageFormatTraits<IntermediateFormat>::PixelType tempPixel;
00710 Array1D<typename Image<InputFormat>::PixelType> inputRow0;
00711 Array1D<typename Image<InputFormat>::PixelType> inputRow1;
00712 Array1D<typename Image<OutputFormat>::PixelType> outputRow0;
00713 Array1D<typename Image<OutputFormat>::PixelType> outputRow1;
00714
00715
00716 for(size_t inputRowIndex = 0; inputRowIndex < (inputImage.rows() - 1);
00717 ++inputRowIndex) {
00718 inputRow0 = inputImage.row(inputRowIndex);
00719 inputRow1 = inputImage.row(inputRowIndex + 1);
00720 outputRow0 = outputImage.row(2 * inputRowIndex);
00721 outputRow1 = outputImage.row(2 * inputRowIndex + 1);
00722 size_t outputColumnIndex = 0;
00723 for(size_t inputColumnIndex = 0;
00724 inputColumnIndex < (inputImage.columns() - 1);
00725 ++inputColumnIndex) {
00726 outputRow0[outputColumnIndex] =
00727 converter0(inputRow0[inputColumnIndex]);
00728
00729
00730 tempPixel = converter1(inputRow0[inputColumnIndex]);
00731 tempPixel += converter1(inputRow0[inputColumnIndex + 1]);
00732 tempPixel /= 2;
00733 outputRow0[outputColumnIndex + 1] = converter2(tempPixel);
00734
00735 tempPixel = converter1(inputRow0[inputColumnIndex]);
00736 tempPixel += converter1(inputRow1[inputColumnIndex]);
00737 tempPixel /= 2;
00738 outputRow1[outputColumnIndex] = converter2(tempPixel);
00739
00740 tempPixel = converter1(inputRow0[inputColumnIndex]);
00741 tempPixel += converter1(inputRow0[inputColumnIndex + 1]);
00742 tempPixel += converter1(inputRow1[inputColumnIndex]);
00743 tempPixel += converter1(inputRow1[inputColumnIndex + 1]);
00744 tempPixel /= 4;
00745 outputRow1[outputColumnIndex + 1] = converter2(tempPixel);
00746
00747 outputColumnIndex += 2;
00748 }
00749
00750 outputRow0[outputColumnIndex] =
00751 converter0(inputRow0[inputRow0.size() - 1]);
00752
00753 tempPixel = converter1(inputRow0[inputRow0.size() - 1]);
00754 tempPixel += converter1(inputRow1[inputRow0.size() - 1]);
00755 tempPixel /= 2;
00756 outputRow1[outputColumnIndex] = converter2(tempPixel);
00757 }
00758
00759
00760 inputRow0 = inputImage.row(inputImage.rows() - 1);
00761 outputRow0 = outputImage.row(outputImage.rows() - 1);
00762 size_t outputColumnIndex = 0;
00763 for(size_t inputColumnIndex = 0;
00764 inputColumnIndex < (inputImage.columns() - 1);
00765 ++inputColumnIndex) {
00766 outputRow0[outputColumnIndex] =
00767 converter0(inputRow0[inputColumnIndex]);
00768
00769 tempPixel = converter1(inputRow0[inputColumnIndex]);
00770 tempPixel += converter1(inputRow0[inputColumnIndex + 1]);
00771 tempPixel /= 2;
00772 outputRow0[outputColumnIndex + 1] = converter2(tempPixel);
00773
00774 outputColumnIndex += 2;
00775 }
00776 outputRow0[outputImage.columns() - 1] =
00777 inputRow0[inputImage.columns() - 1];
00778
00779 return outputImage;
00780 }
00781
00782
00783
00784
00785 template <class Type, ImageFormat FORMAT>
00786 Array2D<Type>
00787 toArray(const Image<FORMAT>& inputImage)
00788 {
00789
00790 typedef typename ImageFormatTraits<FORMAT>::ComponentType ComponentType;
00791
00792 size_t numberOfOutputColumns = inputImage.columns()
00793 * ImageFormatTraits<FORMAT>::getNumberOfComponents();
00794
00795 Array2D<ComponentType> tempArray;
00796 dissociateColorComponents(
00797 const_cast< Image<FORMAT>& >(inputImage), tempArray);
00798
00799 Array2D<Type> returnValue(inputImage.rows(), numberOfOutputColumns);
00800 returnValue.copy(tempArray);
00801 return returnValue;
00802 }
00803
00804 }
00805
00806 }
00807
00808 #endif