26 #include "vigra/edgedetection.hxx" 
   38 template <
class SrcImageIterator, 
class SrcAccessor, 
class DestImage>
 
   39 double resize_image(
const vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, DestImage& dest, 
int resize_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)
 
   48         if (inputSize.width() >= inputSize.height())
 
   50             sizefactor = (double)resize_dimension / inputSize.width();
 
   52             nw = resize_dimension;
 
   53             nh = 
static_cast<int>(0.5 + (sizefactor*inputSize.height()));
 
   57             sizefactor = (double)resize_dimension / inputSize.height();
 
   59             nw = 
static_cast<int>(0.5 + (sizefactor*inputSize.width()));
 
   60             nh = resize_dimension;
 
   70         dest.resize(inputSize);
 
   73     return 1.0/sizefactor;
 
   76 vigra::BImage* 
detectEdges(
const vigra::UInt8RGBImage& input, 
const double scale, 
const double threshold, 
const unsigned int resize_dimension, 
double& size_factor)
 
   79     vigra::UInt8Image scaled;
 
   83     vigra::BImage* image = 
new vigra::BImage(scaled.width(), scaled.height(), 255);
 
   88 vigra::BImage* 
detectEdges(
const vigra::BImage& input, 
const double scale, 
const double threshold, 
const unsigned int resize_dimension, 
double& size_factor)
 
   91     vigra::UInt8Image scaled;
 
   95     vigra::BImage* image = 
new vigra::BImage(scaled.width(), scaled.height(), 255);
 
  102     double pixels_per_mm = 0;
 
  105         pixels_per_mm= (cropFactor/24.0)* ((width>height)?height:width);
 
  109         pixels_per_mm= (24.0/cropFactor)* ((width>height)?height:width);
 
  111     return focal_length*pixels_per_mm;
 
  115 Lines findLines(vigra::BImage& edge, 
double length_threshold, 
double focal_length,
double crop_factor)
 
  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);
 
  120     int lmin = int(sqrt(min_line_length_squared));
 
  132     for(
unsigned int i=0; i<lines.size(); i++)
 
  134         for(
unsigned int j=0; j<lines[i].line.size(); j++)
 
  136             lines[i].line[j]*=scale;
 
  144     double interval = (line.
line.size()-1)/(1.0*numberOfCtrlPoints);
 
  145     for(
unsigned int k = 0; k < numberOfCtrlPoints; k++)
 
  147         int start = (int)(k * interval);
 
  148         int stop =  (int)((k+1) * interval);
 
  150                                    imgNr,line.
line[stop].x, line.
line[stop].y,lineNr);
 
  156 #define MAX_RESIZE_DIM 1600 
  159 vigra::Point2D 
GetFootpoint(
const vigra::Point2D& p, 
const vigra::Point2D& p1, 
const vigra::Point2D& p2, 
double& u)
 
  164     return vigra::Point2D(p1.x + diff.
x, p1.y + diff.
y);
 
  167 vigra::Point2D 
GetFootpoint(
const vigra::Point2D& p, 
const vigra::Point2D& p1, 
const vigra::Point2D& p2)
 
  182         m_start = vigra::Point2D(x, y);
 
  190         m_end = vigra::Point2D(x, y);
 
  198         auto getDist = [](
const vigra::Point2D& p, 
const vigra::Point2D& p1, 
const vigra::Point2D& p2)->
double 
  201             const vigra::Point2D endPoint = 
GetFootpoint(p, p1, p2, t);
 
  202             if (-0.1 < t && t < 1.1)
 
  204                 return (endPoint - p).magnitude();
 
  240     size_t n=line.
line.size();
 
  246     for(
size_t i=0;i<n;i++)
 
  248         s_x+=(double)line.
line[i].x/n;
 
  249         s_y+=(
double)line.
line[i].y/n;
 
  250         s_xy+=(double)line.
line[i].x*line.
line[i].y/n;
 
  251         s_x2+=(
double)line.
line[i].x*line.
line[i].x/n;
 
  253     if(std::abs(s_x2-s_x*s_x)<0.00001)
 
  262         double slope=(s_xy-s_x*s_y)/(s_x2-s_x*s_x);
 
  263         double offset=s_y-slope*s_x;
 
  265         vigra::Point2D p1(0,offset);
 
  266         vigra::Point2D p2(100,100*slope+offset);
 
  281         for(Lines::const_iterator it=lines.begin(); it!=lines.end(); ++it)
 
  283             if((*it).status==
valid_line && (*it).line.size()>2)
 
  288                 if(diff.magnitude()>20)
 
  291                     if(!onlyVerticalLines || std::abs((diff.x*cos(
DEG_TO_RAD(roll))+diff.y*sin(
DEG_TO_RAD(roll)))/diff.magnitude())<0.1)
 
  294                         bool distanceBig = 
