27#ifndef _NONA_REMAPPEDPANOIMAGE_H
28#define _NONA_REMAPPEDPANOIMAGE_H
30#include <vigra/imageinfo.hxx>
31#include <vigra/initimage.hxx>
32#include <vigra/copyimage.hxx>
33#include <vigra/flatmorphology.hxx>
46#define NONA_DEFAULT_EXPOSURE_LOWER_CUTOFF 1/255.0f
47#define NONA_DEFAULT_EXPOSURE_UPPER_CUTOFF 250/255.0f
60template <
class TRANSFORM>
67template <
class TRANSFORM>
72 vigra::BImage & alpha,
79template <
class RemapImage,
class AlphaImage>
126 template<
class DistImgType>
140 template <
class ImgIter,
class ImgAccessor>
150 std::pair<AlphaIter, AlphaAccessor>
alphaImg,
171template <
class SrcImgType,
class FlatImgType,
class DestImgType,
class MaskImgType>
198#include <vigra/impex.hxx>
200#define DEBUG_FILE_PREFIX "C:/temp/"
202#define DEBUG_FILE_PREFIX "/tmp/"
211template <
class RemapImage,
class AlphaImage>
219 if (m_destImg.remapUsingGPU) {
221 const int r =
roi.width() % 8;
222 if (r != 0)
roi.addSize(vigra::Size2D(8 - r, 0));
226 m_transf.createTransform(
src,
dest);
229 DEBUG_DEBUG(
"m_srcImg size: " << m_srcImg.getSize());
240template <
class RemapImage,
class AlphaImage>
242 const PanoCommand::VariableMap &
srcVars,
243 PanoCommand::Lens::LensProjectionFormat
srcProj,
244 const PanoCommand::PanoImage & img,
285template <
class RemapImage,
class AlphaImage>
289 const PanoCommand::PanoImage & img = pano.
getImage(imgNr);
305 m_transf.createTransform(pano, imgNr, opts,
m_srcSize);
312 bool circCrop = pano.getLens(pano.
getImage(imgNr).getLensNr()).getProjection() == Lens::CIRCULAR_FISHEYE;
330template<
class RemapImage,
class AlphaImage>
331template<
class DistImgType>
334 if (Base::boundingBox().
isEmpty())
return;
335 imgX.resize(Base::boundingBox().size().width(), Base::boundingBox().size().height(), vigra::NumericTraits<typename DistImgType::value_type>::max());
336 imgY.resize(Base::boundingBox().size().width(), Base::boundingBox().size().height(), vigra::NumericTraits<typename DistImgType::value_type>::max());
338 int xstart = Base::boundingBox().left();
339 int xend = Base::boundingBox().right();
340 int ystart = Base::boundingBox().top();
341 int yend = Base::boundingBox().bottom();
344 typename DistImgType::Iterator
yImgX(
imgX.upperLeft());
345 typename DistImgType::Iterator
yImgY(
imgY.upperLeft());
346 typename DistImgType::Accessor
accX =
imgX.accessor();
347 typename DistImgType::Accessor
accY =
imgY.accessor();
357 if (m_transf.transformImgCoord(
sx,
sy, x, y))
377template<
class RemapImage,
class AlphaImage>
380 if (Base::boundingBox().
isEmpty())
383 Base::m_mask.resize(Base::boundingBox().size());
385 int xstart = Base::boundingBox().left();
386 int xend = Base::boundingBox().right();
387 int ystart = Base::boundingBox().top();
388 int yend = Base::boundingBox().bottom();
391#pragma omp parallel for schedule(dynamic, 10)
395 typename AlphaImage::Iterator
yalpha(Base::m_mask.upperLeft());
402 if(m_transf.transformImgCoord(
sx,
sy,x,y))
422template <
class ImageType>
431template<
class RemapImage,
class AlphaImage>
432template<
class ImgIter,
class ImgAccessor>
442 const bool useGPU = m_destImg.remapUsingGPU;
444 if (Base::boundingBox().
isEmpty())
458 "RemappedPanoImage<RemapImage,AlphaImage>::remapImage(): image unexpectedly changed dimensions.");
470 std::vector<double>
outLut;
471 if (!m_destImg.outputEMoRParams.empty())
476 if (!m_destImg.outputPixelType.empty()) {
481 maxVal, m_destImg.outputRangeCompression);
483 invResponse.setHDROutput(
true,1.0/pow(2.0,m_destImg.outputExposureValue));
492 switch (m_srcImg.getCropMode()) {
499 initImage(vigra::destImageRange(alpha),0);
501 alpha.upperLeft()+m_srcImg.getSize(),
502 alpha.accessor(),255);
505 initImage(vigra::destImageRange(alpha),255);
508 initImage(vigra::destImageRange(alpha),255);
513 vigra::Rect2D
cR = m_srcImg.getCropRect();
515 (
cR.top() +
cR.height()/2.0) );
517 double radius = std::min(
cR.width(),
cR.height())/2.0;
519 initImage(vigra::destImageRange(alpha),255);
526 vigra::Rect2D
cR = m_srcImg.getCropRect();
528 initImage(vigra::destImageRange(alpha),0);
533 alpha.upperLeft()+
cR.lowerRight(),
534 alpha.accessor(),255);
540 if(m_srcImg.hasActiveMasks())
549 transformImageAlphaGPU(
srcImg,
550 vigra::srcImage(alpha),
551 destImageRange(Base::m_image),
552 destImage(Base::m_mask),
553 Base::boundingBox().upperLeft(),
556 m_srcImg.horizontalWarpNeeded(),
559 if (Base::boundingBox().right() > m_destImg.getROI().right())
563 vigra::Rect2D
newBoundingBox = Base::boundingBox() & m_destImg.getROI();
569 transformImageAlpha(
srcImg,
570 vigra::srcImage(alpha),
571 destImageRange(Base::m_image),
572 destImage(Base::m_mask),
573 Base::boundingBox().upperLeft(),
576 m_srcImg.horizontalWarpNeeded(),
588 alpha.upperLeft()+m_srcImg.getSize(),
589 alpha.accessor(),255);
590 transformImageAlphaGPU(
srcImg,
591 vigra::srcImage(alpha),
592 destImageRange(Base::m_image),
593 destImage(Base::m_mask),
594 Base::boundingBox().upperLeft(),
597 m_srcImg.horizontalWarpNeeded(),
604 destImageRange(Base::m_image),
605 destImage(Base::m_mask),
606 Base::boundingBox().upperLeft(),
609 m_srcImg.horizontalWarpNeeded(),
613 if (Base::boundingBox().right() > m_destImg.getROI().right())
617 vigra::Rect2D
newBoundingBox = Base::boundingBox() & m_destImg.getROI();
624 destImageRange(Base::m_image),
625 destImage(Base::m_mask),
626 Base::boundingBox().upperLeft(),
629 m_srcImg.horizontalWarpNeeded(),
640template<
class RemapImage,
class AlphaImage>
644 std::pair<AlphaIter, AlphaAccessor>
alphaImg,
648 const bool useGPU = m_destImg.remapUsingGPU;
650 if (Base::boundingBox().
isEmpty())
664 "RemappedPanoImage<RemapImage,AlphaImage>::remapImage(): image unexpectedly changed dimensions.");
675 std::vector<double>
outLut;
678 if (!m_destImg.outputPixelType.empty()) {
681 if (!m_destImg.outputEMoRParams.empty())
687 maxVal, m_destImg.outputRangeCompression);
689 invResponse.setHDROutput(
true,1.0/pow(2.0,m_destImg.outputExposureValue));
694 vigra::Rect2D
cR = m_srcImg.getCropRect();
695 switch (m_srcImg.getCropMode()) {
699 vigra::copyImage(vigra::make_triple(
alphaImg.first,
701 vigra::destImage(alpha));
707 vigra::copyImage(vigra::make_triple(
alphaImg.first,
709 vigra::destImage(alpha));
711 (
cR.top() +
cR.height()/2.0) );
712 double radius = std::min(
cR.width(),
cR.height())/2.0;
723 initImage(vigra::destImageRange(alpha),0);
726 vigra::copyImage(
alphaImg.first +
cR.upperLeft(),
729 alpha.upperLeft() +
cR.upperLeft(),alpha.accessor());
735 if(m_srcImg.hasActiveMasks())
745 vigra::srcImage(alpha),
746 destImageRange(Base::m_image),
747 destImage(Base::m_mask),
748 Base::boundingBox().upperLeft(),
751 m_srcImg.horizontalWarpNeeded(),
754 if (Base::boundingBox().right() > m_destImg.getROI().right())
758 vigra::Rect2D
newBoundingBox = Base::boundingBox() & m_destImg.getROI();
765 vigra::srcImage(alpha),
766 destImageRange(Base::m_image),
767 destImage(Base::m_mask),
768 Base::boundingBox().upperLeft(),
771 m_srcImg.horizontalWarpNeeded(),
781 destImageRange(Base::m_image),
782 destImage(Base::m_mask),
783 Base::boundingBox().upperLeft(),
786 m_srcImg.horizontalWarpNeeded(),
789 if (Base::boundingBox().right() > m_destImg.getROI().right())
793 vigra::Rect2D
newBoundingBox = Base::boundingBox() & m_destImg.getROI();
801 destImageRange(Base::m_image),
802 destImage(Base::m_mask),
803 Base::boundingBox().upperLeft(),
806 m_srcImg.horizontalWarpNeeded(),
821template <
class SrcImgType,
class FlatImgType,
class DestImgType,
class MaskImgType>
835 vigra::exportImage(vigra::srcImageRange(
srcImg),
exi);
840 vigra::exportImage(vigra::srcImageRange(
srcAlpha),
exi);
861 vigra::exportImage(vigra::srcImageRange(
remapped.m_image),
exi);
865 vigra::exportImage(vigra::srcImageRange(
remapped.m_mask),
exi);
declaration of classes to work with mask
#define NONA_DEFAULT_EXPOSURE_LOWER_CUTOFF
#define NONA_DEFAULT_EXPOSURE_UPPER_CUTOFF
Helper class for storing different options.
struct to hold a image state for stitching
AlphaImage::Accessor MaskAccessor
RemapImage::value_type image_value_type
RemapImage::ConstAccessor ConstImageAccessor
void remapImage(vigra::triple< ImgIter, ImgIter, ImgAccessor > srcImg, std::pair< AlphaIter, AlphaAccessor > alphaImg, vigra_ext::Interpolator interp, AppBase::ProgressDisplay *progress, bool singleThreaded=false)
remap a image, with alpha channel
void setPanoImage(const SrcPanoImage &src, const PanoramaOptions &dest, vigra::Rect2D roi)
vigra_ext::ValueTypeTraits< image_value_type >::value_type component_type
void setAdvancedOptions(const AdvancedOptions &advancedOptions)
AlphaImage::traverser mask_traverser
RemapImage::traverser image_traverser
AlphaImage::value_type mask_value_type
PanoramaOptions m_destImg
AlphaImage::const_traverser const_mask_traverser
void calcSrcCoordImgs(DistImgType &imgX, DistImgType &imgY)
calculate distance map.
void calcAlpha()
calculate only the alpha channel.
AlphaImage::ConstAccessor ConstMaskAccessor
vigra::ImageImportInfo::ICCProfile m_ICCProfile
void remapImage(vigra::triple< ImgIter, ImgIter, ImgAccessor > srcImg, vigra_ext::Interpolator interpol, AppBase::ProgressDisplay *progress, bool singleThreaded=false)
remap a image without alpha channel
RemapImage::const_traverser const_image_traverser
PTools::Transform m_transf
RemapImage::Accessor ImageAccessor
AdvancedOptions m_advancedOptions
RemappedPanoImage()
create a remapped pano image
vigra_ext::ROIImage< RemapImage, AlphaImage > Base
unsigned int getWidth() const
PanoramaOptions::ProjectionFormat getProjection() const
ProjectionFormat
Projection of final panorama.
unsigned int getHeight() const
get panorama height
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
All variables of a source image.
int getWidth() const
Get the width of the image in pixels.
vigra::FRGBImage ImageType
std::map< std::string, std::string > AdvancedOptions
void estimateImageAlpha(const SrcPanoImage &src, const PanoramaOptions &dest, TRANSFORM &transf, vigra::Rect2D &imgRect, vigra::BImage &alpha, double &scale)
ImageType CopyImageNewSize(const ImageType &image, const vigra::Size2D &newSize)
copies image into new image with changed size
void remapImage(SrcImgType &srcImg, const MaskImgType &srcAlpha, const FlatImgType &srcFlat, const SrcPanoImage &src, const PanoramaOptions &dest, vigra::Rect2D outputRect, RemappedPanoImage< DestImgType, MaskImgType > &remapped, AppBase::ProgressDisplay *progress)
remap a single image
bool GetAdvancedOption(const AdvancedOptions &opts, const std::string &name, const bool defaultValue)
check if given option is saved and return its boolean value, otherwise return defaultValue
void estimateImageRect(const SrcPanoImage &src, const PanoramaOptions &dest, TRANSFORM &transf, vigra::Rect2D &imgRect)
calculate the outline of the image
mainly consists of wrapper around the pano tools library, to assist in ressource management and to pr...
std::string stripPath(const std::string &filename)
remove the path of a filename (mainly useful for gui display of filenames)
void copyImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc)
void createEMoRLUT(const std::vector< float > ¶ms, VECTOR &lut)
void transformImageAlpha(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, std::pair< SrcAlphaIterator, SrcAlphaAccessor > srcAlpha, vigra::triple< DestImageIterator, DestImageIterator, DestAccessor > dest, std::pair< AlphaImageIterator, AlphaAccessor > alpha, vigra::Diff2D destUL, TRANSFORM &transform, PixelTransform &pixelTransform, bool warparound, Interpolator interpol, AppBase::ProgressDisplay *progress, bool singleThreaded=false)
Transform image, and respect a possible alpha channel.
void applyMask(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > img, HuginBase::MaskPolygonVector masks)
double getMaxValForPixelType(const std::string &v)
Interpolator
enum with all interpolation methods
void applyExposureClipMask(vigra::triple< ImgIter, ImgIter, ImgAccessor > image, vigra::triple< AlphaIter, AlphaIter, AlphaAccessor > mask, double lowerLimit, double upperLimit)
void transformImageAlphaGPU(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, std::pair< SrcAlphaIterator, SrcAlphaAccessor > srcAlpha, vigra::triple< DestImageIterator, DestImageIterator, DestAccessor > dest, std::pair< AlphaImageIterator, AlphaAccessor > alpha, vigra::Diff2D destUL, TRANSFORM &transform, PixelTransform &pixelTransform, bool warparound, Interpolator interpol, AppBase::ProgressDisplay *progress)
Transform image, and respect a possible alpha channel.
void enforceMonotonicity(LUT &lut)
enforce monotonicity of an array (mostly used for lookup tables)
void circularCrop(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > img, hugin_utils::FDiff2D middle, double radius)
Apply a circular crop to img.
T1::value_type value_type
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.