33 #include <vigra/impex.hxx>
35 #include <vigra/functorexpression.hxx>
42 #include <pano13/filter.h>
45 static void usage(
const char* name)
47 std::cout << name <<
": find vertical lines in images" << std::endl
50 <<
"Usage: " << name <<
" [options] input.pto" << std::endl
52 <<
" Options:" << std::endl
53 <<
" -o, --output=file.pto Output Hugin PTO file. Default: <filename>_lines.pto" << std::endl
54 <<
" -i, --image=IMGNR Work only on given image numbers" << std::endl
55 <<
" -l, --lines=COUNT Save maximal COUNT lines (default: 5)" << std::endl
56 <<
" -h, --help Shows this help" << std::endl
77 template <
class SrcIMG>
78 void convertToUInt8(SrcIMG& src,
const std::string& origType, vigra::UInt8RGBImage& dest)
80 dest.resize(src.size());
83 if (origType ==
"FLOAT" || origType ==
"DOUBLE" || origType ==
"UINT32" || origType ==
"INT32")
88 vigra::FindAverageAndVariance<float> mean;
89 vigra::inspectImage(
srcImageRange(src, vigra::RGBToGrayAccessor<typename SrcIMG::PixelType>()), mean);
90 const double minVal =
std::max(mean.average() - 3 * sqrt(mean.variance()), 1e-6f);
91 const double maxVal = mean.average() + 3 * sqrt(mean.variance());
101 template <
class SrcIMG>
104 dest.resize(src.size());
107 if (origType ==
"FLOAT" || origType ==
"DOUBLE" || origType ==
"UINT32" || origType ==
"INT32")
112 vigra::FindAverageAndVariance<float> mean;
114 const double minVal =
std::max(mean.average() - 3 * sqrt(mean.variance()), 1e-6f);
115 const double maxVal = mean.average() + 3 * sqrt(mean.variance());
125 template <
class SrcIMG>
129 SrcIMG imageIn(info.width(),info.height());
130 if(info.numExtraBands()==1)
132 mask.resize(info.width(), info.height());
144 template <
class SrcIMG>
147 vigra::UInt8RGBImage image;
148 SrcIMG imageIn(info.width(),info.height());
149 if(info.numExtraBands()==1)
151 mask.resize(info.width(), info.height());
169 std::string pixelType=info.getPixelType();
170 if(pixelType==
"UINT8")
172 image.resize(info.width(),info.height());
173 if(info.numExtraBands()==1)
175 mask.resize(info.width(), info.height());
185 if(pixelType==
"UINT16" || pixelType==
"INT16")
187 image=LoadGrayImageAndConvert<vigra::UInt16Image>(
info, mask);
191 if(pixelType==
"INT32" || pixelType==
"UINT32")
193 image=LoadGrayImageAndConvert<vigra::UInt32Image>(
info, mask);
197 if(pixelType==
"FLOAT" || pixelType==
"DOUBLE")
199 image=LoadGrayImageAndConvert<vigra::FImage>(
info, mask);
203 std::cerr <<
"Unsupported pixel type" << std::endl;
208 if(image.width()>0 && image.height()>0)
218 vigra::UInt8RGBImage image;
221 std::string pixelType=info.getPixelType();
222 if(pixelType==
"UINT8")
224 image.resize(info.width(),info.height());
225 if(info.numExtraBands()==1)
227 mask.resize(info.width(), info.height());
237 if(pixelType==
"UINT16" || pixelType==
"INT16")
239 image=LoadImageAndConvert<vigra::UInt16RGBImage>(
info, mask);
243 if(pixelType==
"INT32" || pixelType==
"UINT32")
245 image=LoadImageAndConvert<vigra::UInt32RGBImage>(
info, mask);
249 if(pixelType==
"FLOAT" || pixelType==
"DOUBLE")
251 image=LoadImageAndConvert<vigra::FRGBImage>(
info, mask);
255 std::cerr <<
"Unsupported pixel type" << std::endl;
260 if(image.width()>0 && image.height()>0)
280 int main(
int argc,
char* argv[])
283 const char* optstring =
"o:i:l:h";
285 static struct option longOptions[] =
287 {
"output", required_argument, NULL,
'o' },
288 {
"image", required_argument, NULL,
'i' },
289 {
"lines", required_argument, NULL,
'l' },
290 {
"help", no_argument, NULL,
'h' },
298 while ((c = getopt_long (argc, argv, optstring, longOptions,
nullptr)) != -1)
310 int imgNr=atoi(optarg);
311 if((imgNr==0) && (strcmp(optarg,
"0")!=0))
316 cmdlineImages.insert(imgNr);
320 nrLines=atoi(optarg);
338 if (argc - optind != 1)
340 if (argc - optind < 1)
352 std::string input=argv[optind];
364 std::vector<size_t> imagesToProcess;
365 if(cmdlineImages.empty())
371 for (
size_t imgGroup = 0; imgGroup < imageGroups.size(); ++imgGroup)
374 if (pano.
getImage(stackImages[0]).YawisLinked())
379 if (pano.
getImage(*(stackImages.begin())).getExposureValue() != pano.
getImage(*(stackImages.rbegin())).getExposureValue())
381 index = stackImages.size() / 2;
383 imagesToProcess.push_back(stackImages[index]);
388 std::copy(stackImages.begin(), stackImages.end(), std::back_inserter(imagesToProcess));
399 for (
size_t i = 0; i < varMapVec.size(); i++)
401 map_get(varMapVec[i],
"TrX").setValue(0);
402 map_get(varMapVec[i],
"TrY").setValue(0);
403 map_get(varMapVec[i],
"TrZ").setValue(0);
408 std::vector<size_t> imagesToCheck;
409 std::swap(imagesToProcess, imagesToCheck);
410 for (
auto& img:imagesToCheck)
413 if (std::abs(optPano.
getImage(img).getPitch()) < 50)
415 imagesToProcess.push_back(img);
423 for (HuginBase::UIntSet::const_iterator it = cmdlineImages.begin(); it != cmdlineImages.end(); ++it)
427 imagesToProcess.push_back(*it);
432 if(imagesToProcess.empty())
434 std::cerr <<
"No image to process found" << std::endl <<
"Stopping processing" << std::endl;
443 std::string s=vigra::impexListExtensions();
447 #pragma omp parallel for schedule(dynamic)
448 for(
int i=0; i < imagesToProcess.size(); ++i)
450 const size_t imgNr = imagesToProcess[i];
451 std::ostringstream buf;
452 buf <<
"Working on image " << pano.
getImage(imgNr).getFilename() << std::endl;
453 std::cout << buf.str();
455 vigra::ImageImportInfo
info(pano.
getImage(imgNr).getFilename().c_str());
457 if(
info.isGrayscale())
470 std::cerr <<
"Image " << pano.
getImage(imgNr).getFilename().c_str() <<
" has "
471 <<
info.numBands() <<
" channels." << std::endl
472 <<
"Linefind works only with grayscale or color images." << std::endl
473 <<
"Skipping image." << std::endl;
476 if(!foundLines.empty())
478 for (HuginBase::CPVector::const_iterator cpIt = foundLines.begin(); cpIt != foundLines.end(); ++cpIt)
485 std::cout << std::endl <<
"Found " << pano.
getNrOfCtrlPoints() - nrCPS <<
" vertical lines" << std::endl << std::endl;
492 std::cout << std::endl <<
"Written output to " << output << std::endl;
static void swap(T &x, T &y)
double getMaxValForPixelType(const std::string &v)
std::vector< UIntSet > UIntSetVector
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.
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...
HuginBase::CPVector GetVerticalLines(const HuginBase::Panorama &pano, const unsigned int imgNr, vigra::UInt8RGBImage &image, vigra::BImage &mask, const unsigned int nrLines)
searches for vertical control points in given image
bool operator()(const size_t &img1, const size_t &img2)
ConstImageVariableGroup & getStacks()
Get the ImageVariableGroup representing the group of stack variables.
declaration of functions for finding lines
Somewhere to specify what variables belong to what.
std::size_t getNrOfCtrlPoints() const
number of control points
virtual void run()
runs the algorithm.
void applyMapping(vigra::triple< SrcIterator, SrcIterator, SrcAccessor > img, vigra::pair< DestIterator, DestAccessor > dest, T min, T max, int mapping)
SortVectorByExposure(const HuginBase::Panorama &pano)
virtual void updateVariables(const VariableMapVector &vars)
Set the variables.
functions to manage ROI's
static hugin_omp::Lock lock
Panorama duplicate() const
duplicate the panorama
std::set< unsigned int > UIntSet
std::vector< VariableMap > VariableMapVector
UIntSetVector getPartsSet() const
return a vector which contains a HuginBase::UIntSet for each group with the corresponding images numb...
unsigned int addCtrlPoint(const ControlPoint &point)
add a new control point.
std::string getPathPrefix(const std::string &filename)
Get the path to a filename.
vigra::BImage LoadGrayImageAndConvert(vigra::ImageImportInfo &info, vigra::BImage &mask)
VariableMapVector getVariables() const
get variables of this panorama
std::size_t getNrOfImages() const
number of images.
HuginBase::CPVector LoadImageAndFindLines(vigra::ImageImportInfo info, HuginBase::Panorama &pano, size_t imgNr, int nrLines)
std::vector< unsigned int > UIntVector
Map::mapped_type & map_get(Map &m, const typename Map::key_type &key)
get a map element.
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...
void convertToUInt8(SrcIMG &src, const std::string &origType, vigra::UInt8RGBImage &dest)
converts the given image to UInt8RGBImage only this image is correctly processed by linefind ...
Make an ImageVariableGroup for lenses and other common concepts.
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
!! from PTOptimise.h 1951
HuginBase::CPVector LoadGrayImageAndFindLines(vigra::ImageImportInfo info, HuginBase::Panorama &pano, size_t imgNr, int nrLines)
static int ptinfoDlg(int command, char *argument)
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...
vigra::UInt8RGBImage LoadImageAndConvert(vigra::ImageImportInfo &info, vigra::BImage &mask)
std::string GetHuginVersion()
return a string with version numbers
std::vector< ControlPoint > CPVector
const HuginBase::Panorama & m_pano
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
void convertGrayToUInt8(SrcIMG &src, const std::string &origType, vigra::BImage &dest)
static int ptProgress(int command, char *argument)
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[])