true;
 
  295                         for (
auto& otherLine : vertLines)
 
  301                                 if (std::abs(vl.
GetAngle() - otherLine.GetAngle()) < 0.05)
 
  315                             vertLines.push_back(vl);
 
  335     template <
class ITERATOR>
 
  340     template <
class ITERATOR, 
class DIFFERENCE>
 
  347 template <
class ImageType>
 
  354     double roll=(needsRemap?0:srcImage.getRoll());
 
  355     double size_factor=1.0;
 
  370         remappedImage.setYaw(0);
 
  371         remappedImage.setPitch(0);
 
  372         remappedImage.setX(0);
 
  373         remappedImage.setY(0);
 
  374         remappedImage.setZ(0);
 
  375         remappedImage.setExposureValue(0);
 
  376         remappedImage.setEMoRParams(std::vector<float>(5, 0.0));
 
  378         remappedImage.setActive(
true);
 
  405         if (mask.size().area() > 0)
 
  416         edge=
detectEdges(remappedBitmap,2,4,
std::max(remappedBitmap.width(),remappedBitmap.height())+10,size_factor);
 
  421     if (mask.size().area() > 0)
 
  427     double focalLength=srcImage.getExifFocalLength();
 
  431             srcImage.getProjection(),srcImage.getHFOV(),srcImage.getCropFactor(),srcImage.getSize());
 
  433     Lines foundLines=
findLines(*edge,0.05,focalLength,srcImage.getCropFactor());
 
  438     if(!filteredLines.empty())
 
  447         for(
size_t i=0; i<filteredLines.size(); i++)
 
  452             if (onlyVerticalLines)
 
  458                 if (std::abs(roll) < 45 || (roll > 135 && roll < 225) || roll > 315)
 
  469                 cp.
x1 = filteredLines[i].GetStart().x*size_factor;
 
  470                 cp.
y1 = filteredLines[i].GetStart().y*size_factor;
 
  471                 cp.
x2 = filteredLines[i].GetEnd().x*size_factor;
 
  472                 cp.
y2 = filteredLines[i].GetEnd().y*size_factor;
 
  478                 if(!transform.
transformImgCoord(xout,yout,filteredLines[i].GetStart().x,filteredLines[i].GetStart().y))
 
  484                 if(!transform.
transformImgCoord(xout,yout,filteredLines[i].GetEnd().x,filteredLines[i].GetEnd().y))
 
  494                 detectedLines.push_back(cp);
 
  500         if (onlyVerticalLines)
 
  503             if (detectedLines.size() > 1)
 
  508                 tempImage.setPitch(0);
 
  509                 tempImage.setRoll(0);
 
  514                 for (
size_t i = 0; i < detectedLines.size(); i++)
 
  522                 std::set<std::string> imgopt;
 
  525                 optVec.push_back(imgopt);
 
  535                 double minError, maxError, mean, var;
 
  538                 double limit = mean + sqrt(var);
 
  540                 for (
int i = detectedLines.size() - 1; i >= 0; i--)
 
  542                     if (detectedLines[i].error > limit)
 
  544                         detectedLines.erase(detectedLines.begin() + i);
 
  549                         maxError = 
std::max(detectedLines[i].error, maxError);
 
  552                 if (!detectedLines.empty() && maxError > 0) 
 
  556                     for (
size_t i = 0; i < detectedLines.size(); i++)
 
  560                         detectedLines[i].error = detectedLines[i].error / maxError + (1.0 - 
std::min(length, 500.0) / 500.0);
 
  562                     std::sort(detectedLines.begin(), detectedLines.end(), 
SortByError);
 
  564                     for (
size_t i = 0; i < detectedLines.size() && i < nrLines; i++)
 
  570                         verticalLines.push_back(cp);
 
  578                 if (detectedLines.size() == 1)
 
  580                     vigra::Diff2D diff((
double)detectedLines[0].x2 - detectedLines[0].x1, (
double)detectedLines[0].y2 - detectedLines[0].y1);
 
  581                     if (std::abs((diff.x * cos(
DEG_TO_RAD(roll)) + diff.y * sin(
DEG_TO_RAD(roll))) / diff.magnitude()) < 0.05)
 
  587                         verticalLines.push_back(cp);
 
  595             verticalLines = detectedLines;
 
  598     return verticalLines;
 
