CalculateOverlap.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00013 /*  This program is free software; you can redistribute it and/or
00014  *  modify it under the terms of the GNU General Public
00015  *  License as published by the Free Software Foundation; either
00016  *  version 2 of the License, or (at your option) any later version.
00017  *
00018  *  This software is distributed in the hope that it will be useful,
00019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021  *  General Public License for more details.
00022  *
00023  *  You should have received a copy of the GNU General Public
00024  *  License along with this software. If not, see
00025  *  <http://www.gnu.org/licenses/>.
00026  *
00027  */
00028 
00029 #include "CalculateOverlap.h"
00030 
00031 namespace HuginBase {
00032 
00033 using namespace hugin_utils;
00034 
00035 CalculateImageOverlap::CalculateImageOverlap(const HuginBase::PanoramaData *pano):m_pano(pano)
00036 {
00037     m_nrImg=pano->getNrOfImages();
00038     if(m_nrImg>0)
00039     {
00040         m_overlap.resize(m_nrImg);
00041         PanoramaOptions opts=pano->getOptions();
00042         m_transform.resize(m_nrImg);
00043         m_invTransform.resize(m_nrImg);
00044         for(unsigned int i=0;i<m_nrImg;i++)
00045         {
00046             m_overlap[i].resize(m_nrImg,0);
00047             m_transform[i]=new PTools::Transform;
00048             m_transform[i]->createTransform(*pano,i,opts);
00049             m_invTransform[i]=new PTools::Transform;
00050             m_invTransform[i]->createInvTransform(*pano,i,opts);
00051         };
00052         // per default we are testing all images
00053         for (unsigned int i = 0; i < m_nrImg; i++)
00054         {
00055             m_testImages.push_back(i);
00056         }
00057     };
00058 };
00059 
00060 CalculateImageOverlap::~CalculateImageOverlap()
00061 {
00062     for(unsigned int i=0;i<m_nrImg;i++)
00063     {
00064         delete m_transform[i];
00065         delete m_invTransform[i];
00066     };
00067 };
00068 
00069 void CalculateImageOverlap::calculate(unsigned int steps)
00070 {
00071     if(m_testImages.empty())
00072     {
00073         return;
00074     };
00075 #pragma omp parallel for schedule(dynamic)
00076     for (int i = 0; i < m_testImages.size(); ++i)
00077     {
00078         unsigned int imgNr = m_testImages[i];
00079         const SrcPanoImage& img = m_pano->getImage(imgNr);
00080         vigra::Rect2D c=vigra::Rect2D(img.getSize());
00081         if(img.getCropMode()!=SrcPanoImage::NO_CROP)
00082         {
00083             c&=img.getCropRect();
00084         };
00085         unsigned int frequency=std::min<unsigned int>(steps,std::min<unsigned int>(c.width(),c.height()));
00086         if(frequency<2)
00087             frequency=2;
00088         std::vector<unsigned int> overlapCounter;
00089         overlapCounter.resize(m_nrImg,0);
00090         unsigned int pointCounter=0;
00091         for (unsigned int x=0; x<frequency; x++)
00092         {
00093             for (unsigned int y=0; y<frequency; y++)
00094             {
00095                 // scale (x, y) so it is always within the cropped region of the
00096                 // image.
00097                 double xc = double (x) / double (frequency) * double(c.width()) + c.left();
00098                 double yc = double (y) / double (frequency) * double(c.height()) + c.top();
00099                 vigra::Point2D p(xc,yc);
00100                 //check if inside crop, especially for circular crops
00101                 if(img.isInside(p,true))
00102                 {
00103                     pointCounter++;
00104                     //transform to panorama coordinates
00105                     double xi,yi;
00106                     if (m_invTransform[imgNr]->transformImgCoord(xi, yi, xc, yc))
00107                     {
00108                         //now, check if point is inside an other image
00109                         for(unsigned int j=0;j<m_nrImg;j++)
00110                         {
00111                             if (imgNr == j)
00112                                 continue;
00113                             double xj,yj;
00114                             //transform to image coordinates
00115                             if(m_transform[j]->transformImgCoord(xj,yj,xi,yi))
00116                             {
00117                                 p.x=xj;
00118                                 p.y=yj;
00119                                 if(m_pano->getImage(j).isInside(p,true))
00120                                 {
00121                                     overlapCounter[j]++;
00122                                 };
00123                             };
00124                         };
00125                     };
00126                 };
00127             };
00128         };
00129         //now calculate overlap and save
00130         m_overlap[imgNr][imgNr] = 1.0;
00131         if(pointCounter>0)
00132         {
00133             for(unsigned int k=0;k<m_nrImg;k++)
00134             {
00135                 if (imgNr == k)
00136                 {
00137                     continue;
00138                 };
00139                 m_overlap[imgNr][k] = (double)overlapCounter[k] / (double)pointCounter;
00140             };
00141         };
00142     };
00143 };
00144 
00145 double CalculateImageOverlap::getOverlap(unsigned int i, unsigned int j)
00146 {
00147     if(i==j)
00148     {
00149         return 1.0;
00150     }
00151     else
00152     {
00153         return std::max<double>(m_overlap[i][j],m_overlap[j][i]);
00154     };
00155 };
00156 
00157 UIntSet CalculateImageOverlap::getOverlapForImage(unsigned int i)
00158 {
00159     UIntSet overlapImgs;
00160     for(unsigned int j=0;j<m_nrImg;j++)
00161     {
00162         if(i!=j)
00163         {
00164             if(getOverlap(i,j)>0)
00165             {
00166                 overlapImgs.insert(j);
00167             };
00168         };
00169     };
00170     return overlapImgs;
00171 };
00172 
00173 void CalculateImageOverlap::limitToImages(UIntSet img)
00174 {
00175     m_testImages.clear();
00176     for (UIntSet::const_iterator it = img.begin(); it != img.end(); ++it)
00177     {
00178         m_testImages.push_back(*it);
00179     };
00180 };
00181 
00182 } // namespace

Generated on 31 Jul 2015 for Hugintrunk by  doxygen 1.4.7