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")
88 vigra::RGBToGrayAccessor<vigra::RGBValue<float> > ga;
89 vigra::FindMinMax<float> minmax;
92 double minVal = minmax.min;
93 double maxVal = minmax.max;
103 template <
class SrcIMG>
106 dest.resize(src.size());
109 if (origType ==
"FLOAT" || origType ==
"DOUBLE")
114 vigra::FindMinMax<float> minmax;
116 double minVal = minmax.min;
117 double maxVal = minmax.max;
127 template <
class SrcIMG>
131 SrcIMG imageIn(info.width(),info.height());
132 if(info.numExtraBands()==1)
134 mask.resize(info.width(), info.height());
146 template <
class SrcIMG>
149 vigra::UInt8RGBImage image;
150 SrcIMG imageIn(info.width(),info.height());
151 if(info.numExtraBands()==1)
153 mask.resize(info.width(), info.height());
171 std::string pixelType=info.getPixelType();
172 if(pixelType==
"UINT8")
174 image.resize(info.width(),info.height());
175 if(info.numExtraBands()==1)
177 mask.resize(info.width(), info.height());
187 if(pixelType==
"UINT16" || pixelType==
"INT16")
189 image=LoadGrayImageAndConvert<vigra::UInt16Image>(
info, mask);
193 if(pixelType==
"INT32" || pixelType==
"UINT32")
195 image=LoadGrayImageAndConvert<vigra::UInt32Image>(
info, mask);
199 if(pixelType==
"FLOAT" || pixelType==
"DOUBLE")
201 image=LoadGrayImageAndConvert<vigra::FImage>(
info, mask);
205 std::cerr <<
"Unsupported pixel type" << std::endl;
210 if(image.width()>0 && image.height()>0)
220 vigra::UInt8RGBImage image;
223 std::string pixelType=info.getPixelType();
224 if(pixelType==
"UINT8")
226 image.resize(info.width(),info.height());
227 if(info.numExtraBands()==1)
229 mask.resize(info.width(), info.height());
239 if(pixelType==
"UINT16" || pixelType==
"INT16")
241 image=LoadImageAndConvert<vigra::UInt16RGBImage>(
info, mask);
245 if(pixelType==
"INT32" || pixelType==
"UINT32")
247 image=LoadImageAndConvert<vigra::UInt32RGBImage>(
info, mask);
251 if(pixelType==
"FLOAT" || pixelType==
"DOUBLE")
253 image=LoadImageAndConvert<vigra::FRGBImage>(
info, mask);
257 std::cerr <<
"Unsupported pixel type" << std::endl;
262 if(image.width()>0 && image.height()>0)
282 int main(
int argc,
char* argv[])
285 const char* optstring =
"o:i:l:h";
287 static struct option longOptions[] =
289 {
"output", required_argument, NULL,
'o' },
290 {
"image", required_argument, NULL,
'i' },
291 {
"lines", required_argument, NULL,
'l' },
292 {
"help", no_argument, NULL,
'h' },
300 while ((c = getopt_long (argc, argv, optstring, longOptions,
nullptr)) != -1)
312 int imgNr=atoi(optarg);
313 if((imgNr==0) && (strcmp(optarg,
"0")!=0))
318 cmdlineImages.insert(imgNr);
322 nrLines=atoi(optarg);
340 if (argc - optind != 1)
342 if (argc - optind < 1)
354 std::string input=argv[optind];
366 std::vector<size_t> imagesToProcess;
367 if(cmdlineImages.empty())
373 for (
size_t imgGroup = 0; imgGroup < imageGroups.size(); ++imgGroup)
376 if (pano.
getImage(stackImages[0]).YawisLinked())
381 if (pano.
getImage(*(stackImages.begin())).getExposureValue() != pano.
getImage(*(stackImages.rbegin())).getExposureValue())
383 index = stackImages.size() / 2;
385 imagesToProcess.push_back(stackImages[index]);
390 std::copy(stackImages.begin(), stackImages.end(), std::back_inserter(imagesToProcess));
401 for (
size_t i = 0; i < varMapVec.size(); i++)
403 map_get(varMapVec[i],
"TrX").setValue(0);
404 map_get(varMapVec[i],
"TrY").setValue(0);
405 map_get(varMapVec[i],
"TrZ").setValue(0);
410 std::vector<size_t> imagesToCheck;
411 std::swap(imagesToProcess, imagesToCheck);
412 for (
auto& img:imagesToCheck)
415 if (std::abs(optPano.
getImage(img).getPitch()) < 50)
417 imagesToProcess.push_back(img);
425 for (HuginBase::UIntSet::const_iterator it = cmdlineImages.begin(); it != cmdlineImages.end(); ++it)
429 imagesToProcess.push_back(*it);
434 if(imagesToProcess.empty())
436 std::cerr <<
"No image to process found" << std::endl <<
"Stopping processing" << std::endl;
445 std::string s=vigra::impexListExtensions();
449 #pragma omp parallel for schedule(dynamic)
450 for(
int i=0; i < imagesToProcess.size(); ++i)
452 const size_t imgNr = imagesToProcess[i];
453 std::ostringstream buf;
454 buf <<
"Working on image " << pano.
getImage(imgNr).getFilename() << std::endl;
455 std::cout << buf.str();
457 vigra::ImageImportInfo
info(pano.
getImage(imgNr).getFilename().c_str());
459 if(
info.isGrayscale())
472 std::cerr <<
"Image " << pano.
getImage(imgNr).getFilename().c_str() <<
" has "
473 <<
info.numBands() <<
" channels." << std::endl
474 <<
"Linefind works only with grayscale or color images." << std::endl
475 <<
"Skipping image." << std::endl;
478 if(!foundLines.empty())
480 for (HuginBase::CPVector::const_iterator cpIt = foundLines.begin(); cpIt != foundLines.end(); ++cpIt)
487 std::cout << std::endl <<
"Found " << pano.
getNrOfCtrlPoints() - nrCPS <<
" vertical lines" << std::endl << std::endl;
494 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[])