Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FindLines.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
8 /***************************************************************************
9  * Copyright (C) 2009 by Tim Nugent *
10  * timnugent@gmail.com *
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  * This program is distributed in the hope that it will be useful, *
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20  * GNU General Public License for more details. *
21  * *
22  * You should have received a copy of the GNU General Public License *
23  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
24  ***************************************************************************/
25 
26 #include "vigra/edgedetection.hxx"
27 #include "FindLines.h"
28 #include "FindN8Lines.h"
31 #include <nona/RemappedPanoImage.h>
34 
35 namespace HuginLines
36 {
37 
38 template <class SrcImageIterator, class SrcAccessor, class DestImage>
39 double resize_image(const vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, DestImage& dest, int resize_dimension)
40 {
41  // Re-size to max dimension
42  double sizefactor=1.0;
43  const vigra::Size2D inputSize(src.second - src.first);
44  if (inputSize.width() > resize_dimension || inputSize.height() > resize_dimension)
45  {
46  int nw;
47  int nh;
48  if (inputSize.width() >= inputSize.height())
49  {
50  sizefactor = (double)resize_dimension / inputSize.width();
51  // calculate new image size
52  nw = resize_dimension;
53  nh = static_cast<int>(0.5 + (sizefactor*inputSize.height()));
54  }
55  else
56  {
57  sizefactor = (double)resize_dimension / inputSize.height();
58  // calculate new image size
59  nw = static_cast<int>(0.5 + (sizefactor*inputSize.width()));
60  nh = resize_dimension;
61  }
62 
63  // create an image of appropriate size
64  dest.resize(nw, nh);
65  // resize the image, using a bi-cubic spline algorithm
66  resizeImageNoInterpolation(src, destImageRange(dest));
67  }
68  else
69  {
70  dest.resize(inputSize);
71  copyImage(src, destImage(dest));
72  };
73  return 1.0/sizefactor;
74 }
75 
76 vigra::BImage* detectEdges(const vigra::UInt8RGBImage& input, const double scale, const double threshold, const unsigned int resize_dimension, double& size_factor)
77 {
78  // Resize image
79  vigra::UInt8Image scaled;
80  size_factor = resize_image(vigra::srcImageRange(input, vigra::RGBToGrayAccessor<vigra::RGBValue<vigra::UInt8> >()), scaled, resize_dimension);
81 
82  // Run Canny edge detector
83  vigra::BImage* image = new vigra::BImage(scaled.width(), scaled.height(), 255);
84  vigra::cannyEdgeImage(vigra::srcImageRange(scaled), vigra::destImage(*image), scale, threshold, 0);
85  return image;
86 };
87 
88 vigra::BImage* detectEdges(const vigra::BImage& input, const double scale, const double threshold, const unsigned int resize_dimension, double& size_factor)
89 {
90  // Resize image
91  vigra::UInt8Image scaled;
92  size_factor=resize_image(vigra::srcImageRange(input), scaled, resize_dimension);
93 
94  // Run Canny edge detector
95  vigra::BImage* image = new vigra::BImage(scaled.width(), scaled.height(), 255);
96  vigra::cannyEdgeImage(vigra::srcImageRange(scaled), vigra::destImage(*image), scale, threshold, 0);
97  return image;
98 };
99 
100 double calculate_focal_length_pixels(double focal_length,double cropFactor,double width, double height)
101 {
102  double pixels_per_mm = 0;
103  if (cropFactor > 1)
104  {
105  pixels_per_mm= (cropFactor/24.0)* ((width>height)?height:width);
106  }
107  else
108  {
109  pixels_per_mm= (24.0/cropFactor)* ((width>height)?height:width);
110  }
111  return focal_length*pixels_per_mm;
112 }
113 
114 
115 Lines findLines(vigra::BImage& edge, double length_threshold, double focal_length,double crop_factor)
116 {
117  unsigned int longest_dimension=(edge.width() > edge.height()) ? edge.width() : edge.height();
118  double min_line_length_squared=(length_threshold*longest_dimension)*(length_threshold*longest_dimension);
119 
120  int lmin = int(sqrt(min_line_length_squared));
121  double flpix=calculate_focal_length_pixels(focal_length,crop_factor,edge.width(),edge.height());
122 
123  vigra::BImage lineImage = edgeMap2linePts(edge);
124  Lines lines;
125  linePts2lineList( lineImage, lmin, flpix, lines );
126 
127  return lines;
128 };
129 
130 void ScaleLines(Lines& lines,const double scale)
131 {
132  for(unsigned int i=0; i<lines.size(); i++)
133  {
134  for(unsigned int j=0; j<lines[i].line.size(); j++)
135  {
136  lines[i].line[j]*=scale;
137  };
138  };
139 };
140 
141 HuginBase::CPVector GetControlPoints(const SingleLine& line,const unsigned int imgNr, const unsigned int lineNr,const unsigned int numberOfCtrlPoints)
142 {
144  double interval = (line.line.size()-1)/(1.0*numberOfCtrlPoints);
145  for(unsigned int k = 0; k < numberOfCtrlPoints; k++)
146  {
147  int start = (int)(k * interval);
148  int stop = (int)((k+1) * interval);
149  HuginBase::ControlPoint cp(imgNr,line.line[start].x, line.line[start].y,
150  imgNr,line.line[stop].x, line.line[stop].y,lineNr);
151  cpv.push_back(cp);
152  };
153  return cpv;
154 };
155 
156 #define MAX_RESIZE_DIM 1600
157 
158 //return footpoint of point p on line between point p1 and p2
159 vigra::Point2D GetFootpoint(const vigra::Point2D& p, const vigra::Point2D& p1, const vigra::Point2D& p2, double& u)
160 {
161  hugin_utils::FDiff2D diff = p2 - p1;
162  u = ((p.x - p1.x)*(p2.x - p1.x) + (p.y - p1.y)*(p2.y - p1.y)) / hugin_utils::sqr(hugin_utils::norm(diff));
163  diff *= u;
164  return vigra::Point2D(p1.x + diff.x, p1.y + diff.y);
165 };
166 
167 vigra::Point2D GetFootpoint(const vigra::Point2D& p, const vigra::Point2D& p1, const vigra::Point2D& p2)
168 {
169  double u;
170  return GetFootpoint(p, p1, p2, u);
171 };
172 
174 {
175 public:
176  void SetStart(const vigra::Point2D point)
177  {
178  m_start = point;
179  };
180  void SetStart(const int x, const int y)
181  {
182  m_start = vigra::Point2D(x, y);
183  };
184  void SetEnd(const vigra::Point2D point)
185  {
186  m_end = point;
187  };
188  void SetEnd(const int x, const int y)
189  {
190  m_end = vigra::Point2D(x, y);
191  };
192  double GetLineLength() const
193  {
194  return (m_end - m_start).magnitude();
195  };
196  double GetEstimatedDistance(const VerticalLine& otherLine) const
197  {
198  auto getDist = [](const vigra::Point2D& p, const vigra::Point2D& p1, const vigra::Point2D& p2)->double
199  {
200  double t;
201  const vigra::Point2D endPoint = GetFootpoint(p, p1, p2, t);
202  if (-0.1 < t && t < 1.1)
203  {
204  return (endPoint - p).magnitude();
205  }
206  else
207  {
208  return DBL_MAX;
209  };
210  };
211  return std::min({getDist(otherLine.GetStart(), m_start, m_end), getDist(otherLine.GetEnd(), m_start, m_end),
212  getDist(m_start, otherLine.GetStart(), otherLine.GetEnd()), getDist(m_end, otherLine.GetStart(), otherLine.GetEnd())});
213  }
214  double GetAngle() const
215  {
216  return atan2(m_end.y - m_start.y, m_end.x - m_start.x);
217  };
218  const vigra::Point2D& GetStart() const
219  {
220  return m_start;
221  };
222  const vigra::Point2D& GetEnd() const
223  {
224  return m_end;
225  };
226 private:
227  vigra::Point2D m_start;
228  vigra::Point2D m_end;
229 };
230 
231 typedef std::vector<VerticalLine> VerticalLineVector;
232 
233 //linear fit of given line, returns endpoints of fitted line
235 {
236  size_t n=line.line.size();
237  VerticalLine vl;
238  double s_x=0;
239  double s_y=0;
240  double s_xy=0;
241  double s_x2=0;
242  for(size_t i=0;i<n;i++)
243  {
244  s_x+=(double)line.line[i].x/n;
245  s_y+=(double)line.line[i].y/n;
246  s_xy+=(double)line.line[i].x*line.line[i].y/n;
247  s_x2+=(double)line.line[i].x*line.line[i].x/n;
248  };
249  if(std::abs(s_x2-s_x*s_x)<0.00001)
250  {
251  //vertical line needs special treatment
252  vl.SetStart(s_x, line.line[0].y);
253  vl.SetEnd(s_x, line.line[n - 1].y);
254  }
255  else
256  {
257  //calculate slope and offset
258  double slope=(s_xy-s_x*s_y)/(s_x2-s_x*s_x);
259  double offset=s_y-slope*s_x;
260  //convert to parametric form
261  vigra::Point2D p1(0,offset);
262  vigra::Point2D p2(100,100*slope+offset);
263  //calculate footpoint of first and last point
264  vl.SetStart(GetFootpoint(line.line[0], p1, p2));
265  vl.SetEnd(GetFootpoint(line.line[n - 1], p1, p2));
266  };
267  return vl;
268 };
269 
270 //filter detected lines
271 //return fitted lines which have only a small deviation from the vertical
273 {
274  VerticalLineVector vertLines;
275  if(!lines.empty())
276  {
277  for(Lines::const_iterator it=lines.begin(); it!=lines.end(); ++it)
278  {
279  if((*it).status==valid_line && (*it).line.size()>2)
280  {
281  VerticalLine vl=FitLine(*it);
282  const vigra::Diff2D diff = vl.GetEnd() - vl.GetStart();
283  // check that line is long enough
284  if(diff.magnitude()>20)
285  {
286  // now check angle with respect to roll angle, accept only deviation of 5° (sin 5°=0.1)
287  if(std::abs((diff.x*cos(DEG_TO_RAD(roll))+diff.y*sin(DEG_TO_RAD(roll)))/diff.magnitude())<0.1)
288  {
289  // check distance and angle to other lines
290  bool distanceBig = true;
291  for (auto& otherLine : vertLines)
292  {
293  // distance should be at least 80 pixel = 5 % from image width
294  if (vl.GetEstimatedDistance(otherLine) < 80)
295  {
296  // now check if line are parallel = have the same angle (tan(3°)=0.05)
297  if (std::abs(vl.GetAngle() - otherLine.GetAngle()) < 0.05)
298  {
299  distanceBig = false;
300  // both lines are close to each other, keep only the longer one
301  if (vl.GetLineLength() > otherLine.GetLineLength())
302  {
303  otherLine = vl;
304  }
305  continue;
306  };
307  };
308  }
309  if (distanceBig)
310  {
311  vertLines.push_back(vl);
312  };
313  };
314  };
315  };
316  };
317  };
318  return vertLines;
319 };
320 
321 //function to sort HuginBase::CPVector by error distance
323 {
324  return cp1.error<cp2.error;
325 };
326 
328 {
329 public:
330  typedef vigra::UInt8 value_type;
331  template <class ITERATOR>
332  value_type operator()(ITERATOR const & i) const
333  {
334  return 255 - (*i);
335  }
336  template <class ITERATOR, class DIFFERENCE>
337  value_type operator()(ITERATOR const & i, DIFFERENCE d) const
338  {
339  return 255 - i[d];
340  }
341 };
342 
343 template <class ImageType>
344 HuginBase::CPVector _getVerticalLines(const HuginBase::Panorama& pano,const unsigned int imgNr,ImageType& image, vigra::BImage& mask, const unsigned int nrLines)
345 {
346  HuginBase::CPVector verticalLines;
347  HuginBase::CPVector detectedLines;
348  const HuginBase::SrcPanoImage& srcImage=pano.getImage(imgNr);
349  bool needsRemap=srcImage.getProjection()!=HuginBase::SrcPanoImage::RECTILINEAR;
350  double roll=(needsRemap?0:srcImage.getRoll());
351  double size_factor=1.0;
352  HuginBase::SrcPanoImage remappedImage;
354  vigra::BImage* edge;
355  if(!needsRemap)
356  {
357  //rectilinear image can be used as is
358  //detect edges
359  edge=detectEdges(image,2,4,MAX_RESIZE_DIM,size_factor);
360  }
361  else
362  {
363  //remap all other image to equirectangular
364  //create temporary SrcPanoImage, set appropriate image variables
365  remappedImage=pano.getSrcImage(imgNr);
366  remappedImage.setYaw(0);
367  remappedImage.setPitch(0);
368  remappedImage.setX(0);
369  remappedImage.setY(0);
370  remappedImage.setZ(0);
371  remappedImage.setExposureValue(0);
372  remappedImage.setEMoRParams(std::vector<float>(5, 0.0));
373  remappedImage.deleteAllMasks();
374  remappedImage.setActive(true);
375  //create PanoramaOptions for remapping of image
377  opts.setWidth(MAX_RESIZE_DIM);
378  opts.outputExposureValue=0;
379  //calculate output canvas size
380  HuginBase::Panorama tempPano;
381  tempPano.addImage(remappedImage);
382  tempPano.setOptions(opts);
383 
384  HuginBase::CalculateFitPanorama fitPano(tempPano);
385  fitPano.run();
386  opts.setHFOV(fitPano.getResultHorizontalFOV());
388  if (opts.getVFOV() > 100)
389  {
390  // limit vertical fov to 100 deg to prevent finding lines
391  // near nadir/zenit which are probably wrong with this simple
392  // line finding algorithmus
393  opts.setHeight(hugin_utils::roundi(opts.getHeight() * 90.0 / opts.getVFOV()));
394  };
395  tempPano.setOptions(opts);
396 
397  //finally remap image
400  remapped->setPanoImage(remappedImage,opts,opts.getROI());
401  if (mask.size().area() > 0)
402  {
403  remapped->remapImage(vigra::srcImageRange(image), vigra::srcImage(mask), vigra_ext::INTERP_CUBIC, progress);
404  }
405  else
406  {
407  remapped->remapImage(vigra::srcImageRange(image), vigra_ext::INTERP_CUBIC, progress);
408  };
409  ImageType remappedBitmap=remapped->m_image;
410  mask = remapped->m_mask;
411  //detect edges
412  edge=detectEdges(remappedBitmap,2,4,std::max(remappedBitmap.width(),remappedBitmap.height())+10,size_factor);
413  delete remapped;
414  delete progress;
415  };
416  // ignore all edges outside of masked areas
417  if (mask.size().area() > 0)
418  {
419  vigra::initImageIf(vigra::destImageRange(*edge), vigra::srcImage(mask, InvertedMaskAccessor()), vigra::UInt8(255));
420  };
421  //detect lines
422  //we need the focal length
423  double focalLength=srcImage.getExifFocalLength();
424  if(focalLength==0)
425  {
427  srcImage.getProjection(),srcImage.getHFOV(),srcImage.getCropFactor(),srcImage.getSize());
428  };
429  Lines foundLines=findLines(*edge,0.05,focalLength,srcImage.getCropFactor());
430  delete edge;
431  //filter results
432  VerticalLineVector filteredLines=FilterLines(foundLines,roll);
433  //create control points
434  if(!filteredLines.empty())
435  {
436  //we need to transform the coordinates to image coordinates because the detection
437  //worked on smaller images or in remapped image
439  if(needsRemap)
440  {
441  transform.createTransform(remappedImage,opts);
442  };
443  for(size_t i=0; i<filteredLines.size(); i++)
444  {
446  cp.image1Nr=0;
447  cp.image2Nr=0;
449  if(!needsRemap)
450  {
451  cp.x1 = filteredLines[i].GetStart().x*size_factor;
452  cp.y1 = filteredLines[i].GetStart().y*size_factor;
453  cp.x2 = filteredLines[i].GetEnd().x*size_factor;
454  cp.y2 = filteredLines[i].GetEnd().y*size_factor;
455  }
456  else
457  {
458  double xout;
459  double yout;
460  if(!transform.transformImgCoord(xout,yout,filteredLines[i].GetStart().x,filteredLines[i].GetStart().y))
461  {
462  continue;
463  };
464  cp.x1=xout;
465  cp.y1=yout;
466  if(!transform.transformImgCoord(xout,yout,filteredLines[i].GetEnd().x,filteredLines[i].GetEnd().y))
467  {
468  continue;
469  };
470  cp.x2=xout;
471  cp.y2=yout;
472  };
473  if(cp.x1>=0 && cp.x1<srcImage.getWidth() && cp.y1>=0 && cp.y1<srcImage.getHeight() &&
474  cp.x2>=0 && cp.x2<srcImage.getWidth() && cp.y2>=0 && cp.y2<srcImage.getHeight())
475  {
476  detectedLines.push_back(cp);
477  };
478  };
479  //now a final check of the found vertical lines
480  //we optimize the pano with a single image and disregard vertical lines with bigger errors
481  //we need at least 2 lines
482  if(detectedLines.size()>1)
483  {
484  HuginBase::Panorama tempPano;
485  HuginBase::SrcPanoImage tempImage=pano.getSrcImage(imgNr);
486  tempImage.setYaw(0);
487  tempImage.setPitch(0);
488  tempImage.setRoll(0);
489  tempImage.setX(0);
490  tempImage.setY(0);
491  tempImage.setZ(0);
492  tempPano.addImage(tempImage);
493  for(size_t i=0; i<detectedLines.size(); i++)
494  {
495  tempPano.addCtrlPoint(detectedLines[i]);
496  };
499  tempPano.setOptions(opt2);
501  std::set<std::string> imgopt;
502  imgopt.insert("p");
503  imgopt.insert("r");
504  optVec.push_back(imgopt);
505  tempPano.setOptimizeVector(optVec);
506  // ARGH the panotools optimizer uses global variables is not reentrant
507 #pragma omp critical
508  {
509  HuginBase::PTools::optimize(tempPano);
510  }
511  //first filter stage
512  //we disregard all lines with big error
513  //calculate statistic and determine limit
514  double minError,maxError,mean,var;
515  HuginBase::CalculateCPStatisticsError::calcCtrlPntsErrorStats(tempPano,minError,maxError,mean,var);
516  detectedLines=tempPano.getCtrlPoints();
517  double limit=mean+sqrt(var);
518  maxError=0;
519  for(int i=detectedLines.size()-1; i>=0; i--)
520  {
521  if(detectedLines[i].error>limit)
522  {
523  detectedLines.erase(detectedLines.begin()+i);
524  }
525  else
526  {
527  //we need the max error of the remaining lines for the next step
528  maxError=std::max(detectedLines[i].error,maxError);
529  };
530  };
531  if(!detectedLines.empty() && maxError>0) //security check, should never be false
532  {
533  //now keep only the best nrLines lines
534  //we are using error and line length as figure of merrit
535  for(size_t i=0;i<detectedLines.size();i++)
536  {
537  double length=sqrt(hugin_utils::sqr(detectedLines[i].x2-detectedLines[i].x1)+hugin_utils::sqr(detectedLines[i].y2-detectedLines[i].y1));
538  //calculate number of merrit
539  detectedLines[i].error=detectedLines[i].error/maxError+(1.0-std::min(length,500.0)/500.0);
540  };
541  std::sort(detectedLines.begin(),detectedLines.end(),SortByError);
542  //only save best nrLines control points
543  for(size_t i=0;i<detectedLines.size() && i<nrLines; i++)
544  {
545  HuginBase::ControlPoint cp=detectedLines[i];
546  cp.image1Nr=imgNr;
547  cp.image2Nr=imgNr;
548  cp.error=0;
549  verticalLines.push_back(cp);
550  };
551  };
552  }
553  else
554  {
555  //if only one line was detected we do a special check
556  //the allow deviation between line and roll angle is checked more narrow than in the first check
557  if(detectedLines.size()==1)
558  {
559  vigra::Diff2D diff((double)detectedLines[0].x2-detectedLines[0].x1,(double)detectedLines[0].y2-detectedLines[0].y1);
560  if(std::abs((diff.x*cos(DEG_TO_RAD(roll))+diff.y*sin(DEG_TO_RAD(roll)))/diff.magnitude())<0.05)
561  {
562  HuginBase::ControlPoint cp=detectedLines[0];
563  cp.image1Nr=imgNr;
564  cp.image2Nr=imgNr;
565  cp.error=0;
566  verticalLines.push_back(cp);
567  };
568  };
569  };
570  };
571  return verticalLines;
572 };
573 
574 HuginBase::CPVector GetVerticalLines(const HuginBase::Panorama& pano,const unsigned int imgNr,vigra::UInt8RGBImage& image, vigra::BImage& mask, const unsigned int nrLines)
575 {
576  return _getVerticalLines(pano, imgNr, image, mask, nrLines);
577 };
578 
579 HuginBase::CPVector GetVerticalLines(const HuginBase::Panorama& pano,const unsigned int imgNr,vigra::BImage& image, vigra::BImage& mask, const unsigned int nrLines)
580 {
581  return _getVerticalLines(pano, imgNr, image, mask, nrLines);
582 };
583 
584 }; //namespace
AlphaImage m_mask
corresponding alpha channel
Definition: ROIImage.h:274
std::vector< vigra::Point2D > line
Definition: LinesTypes.h:45
#define MAX_RESIZE_DIM
Definition: FindLines.cpp:156
Dummy progress display, without output.
double norm(T t)
Definition: hugin_math.h:175
vigra::Point2D m_end
Definition: FindLines.cpp:228
const vigra::Point2D & GetEnd() const
Definition: FindLines.cpp:222
void setHeight(unsigned int h)
set panorama height
int roundi(T x)
Definition: hugin_math.h:73
void setPanoImage(const SrcPanoImage &src, const PanoramaOptions &dest, vigra::Rect2D roi)
VerticalLine FitLine(SingleLine line)
Definition: FindLines.cpp:234
SrcPanoImage getSrcImage(unsigned imgNr) const
get a description of a source image
Definition: Panorama.cpp:1620
void SetStart(const vigra::Point2D point)
Definition: FindLines.cpp:176
double calculate_focal_length_pixels(double focal_length, double cropFactor, double width, double height)
Definition: FindLines.cpp:100
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
Definition: FindLines.cpp:574
declaration of functions for finding lines
const vigra::Point2D & GetStart() const
Definition: FindLines.cpp:218
unsigned int getHeight() const
get panorama height
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)
void ScaleLines(Lines &lines, const double scale)
scales the given lines with given factor use in conjugation with HuginLines::detectEdges to scale the...
Definition: FindLines.cpp:130
Contains functions to transform whole images.
double resize_image(const vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, DestImage &dest, int resize_dimension)
Definition: FindLines.cpp:39
T sqr(T t)
Definition: hugin_math.h:169
std::vector< VerticalLine > VerticalLineVector
Definition: FindLines.cpp:231
vigra::Point2D GetFootpoint(const vigra::Point2D &p, const vigra::Point2D &p1, const vigra::Point2D &p2, double &u)
Definition: FindLines.cpp:159
a single line extracted from image
Definition: LinesTypes.h:43
virtual void run()
runs the algorithm.
static char * line
Definition: svm.cpp:2784
const CPVector & getCtrlPoints() const
get all control point of this Panorama
Definition: Panorama.h:319
int getHeight() const
Get the height of the image in pixels.
Definition: SrcPanoImage.h:276
vigra::pair< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImage(const ROIImage< Image, Mask > &img)
Definition: ROIImage.h:300
Lines findLines(vigra::BImage &edge, double length_threshold, double focal_length, double crop_factor)
find straightish non-crossing lines find straightish non-crossing lines in an edge map using 8-neighb...
Definition: FindLines.cpp:115
value_type operator()(ITERATOR const &i) const
Definition: FindLines.cpp:332
represents a control point
Definition: ControlPoint.h:38
void setOptimizeVector(const OptimizeVector &optvec)
set optimize setting
Definition: Panorama.cpp:297
double GetEstimatedDistance(const VerticalLine &otherLine) const
Definition: FindLines.cpp:196
const vigra::Rect2D & getROI() const
Model for a panorama.
Definition: Panorama.h:152
unsigned int addCtrlPoint(const ControlPoint &point)
add a new control point.
Definition: Panorama.cpp:381
HuginBase::CPVector GetControlPoints(const SingleLine &line, const unsigned int imgNr, const unsigned int lineNr, const unsigned int numberOfCtrlPoints)
returns a HuginBase::CPVector with cps_per_lines
Definition: FindLines.cpp:141
vigra::FRGBImage ImageType
int getWidth() const
Get the width of the image in pixels.
Definition: SrcPanoImage.h:266
void remapImage(vigra::triple< ImgIter, ImgIter, ImgAccessor > srcImg, vigra_ext::Interpolator interpol, AppBase::ProgressDisplay *progress, bool singleThreaded=false)
remap a image without alpha channel
double GetAngle() const
Definition: FindLines.cpp:214
virtual double getResultHeight()
Definition: FitPanorama.h:75
void deleteAllMasks()
delete all masks
declaration of find lines algorithm
vigra::Point2D m_start
Definition: FindLines.cpp:225
evaluate x, points are on a vertical line
Definition: ControlPoint.h:47
VerticalLineVector FilterLines(Lines lines, double roll)
Definition: FindLines.cpp:272
double GetLineLength() const
Definition: FindLines.cpp:192
static double calcFocalLength(SrcPanoImage::Projection proj, double hfov, double crop, vigra::Size2D imageSize)
calcualte focal length, given crop factor and hfov
vigra::pair< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImage(ROIImage< Image, Alpha > &img)
Definition: ROIImage.h:324
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
Definition: ROIImage.h:287
vigra::BImage * detectEdges(const vigra::UInt8RGBImage &input, const double scale, const double threshold, const unsigned int resize_dimension, double &size_factor)
detect and mark edges in an edge image using Canny&#39;s algorithm
Definition: FindLines.cpp:76
!! from PTOptimise.h 1951
unsigned int addImage(const SrcPanoImage &img)
the the number for a specific image
Definition: Panorama.cpp:319
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.
Definition: threshold.h:41
void setHFOV(double h, bool keepView=true)
set the horizontal field of view.
bool transformImgCoord(double &x_dest, double &y_dest, double x_src, double y_src) const
like transform, but return image coordinates, not cartesian coordinates
virtual double getResultHorizontalFOV()
Definition: FitPanorama.h:68
void SetEnd(const int x, const int y)
Definition: FindLines.cpp:188
void SetEnd(const vigra::Point2D point)
Definition: FindLines.cpp:184
std::vector< SingleLine > Lines
vector of extracted lines from image
Definition: LinesTypes.h:50
static T max(T x, T y)
Definition: svm.cpp:65
void SetStart(const int x, const int y)
Definition: FindLines.cpp:180
Holds transformations for Image -&gt; Pano and the other way.
unsigned int optimize(PanoramaData &pano, const char *userScript)
optimize the images imgs, for variables optvec, using vars as start.
std::vector< ControlPoint > CPVector
Definition: ControlPoint.h:99
vigra::triple< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImageRange(ROIImage< Image, Alpha > &img)
Definition: ROIImage.h:312
#define DEG_TO_RAD(x)
Definition: hugin_math.h:44
void copyImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc)
Definition: openmp_vigra.h:305
std::vector< std::set< std::string > > OptimizeVector
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition: Panorama.h:211
void setOptions(const PanoramaOptions &opt)
set new output settings This is not used directly for optimizing/stiching, but it can be feed into ru...
Definition: Panorama.cpp:1531
value_type operator()(ITERATOR const &i, DIFFERENCE d) const
Definition: FindLines.cpp:337
All variables of a source image.
Definition: SrcPanoImage.h:194
void setProjection(ProjectionFormat f)
set the Projection format and adjust the hfov/vfov if nessecary
Panorama image options.
struct to hold a image state for stitching
static T min(T x, T y)
Definition: svm.cpp:62
int linePts2lineList(vigra::BImage &img, int minsize, double flpix, Lines &lines)
converts a linePts image to a list of lines
void createTransform(const vigra::Diff2D &srcSize, VariableMap srcVars, Lens::LensProjectionFormat srcProj, const vigra::Diff2D &destSize, PanoramaOptions::ProjectionFormat destProj, const std::vector< double > &destProjParam, double destHFOV, const vigra::Diff2D &origSrcSize)
initialize pano-&gt;image transformation
void setWidth(unsigned int w, bool keepView=true)
set panorama width keep the HFOV, if keepView=true
HuginBase::CPVector _getVerticalLines(const HuginBase::Panorama &pano, const unsigned int imgNr, ImageType &image, vigra::BImage &mask, const unsigned int nrLines)
Definition: FindLines.cpp:344
vigra::BImage edgeMap2linePts(vigra::BImage &input)
marks line point
Definition: FindN8Lines.cpp:43
bool SortByError(const HuginBase::ControlPoint &cp1, const HuginBase::ControlPoint &cp2)
Definition: FindLines.cpp:322