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 CalculateImageOverlap::CalculateImageOverlap(const HuginBase::PanoramaData *pano):m_pano(pano)
00034 {
00035     m_nrImg=pano->getNrOfImages();
00036     if(m_nrImg>0)
00037     {
00038         m_overlap.resize(m_nrImg);
00039         PanoramaOptions opts=pano->getOptions();
00040         m_transform.resize(m_nrImg);
00041         m_invTransform.resize(m_nrImg);
00042         for(unsigned int i=0;i<m_nrImg;i++)
00043         {
00044             m_overlap[i].resize(m_nrImg,0);
00045             m_transform[i]=new PTools::Transform;
00046             m_transform[i]->createTransform(*pano,i,opts);
00047             m_invTransform[i]=new PTools::Transform;
00048             m_invTransform[i]->createInvTransform(*pano,i,opts);
00049         };
00050         // per default we are testing all images
00051         for (unsigned int i = 0; i < m_nrImg; i++)
00052         {
00053             m_testImages.push_back(i);
00054         }
00055     };
00056 };
00057 
00058 CalculateImageOverlap::~CalculateImageOverlap()
00059 {
00060     for(unsigned int i=0;i<m_nrImg;i++)
00061     {
00062         delete m_transform[i];
00063         delete m_invTransform[i];
00064     };
00065 };
00066 
00067 void CalculateImageOverlap::calculate(unsigned int steps)
00068 {
00069     if(m_testImages.empty())
00070     {
00071         return;
00072     };
00073 #pragma omp parallel for schedule(dynamic)
00074     for (int i = 0; i < m_testImages.size(); ++i)
00075     {
00076         unsigned int imgNr = m_testImages[i];
00077         const SrcPanoImage& img = m_pano->getImage(imgNr);
00078         vigra::Rect2D c=vigra::Rect2D(img.getSize());
00079         if(img.getCropMode()!=SrcPanoImage::NO_CROP)
00080         {
00081             c&=img.getCropRect();
00082         };
00083         unsigned int frequency=std::min<unsigned int>(steps,std::min<unsigned int>(c.width(),c.height()));
00084         if(frequency<2)
00085             frequency=2;
00086         std::vector<unsigned int> overlapCounter;
00087         overlapCounter.resize(m_nrImg,0);
00088         unsigned int pointCounter=0;
00089         for (unsigned int x=0; x<frequency; x++)
00090         {
00091             for (unsigned int y=0; y<frequency; y++)
00092             {
00093                 // scale (x, y) so it is always within the cropped region of the
00094                 // image.
00095                 double xc = double (x) / double (frequency) * double(c.width()) + c.left();
00096                 double yc = double (y) / double (frequency) * double(c.height()) + c.top();
00097                 vigra::Point2D p(xc,yc);
00098                 //check if inside crop, especially for circular crops
00099                 if(img.isInside(p,true))
00100                 {
00101                     pointCounter++;
00102                     //transform to panorama coordinates
00103                     double xi,yi;
00104                     if (m_invTransform[imgNr]->transformImgCoord(xi, yi, xc, yc))
00105                     {
00106                         //now, check if point is inside an other image
00107                         for(unsigned int j=0;j<m_nrImg;j++)
00108                         {
00109                             if (imgNr == j)
00110                                 continue;
00111                             double xj,yj;
00112                             //transform to image coordinates
00113                             if(m_transform[j]->transformImgCoord(xj,yj,xi,yi))
00114                             {
00115                                 p.x=xj;
00116                                 p.y=yj;
00117                                 if(m_pano->getImage(j).isInside(p,true))
00118                                 {
00119                                     overlapCounter[j]++;
00120                                 };
00121                             };
00122                         };
00123                     };
00124                 };
00125             };
00126         };
00127         //now calculate overlap and save
00128         m_overlap[imgNr][imgNr] = 1.0;
00129         if(pointCounter>0)
00130         {
00131             for(unsigned int k=0;k<m_nrImg;k++)
00132             {
00133                 if (imgNr == k)
00134                 {
00135                     continue;
00136                 };
00137                 m_overlap[imgNr][k] = (double)overlapCounter[k] / (double)pointCounter;
00138             };
00139         };
00140     };
00141 };
00142 
00143 double CalculateImageOverlap::getOverlap(unsigned int i, unsigned int j) const
00144 {
00145     if(i==j)
00146     {
00147         return 1.0;
00148     }
00149     else
00150     {
00151         return std::max<double>(m_overlap[i][j],m_overlap[j][i]);
00152     };
00153 };
00154 
00155 UIntSet CalculateImageOverlap::getOverlapForImage(unsigned int i) const
00156 {
00157     UIntSet overlapImgs;
00158     for(unsigned int j=0;j<m_nrImg;j++)
00159     {
00160         if(i!=j)
00161         {
00162             if(getOverlap(i,j)>0)
00163             {
00164                 overlapImgs.insert(j);
00165             };
00166         };
00167     };
00168     return overlapImgs;
00169 };
00170 
00171 void CalculateImageOverlap::limitToImages(UIntSet img)
00172 {
00173     m_testImages.clear();
00174     for (UIntSet::const_iterator it = img.begin(); it != img.end(); ++it)
00175     {
00176         m_testImages.push_back(*it);
00177     };
00178 };
00179 
00180 } // namespace

Generated on 27 May 2016 for Hugintrunk by  doxygen 1.4.7