AlphaImage m_mask
corresponding alpha channel 
std::vector< vigra::Point2D > line
Dummy progress display, without output. 
const vigra::Point2D & GetEnd() const 
void setHeight(unsigned int h)
set panorama height 
void setPanoImage(const SrcPanoImage &src, const PanoramaOptions &dest, vigra::Rect2D roi)
VerticalLine FitLine(SingleLine line)
SrcPanoImage getSrcImage(unsigned imgNr) const 
get a description of a source image 
void SetStart(const vigra::Point2D point)
double calculate_focal_length_pixels(double focal_length, double cropFactor, double width, double height)
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 
declaration of functions for finding lines 
const vigra::Point2D & GetStart() const 
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...
Contains functions to transform whole images. 
double resize_image(const vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, DestImage &dest, int resize_dimension)
std::vector< VerticalLine > VerticalLineVector
vigra::Point2D GetFootpoint(const vigra::Point2D &p, const vigra::Point2D &p1, const vigra::Point2D &p2, double &u)
VerticalLineVector FilterLines(Lines lines, double roll, const bool onlyVerticalLines)
a single line extracted from image 
virtual void run()
runs the algorithm. 
const CPVector & getCtrlPoints() const 
get all control point of this Panorama 
int getHeight() const 
Get the height of the image in pixels. 
vigra::pair< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImage(const ROIImage< Image, Mask > &img)
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...
value_type operator()(ITERATOR const &i) const 
represents a control point 
void setOptimizeVector(const OptimizeVector &optvec)
set optimize setting 
double GetEstimatedDistance(const VerticalLine &otherLine) const 
const vigra::Rect2D & getROI() const 
unsigned int addCtrlPoint(const ControlPoint &point)
add a new control point. 
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 
vigra::FRGBImage ImageType
HuginBase::CPVector _getFilteredLines(const HuginBase::Panorama &pano, const unsigned int imgNr, ImageType &image, vigra::BImage &mask, const unsigned int nrLines, const bool onlyVerticalLines)
int getWidth() const 
Get the width of the image in pixels. 
void remapImage(vigra::triple< ImgIter, ImgIter, ImgAccessor > srcImg, vigra_ext::Interpolator interpol, AppBase::ProgressDisplay *progress, bool singleThreaded=false)
remap a image without alpha channel 
RemapImage m_image
remapped image 
virtual double getResultHeight()
void deleteAllMasks()
delete all masks 
declaration of find lines algorithm 
HuginBase::CPVector GetLines(const HuginBase::Panorama &pano, const unsigned int imgNr, vigra::UInt8RGBImage &image, vigra::BImage &mask)
searches for all lines, the same as GetVerticalLines execpt that no filtering according to roll angle...
evaluate x, points are on a vertical line 
double GetLineLength() const 
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)
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 
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's algorithm 
!! from PTOptimise.h 1951 
unsigned int addImage(const SrcPanoImage &img)
the the number for a specific image 
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. 
void setHFOV(double h, bool keepView=true)
set the horizontal field of view. 
virtual double getResultHorizontalFOV()
void SetEnd(const int x, const int y)
void SetEnd(const vigra::Point2D point)
std::vector< SingleLine > Lines
vector of extracted lines from image 
void SetStart(const int x, const int y)
const bool IsVertical() const 
std::vector< ControlPoint > CPVector
vigra::triple< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImageRange(ROIImage< Image, Alpha > &img)
void copyImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc)
std::vector< std::set< std::string > > OptimizeVector
const SrcPanoImage & getImage(std::size_t nr) const 
get a panorama image, counting starts with 0 
void setOptions(const PanoramaOptions &opt)
set new output settings This is not used directly for optimizing/stiching, but it can be feed into ru...
value_type operator()(ITERATOR const &i, DIFFERENCE d) const 
All variables of a source image. 
void setProjection(ProjectionFormat f)
set the Projection format and adjust the hfov/vfov if nessecary 
evaluate y, points are on a horizontal line 
struct to hold a image state for stitching 
int linePts2lineList(vigra::BImage &img, int minsize, double flpix, Lines &lines)
converts a linePts image to a list of lines 
void setWidth(unsigned int w, bool keepView=true)
set panorama width keep the HFOV, if keepView=true 
vigra::BImage edgeMap2linePts(vigra::BImage &input)
marks line point 
bool SortByError(const HuginBase::ControlPoint &cp1, const HuginBase::ControlPoint &cp2)
double outputExposureValue