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