00001
00002
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00053 fill_set(testImages,0,m_nrImg-1);
00054 };
00055 };
00056
00057 CalculateImageOverlap::~CalculateImageOverlap()
00058 {
00059 for(unsigned int i=0;i<m_nrImg;i++)
00060 {
00061 delete m_transform[i];
00062 delete m_invTransform[i];
00063 };
00064 };
00065
00066 void CalculateImageOverlap::calculate(unsigned int steps)
00067 {
00068 if(testImages.size()==0)
00069 {
00070 return;
00071 };
00072 for(UIntSet::const_iterator it=testImages.begin(); it!=testImages.end();it++)
00073 {
00074 const SrcPanoImage& img=m_pano->getImage(*it);
00075 vigra::Rect2D c=vigra::Rect2D(img.getSize());
00076 if(img.getCropMode()!=SrcPanoImage::NO_CROP)
00077 {
00078 c&=img.getCropRect();
00079 };
00080 unsigned int frequency=std::min<unsigned int>(steps,std::min<unsigned int>(c.width(),c.height()));
00081 if(frequency<2)
00082 frequency=2;
00083 std::vector<unsigned int> overlapCounter;
00084 overlapCounter.resize(m_nrImg,0);
00085 unsigned int pointCounter=0;
00086 for (unsigned int x=0; x<frequency; x++)
00087 {
00088 for (unsigned int y=0; y<frequency; y++)
00089 {
00090
00091
00092 double xc = double (x) / double (frequency) * double(c.width()) + c.left();
00093 double yc = double (y) / double (frequency) * double(c.height()) + c.top();
00094 vigra::Point2D p(xc,yc);
00095
00096 if(img.isInside(p,true))
00097 {
00098 pointCounter++;
00099
00100 double xi,yi;
00101 if(m_invTransform[*it]->transformImgCoord(xi,yi,xc,yc))
00102 {
00103
00104 for(unsigned int j=0;j<m_nrImg;j++)
00105 {
00106 if((*it)==j)
00107 continue;
00108 double xj,yj;
00109
00110 if(m_transform[j]->transformImgCoord(xj,yj,xi,yi))
00111 {
00112 p.x=xj;
00113 p.y=yj;
00114 if(m_pano->getImage(j).isInside(p,true))
00115 {
00116 overlapCounter[j]++;
00117 };
00118 };
00119 };
00120 };
00121 };
00122 };
00123 };
00124
00125 m_overlap[*it][*it]=1.0;
00126 if(pointCounter>0)
00127 {
00128 for(unsigned int k=0;k<m_nrImg;k++)
00129 {
00130 if((*it)==k)
00131 {
00132 continue;
00133 };
00134 m_overlap[*it][k]=(double)overlapCounter[k]/(double)pointCounter;
00135 };
00136 };
00137 };
00138 };
00139
00140 double CalculateImageOverlap::getOverlap(unsigned int i, unsigned int j)
00141 {
00142 if(i==j)
00143 {
00144 return 1.0;
00145 }
00146 else
00147 {
00148 return std::max<double>(m_overlap[i][j],m_overlap[j][i]);
00149 };
00150 };
00151
00152 UIntSet CalculateImageOverlap::getOverlapForImage(unsigned int i)
00153 {
00154 UIntSet overlapImgs;
00155 for(unsigned int j=0;j<m_nrImg;j++)
00156 {
00157 if(i!=j)
00158 {
00159 if(getOverlap(i,j)>0)
00160 {
00161 overlapImgs.insert(j);
00162 };
00163 };
00164 };
00165 return overlapImgs;
00166 };
00167
00168 void CalculateImageOverlap::limitToImages(UIntSet img)
00169 {
00170 testImages=img;
00171 };
00172
00173 }