28 #include <hugin_config.h>
42 #include "vigra/impexalpha.hxx"
44 static void usage(
const char* name)
46 std::cout << name <<
": report the number of image groups in a project" << std::endl
49 <<
"Usage: " << name <<
" input.pto" << std::endl
51 << name <<
" examines the connections between images in a project and" << std::endl
52 <<
"reports back the number of parts or image groups in that project" << std::endl
54 <<
"Further switches:" << std::endl
55 <<
" --print-output-info Print more information about the output" << std::endl
56 <<
" --print-lens-info Print more information about lenses" << std::endl
57 <<
" --print-stack-info Print more information about assigned stacks" << std::endl
58 <<
" --print-image-info Print information about image files" << std::endl
59 <<
" --create-missing-images Creates placeholder images for non-existing" << std::endl
60 <<
" images in same directory as the pto file" << std::endl
62 << name <<
" is used by the assistant" << std::endl
66 void PrintImageGroup(
const std::vector<HuginBase::UIntSet>& imageGroup,
const std::string& prefix=std::string())
68 for (
size_t i=0; i < imageGroup.size(); i++)
72 std::cout << prefix <<
" " << i <<
": ";
76 for (HuginBase::UIntSet::const_iterator it = imageGroup[i].begin(); it != imageGroup[i].end(); ++it)
79 if (c+1 != imageGroup[i].size())
86 if (prefix.empty() && (i+1 != imageGroup.size()))
90 std::cout << std::endl;
96 vigra::FindMinMax<float> minmax;
97 vigra::inspectImage(
srcImageRange(image, vigra::RedAccessor<vigra::RGBValue<float>>()), minmax);
98 std::cout <<
" Red channel: " << minmax.min <<
"-" << minmax.max << std::endl;
100 vigra::inspectImage(
srcImageRange(image, vigra::GreenAccessor<vigra::RGBValue<float>>()), minmax);
101 std::cout <<
" Green channel: " << minmax.min <<
"-" << minmax.max << std::endl;
103 vigra::inspectImage(
srcImageRange(image, vigra::BlueAccessor<vigra::RGBValue<float>>()), minmax);
104 std::cout <<
" Blue channel: " << minmax.min <<
"-" << minmax.max << std::endl;
109 vigra::FindMinMax<float> minmax;
111 std::cout <<
" " << text <<
": " << minmax.min <<
"-" << minmax.max << std::endl;
117 std::cout << std::endl;
120 const std::string filename = pano.
getImage(imgNr).getFilename();
121 std::cout <<
"Image " << imgNr <<
": " << filename;
124 if (vigra::isImage(filename.c_str()))
126 vigra::ImageImportInfo
info(filename.c_str());
127 std::filesystem::path file(filename);
128 std::cout << std::endl
129 <<
" File type: " <<
info.getFileType() << std::endl;
130 const auto fileSize = std::filesystem::file_size(file);
131 std::cout <<
" File size: ";
134 std::cout << fileSize / 1000 <<
" kB" << std::endl;
138 std::cout << fileSize <<
" B" << std::endl;
140 std::cout <<
" Pixel type: " <<
info.getPixelType() << std::endl
141 <<
" Pixel size: " <<
info.width() <<
"x" <<
info.height() << std::endl
142 <<
" Resolution: " <<
info.getXResolution() <<
"/" <<
info.getYResolution() << std::endl
143 <<
" Offset: " <<
info.getPosition() << std::endl
144 <<
" Canvas size: " <<
info.getCanvasSize() << std::endl
146 <<
" Bands: " <<
info.numBands() << std::endl
147 <<
" Extra bands: " <<
info.numExtraBands() << std::endl;
148 if (
info.numImages() > 1)
150 std::cout <<
" Subimages: " <<
info.numImages() <<
" (reading index " <<
info.getImageIndex() <<
")" << std::endl;
152 if (
info.numExtraBands() == 0)
155 if (
info.numBands() == 3)
158 vigra::FRGBImage image(
info.size());
164 if (
info.numBands() == 1)
167 vigra::FImage image(
info.size());
173 std::cout <<
" Only RGB or grayscale images supported" << std::endl;
176 std::cout << std::endl;
180 if (
info.numExtraBands() == 1)
183 if (
info.numBands() == 4)
186 vigra::FRGBImage image(
info.size());
187 vigra::FImage mask(
info.size());
194 if (
info.numBands() == 2)
197 vigra::FImage image(
info.size());
198 vigra::FImage mask(
info.size());
205 std::cout <<
" Only RGB or grayscale images supported" << std::endl;
208 std::cout << std::endl;
212 std::cout <<
" Only images with one or no alpha channel supported" << std::endl;
219 std::filesystem::path file(filename);
220 std::cout << std::endl <<
" not recognized by vigra as image file" << std::endl
221 <<
" File size: " << std::filesystem::file_size(file) / 1024 <<
" kiB" << std::endl << std::endl;
227 std::cout <<
" does not exists." << std::endl <<std::endl;
236 std::uniform_int_distribution<> distribIndex(0, 128);
237 auto randIndex = std::bind(distribIndex, rng);
239 bool requiresPTOrewrite =
false;
242 const std::filesystem::path imagePath(ptoPath);
246 std::filesystem::path srcFile(pano.
getImage(imgNr).getFilename());
247 std::cout <<
"Image " << imgNr <<
": " << srcFile.string();
248 if (std::filesystem::exists(srcFile))
250 std::cout <<
" exists." << std::endl;
255 srcFile = std::filesystem::absolute(srcFile);
256 std::filesystem::path newImage(imagePath);
257 newImage /= srcFile.filename();
259 if (newImage != srcFile)
261 requiresPTOrewrite =
true;
264 std::cout <<
" does not exist. Creating " << newImage.filename() << std::endl;
267 vigra::RGBValue<vigra::UInt8>(64 + randIndex(), 64 + randIndex(), 64 + randIndex()));
268 vigra::ImageExportInfo imgExportInfo(newImage.string().c_str());
272 if (requiresPTOrewrite)
277 std::cout <<
"Written output to " << output << std::endl;
282 int main(
int argc,
char* argv[])
285 const char* optstring =
"h";
288 PRINT_OUTPUT_INFO=1000,
289 PRINT_LENS_INFO=1004,
290 PRINT_STACK_INFO=1005,
291 CREATE_DUMMY_IMAGES=1006,
294 static struct option longOptions[] =
296 {
"print-output-info", no_argument, NULL, PRINT_OUTPUT_INFO },
297 {
"print-lens-info", no_argument, NULL, PRINT_LENS_INFO },
298 {
"print-stack-info", no_argument, NULL, PRINT_STACK_INFO },
299 {
"print-image-info", no_argument, NULL, PRINT_IMAGE_INFO },
300 {
"create-missing-images", no_argument, NULL, CREATE_DUMMY_IMAGES },
301 {
"help", no_argument, NULL,
'h' },
306 bool printOutputInfo=
false;
307 bool printLensInfo =
false;
308 bool printStackInfo =
false;
309 bool printImageInfo =
false;
310 bool createDummyImages =
false;
312 while ((c = getopt_long (argc, argv, optstring, longOptions,
nullptr)) != -1)
319 case PRINT_OUTPUT_INFO:
320 printOutputInfo=
true;
322 case PRINT_LENS_INFO:
323 printLensInfo =
true;
325 case PRINT_STACK_INFO:
326 printStackInfo =
true;
328 case PRINT_IMAGE_INFO:
329 printImageInfo =
true;
331 case CREATE_DUMMY_IMAGES:
332 createDummyImages =
true;
345 if (argc - optind != 1)
347 if (argc - optind < 1)
359 std::string input=argv[optind];
362 if (createDummyImages)
374 std::cout << std::endl
375 <<
"Opened project " << input << std::endl << std::endl
376 <<
"Project contains" << std::endl
392 std::cout <<
"Control points statistics" << std::endl
393 << std::fixed << std::setprecision(2)
394 <<
"\tMean error : " << mean << std::endl
395 <<
"\tStandard deviation: " << sqrt(var) << std::endl
396 <<
"\tMinimum : " << min << std::endl
397 <<
"\tMaximum : " << max << std::endl;
405 std::cout <<
"All images are connected." << std::endl;
411 std::cout <<
"Found unconnected images!" << std::endl
412 <<
"There are " << comps.size() <<
" image groups." << std::endl;
414 std::cout <<
"Image groups: " << std::endl;
415 for (
size_t i=0; i < comps.size(); i++)
418 HuginGraph::ImageGraph::Components::value_type::const_iterator it;
420 for (it = comps[i].begin(); it != comps[i].end(); ++it)
423 if (c+1 != comps[i].size())
430 if (i+1 != comps.size())
432 std::cout <<
", " << std::endl;
435 returnValue=comps.size();
437 std::cout << std::endl;
440 std::cout << std::endl <<
"Lenses:" << std::endl;
445 std::cout << std::endl <<
"Stacks:" << std::endl;
452 std::cout << std::endl <<
"Output contains" << std::endl
453 << stacks.size() <<
" images stacks:" << std::endl;
456 std::cout << std::endl << std::endl <<
"and " << layers.size() <<
" exposure layers:" << std::endl;
461 std::cout <<
"Supported file formats: " << vigra::impexListFormats() << std::endl
462 <<
"Supported extensions: " << vigra::impexListExtensions() << std::endl;
465 if (createDummyImages)
std::string GetICCDesc(const vigra::ImageImportInfo::ICCProfile &iccProfile)
returns description of given icc profile
void InspectGrayscaleImage(const vigra::FImage &image, const std::string text)
std::vector< UIntSet > getHDRStacks(const PanoramaData &pano, UIntSet allImgs, PanoramaOptions opts)
returns vector of set of output stacks
bool FileExists(const std::string &filename)
checks if file exists
declaration of functions to handle stacks and layers
std::vector< UIntSet > getExposureLayers(const PanoramaData &pano, UIntSet allImgs, PanoramaOptions opts)
returns vector of set of output exposure layers
void InspectRGBImage(const vigra::FRGBImage &image)
std::string GetOutputFilename(const std::string &out, const std::string &in, const std::string &suffix)
construct output filename, if ouput is known return this value otherwise use the input filename and a...
ConstImageVariableGroup & getStacks()
Get the ImageVariableGroup representing the group of stack variables.
Somewhere to specify what variables belong to what.
static void calcCtrlPntsErrorStats(const PanoramaData &pano, double &min, double &max, double &mean, double &var, const int &imgNr=-1, const bool onlyActive=false, const bool ignoreLineCp=false)
UIntSet getImagesinROI(const PanoramaData &pano, const UIntSet activeImages)
returns set of images which are visible in output ROI
void PrintImageInfo(const HuginBase::Panorama &pano)
std::size_t getNrOfCtrlPoints() const
number of control points
int getHeight() const
Get the height of the image in pixels.
std::vector< HuginBase::UIntSet > Components
stores the components of the graph
void PrintImageGroup(const std::vector< HuginBase::UIntSet > &imageGroup, const std::string &prefix=std::string())
void CreateMissingImages(HuginBase::Panorama &pano, const std::string &output)
std::set< unsigned int > UIntSet
ConstImageVariableGroup & getLenses()
Get the ImageVariableGroup representing the group of lens variables.
UIntSetVector getPartsSet() const
return a vector which contains a HuginBase::UIntSet for each group with the corresponding images numb...
std::string getPathPrefix(const std::string &filename)
Get the path to a filename.
std::string GetAbsoluteFilename(const std::string &filename)
returns the full absolute filename
std::size_t getNrOfImages() const
number of images.
int getWidth() const
Get the width of the image in pixels.
bool ReadPTOFile(const std::string &filename, const std::string &prefix="")
read pto file from the given filename into Panorama object it does some checks on the file and issues...
Make an ImageVariableGroup for lenses and other common concepts.
void setImageFilename(unsigned int img, const std::string &fname)
set a new image filename
vigra::pair< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImage(ROIImage< Image, Alpha > &img)
vigra::triple< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImageRange(const ROIImage< Image, Mask > &img)
helper function for ROIImages
UIntSet getActiveImages() const
get active images
void importImageAlpha(const ImageImportInfo &import_info, ImageIterator image_iterator, ImageAccessor image_accessor, AlphaIterator alpha_iterator, AlphaAccessor alpha_accessor)
Read the image specified by the given vigra::ImageImportInfo object including its alpha channel...
const PanoramaOptions & getOptions() const
returns the options for this panorama
Components GetComponents()
find all connected components
std::string GetHuginVersion()
return a string with version numbers
bool WritePTOFile(const std::string &filename, const std::string &prefix="")
write data to given pto file
static void info(const char *fmt,...)
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
std::size_t getNumberOfParts() const
get the number of parts.
std::string stripPath(const std::string &filename)
remove the path of a filename (mainly useful for gui display of filenames)
int main(int argc, char *argv[])
class to work with images graphs created from a HuginBase::Panorama class it creates a graph based on...