27#include <hugin_config.h>
31#include <vigra/error.hxx>
32#include <vigra/impex.hxx>
33#include <vigra/codec.hxx>
47template <
class SrcImgType,
class AlphaImgType,
class FlatImgType,
class DestImgType>
59template <
class PIXELTYPE>
63static void usage(
const char* name)
65 std::cout << name <<
": correct lens distortion, vignetting and chromatic abberation" << std::endl
68 <<
"Usage: " << name <<
" [options] inputfile(s) " << std::endl
69 <<
" option are: " << std::endl
70 <<
" --green=db|a:b:c:d Correct radial distortion for all channels" << std::endl
71 <<
" Specify 'db' for database lookup or" << std::endl
72 <<
" the 4 coefficients a:b:c:d" << std::endl
73 <<
" --blue=db|a:b:c:d Correct radial distortion for blue channel," << std::endl
74 <<
" this is applied on top of the --green" << std::endl
75 <<
" distortion coefficients, use for TCA corr" << std::endl
76 <<
" Specify 'db' for database lookup or" << std::endl
77 <<
" the 4 coefficients a:b:c:d" << std::endl
78 <<
" --red=db|a:b:c:d Correct radial distortion for red channel," << std::endl
79 <<
" this is applied on top of the --green" << std::endl
80 <<
" distortion coefficients, use for TCA corr" << std::endl
81 <<
" Specify 'db' for database lookup or" << std::endl
82 <<
" the 4 coefficients a:b:c:d" << std::endl
83 <<
" --camera-maker=Maker Camera manufacturer, for database query" << std::endl
84 <<
" --camera-model=Cam Camera name, for database query" << std::endl
85 <<
" --lensname=Lens Lens name, for database query" << std::endl
86 <<
" Specify --camera-maker and --camera-model" << std::endl
87 <<
" for fixed lens cameras or --lensname" << std::endl
88 <<
" for interchangeable lenses." << std::endl
89 <<
" --focallength=50 Specify focal length in mm, for database query" << std::endl
90 <<
" --aperture=3.5 Specify aperture for vignetting data database query" << std::endl
91 <<
" --dont-rescale Do not rescale the image to avoid black borders." << std::endl
93 <<
" --flatfield=filename Vignetting correction by flatfield division" << std::endl
94 <<
" I = I / c, c = flatfield / mean(flatfield)" << std::endl
95 <<
" --vignetting=db|a:b:c:d Correct vignetting (by division)" << std::endl
96 <<
" Specify db for database look up or the " << std::endl
97 <<
" the 4 coefficients a:b:c:d" << std::endl
98 <<
" I = I / ( a + b*r^2 + c*r^4 + d*r^6)" << std::endl
99 <<
" --linear Do vignetting correction in linear color space" << std::endl
100 <<
" --gamma=value Gamma of input data. used for gamma correction" << std::endl
101 <<
" before and after flatfield correction" << std::endl
102 <<
" --help Display help (this text)" << std::endl
103 <<
" --output=name Set output filename. If more than one image is given," << std::endl
104 <<
" the name will be uses as suffix" << std::endl
105 <<
" (default suffix: _corr)" << std::endl
106 <<
" --compression=value Compression of the output files" << std::endl
107 <<
" For jpeg output: 0-100" << std::endl
108 <<
" For tiff output: PACKBITS, DEFLATE, LZW" << std::endl
109 <<
" --offset=X:Y Horizontal and vertical shift" << std::endl
110 <<
" --verbose Verbose" << std::endl;
117 const char*
optstring =
"e:g:b:r:m:n:l:d:sf:c:i:t:ho:x:va:";
147 std::vector<double>
vec4(4);
151 unsigned verbose = 0;
155 std::string compression;
275 std::cout <<
"WARNING: Switch --threads is deprecated. Set environment variable OMP_NUM_THREADS instead" << std::endl;
332 std::vector<std::string>
inFiles;
360 std::string name(
argv[
i]);
407 std::cerr <<
"Correcting " << *
inIt <<
" -> " << *
outIt << endl;
413 vigra::ImageImportInfo info(
inIt->c_str());
414 const char*
pixelType = info.getPixelType();
415 int bands = info.numBands();
426 std::cerr <<
"Not enough data for database lookup" << std::endl
427 <<
"Specify lensname (--lensname) or camera maker and model " << std::endl
428 <<
"(--camera-maker and --camera-model) as parameter." << std::endl;
440 std::cerr <<
"Could not determine focal length." << std::endl
441 <<
"Specify focal length (--focallength) as parameter." << std::endl;
451 std::cout <<
"Lookup in database for " <<
currentImg.getDBLensName() <<
" @ " <<
currentImg.getExifFocalLength() <<
" mm" << std::endl;
457 std::cerr <<
"No suitable distortion data found in database." << std::endl
458 <<
"Skipping image." << std::endl;
464 std::cout <<
"Read distortion data: " <<
dist[0] <<
", " <<
dist[1] <<
", " <<
dist[2] <<
", " <<
dist[3] << std::endl;
469 if (
fabs(aperture) < 0.1)
473 std::cerr <<
"Could not determine aperture." << std::endl
474 <<
"Specify aperture (--aperture) as parameter." << std::endl;
484 std::cerr <<
"No suitable vignetting data found in database." << std::endl
485 <<
"Skipping image." << std::endl;
490 std::vector<double>
vig =
currentImg.getRadialVigCorrCoeff();
491 std::cout <<
"Read vigneting data: " <<
vig[1] <<
", " <<
vig[2] <<
", " <<
vig[3] << std::endl;
505 std::cerr <<
"No suitable tca data found in database." << std::endl
506 <<
"Skipping image." << std::endl;
511 std::cout <<
"Read tca data red: " <<
tcaRed[0] <<
", " <<
tcaRed[1] <<
", " <<
tcaRed[2] <<
", " <<
tcaRed[3] << std::endl;
518 if (bands == 3 || (bands == 4 &&
extraBands == 1))
548 DEBUG_ERROR(
"unsupported depth, only 3 channel images are supported");
551 throw std::runtime_error(
"unsupported depth, only 3 channels images are supported");
556 catch (std::exception& e)
558 std::cerr <<
"caught exception: " << e.what() << std::endl;
585template <
class SrcImgType,
class AlphaImgType,
class FlatImgType,
class DestImgType>
601 progress->setMessage(
"correcting image");
612 std::vector<double>
outLut;
615 invResp.setOutput(1.0 / pow(2.0,
src.getExposureValue()),
outLut, maxValue);
619 vigra::transformImage(srcImageRange(
srcImg), destImage(
srcImg), vigra::functor::Arg1()/vigra::functor::Param(maxValue));
627 vigra::BImage alpha(
destImg.size());
641 vigra::transformImage(vigra::srcImageRange(
srcFlat), vigra::destImage(
srcFlat), vigra::functor::Arg1() / vigra::functor::Param(maxValue));
646 vigra::gaussianSmoothing(vigra::srcImageRange(
srcFlat), vigra::destImage(
srcFlat), 20);
648 vigra::FindAverage<typename FlatImgType::value_type>
meanFlat;
650 vigra::transformImage(vigra::srcImageRange(
srcFlat), vigra::destImage(
srcFlat), vigra::functor::Arg1() / vigra::functor::Param(
meanFlat.average()));
660 DEBUG_DEBUG(
"Black border correction scale factor: " << scaleFactor);
661 double sf=scaleFactor;
662 std::vector<double>
radGreen =
src.getRadialDistortion();
663 for (
int i=0;
i < 4;
i++)
673 if (
src.getCorrectTCA())
752 vigra::functor::Arg1() & vigra::functor::Arg2() & vigra::functor::Arg3());
759 std::vector <double>
radCoeff =
src.getRadialDistortion();
760 if (
transf.isIdentity() ||
769 transformImageAlpha(srcImageRange(
srcImg),
785template <
class PIXELTYPE>
789 vigra::BasicImage<vigra::RGBValue<double> >
srcImg(info.size());
790 vigra::BasicImage<PIXELTYPE>
output(info.size());
791 vigra::BImage alpha(info.size(), 255);
793 if (info.numBands() == 3)
795 vigra::importImage(info, destImage(
srcImg));
799 importImageAlpha(info, destImage(
srcImg), destImage(alpha));
804 vigra::ImageImportInfo
finfo(
src.getFlatfieldFilename().c_str());
811 outInfo.setICCProfile(info.getICCProfile());
812 outInfo.setPixelType(info.getPixelType());
813 if (!compression.empty())
815 outInfo.setCompression(compression.c_str());
817 const std::string
filetype(vigra::getEncoder(
outInfo.getFileName())->getFileType());
818 if (vigra::isBandNumberSupported(
filetype, 4))
821 std::cout <<
"Saving " <<
outInfo.getFileName() << std::endl;
827 std::cout <<
"Saving " <<
outInfo.getFileName() <<
" without alpha channel" << std::endl
828 <<
"because the fileformat " <<
filetype <<
" does not support" << std::endl
829 <<
"an alpha channel." << std::endl;
class to access Hugins camera and lens database
Dummy progress display, without output.
a progress display to print progress reports to a stream
VignettingCorrMode
vignetting correction mode (bitflags, no real enum)
@ VIGCORR_DIV
correct by division.
@ VIGCORR_FLATFIELD
flatfield correction
@ VIGCORR_NONE
no vignetting correction
@ VIGCORR_RADIAL
radial vignetting correction
@ RESPONSE_LINEAR
linear response
@ RESPONSE_EMOR
empirical model of response
static void Clean()
cleanup the static LensDB instance, must be called at the end of the program
static LensDB & GetSingleton()
returns the static LensDB instance
All variables of a source image.
int main(int argc, char *argv[])
void correctImage(SrcImgType &srcImg, const AlphaImgType &srcAlpha, const FlatImgType &srcFlat, HuginBase::SrcPanoImage src, vigra_ext::Interpolator interpolator, double maxValue, DestImgType &destImg, AlphaImgType &destAlpha, bool doCrop, AppBase::ProgressDisplay *progress)
void correctRGB(HuginBase::SrcPanoImage &src, vigra::ImageImportInfo &info, const char *outfile, bool crop, const std::string &compression, AppBase::ProgressDisplay *progress)
class AlphaIterator class AlphaAccessor inline void exportImageAlpha(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor, AlphaIterator alpha_upper_left, AlphaAccessor alpha_accessor, const ImageExportInfo &export_info)
double estScaleFactorForFullFrame(const SrcPanoImage &src)
Calculate effective scaling factor for a given source image.
std::string stripExtension(const std::string &basename2)
remove extension of a filename
std::string getExtension(const std::string &basename2)
Get extension of a filename.
std::string tolower(const std::string &s)
convert a string to lowercase
std::string GetHuginVersion()
return a string with version numbers
std::string stripPath(const std::string &filename)
remove the path of a filename (mainly useful for gui display of filenames)
void createEMoRLUT(const std::vector< float > ¶ms, VECTOR &lut)
void transformImage(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, 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 an image into the panorama.
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.
double getMaxValForPixelType(const std::string &v)
Interpolator
enum with all interpolation methods
void enforceMonotonicity(LUT &lut)
enforce monotonicity of an array (mostly used for lookup tables)
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.