LayerStacks.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00008  /*  This is free software; you can redistribute it and/or
00009  *  modify it under the terms of the GNU General Public
00010  *  License as published by the Free Software Foundation; either
00011  *  version 2 of the License, or (at your option) any later version.
00012  *
00013  *  This software is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  *  Lesser General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU General Public
00019  *  License along with this software. If not, see
00020  *  <http://www.gnu.org/licenses/>.
00021  *
00022  */
00023 
00024 #include "LayerStacks.h"
00025 
00026 #include <panodata/PanoramaData.h>
00027 #include <panodata/StandardImageVariableGroups.h>
00028 #include <algorithms/basic/CalculateOverlap.h>
00029 #include <algorithms/optimizer/ImageGraph.h>
00030 #include <algorithms/nona/ComputeImageROI.h>
00031 
00032 namespace HuginBase
00033 {
00034 
00035 std::vector<UIntSet> getHDRStacks(const PanoramaData & pano, UIntSet allImgs, PanoramaOptions opts)
00036 {
00037     std::vector<UIntSet> result;
00038 
00039     // if no images are available, return empty result vector
00040     if ( allImgs.empty() )
00041     {
00042         return result;
00043     }
00044 
00045     // special case: for a negtive overlap use the assigned stacks and skip
00046     // overlap calculation
00047     if (opts.outputStacksMinOverlap < 0)
00048     {
00049         HuginBase::ConstStandardImageVariableGroups variable_groups(pano);
00050         return variable_groups.getStacks().getPartsSet();
00051     };
00052 
00053     UIntSet stack;
00054 
00055     CalculateImageOverlap overlap(&pano);
00056     overlap.calculate(10);  // we are testing 10*10=100 points
00057     do
00058     {
00059         const unsigned srcImg = *(allImgs.begin());
00060         stack.insert(srcImg);
00061         allImgs.erase(srcImg);
00062 
00063         // find all images that have a suitable overlap.
00064         for (UIntSet::const_iterator it = allImgs.begin(); it != allImgs.end(); ++it)
00065         {
00066             const unsigned srcImg2 = *it;
00067             if (overlap.getOverlap(srcImg, srcImg2) > opts.outputStacksMinOverlap)
00068             {
00069                 stack.insert(srcImg2);
00070             };
00071         };
00072         for (UIntSet::const_iterator it = stack.begin(); it != stack.end(); ++it)
00073         {
00074             allImgs.erase(*it);
00075         };
00076         result.push_back(stack);
00077         stack.clear();
00078     } while (!allImgs.empty());
00079 
00080     return result;
00081 }
00082 
00083 std::vector<UIntSet> getExposureLayers(const PanoramaData & pano, UIntSet allImgs, PanoramaOptions opts)
00084 {
00085     return getExposureLayers(pano, allImgs, opts.outputLayersExposureDiff);
00086 };
00087 
00088 std::vector<UIntSet> getExposureLayers(const PanoramaData & pano, UIntSet allImgs, const double maxEVDiff)
00089 {
00090     std::vector<UIntSet> result;
00091 
00092     // if no images are available, return empty result vector
00093     if ( allImgs.empty() )
00094     {
00095         return result;
00096     }
00097 
00098     UIntSet layer;
00099 
00100     do
00101     {
00102         const unsigned srcImg = *(allImgs.begin());
00103         layer.insert(srcImg);
00104         allImgs.erase(srcImg);
00105 
00106         // find all images that have a similar exposure values.
00107         const double firstExposureValue = pano.getImage(srcImg).getExposureValue();
00108         for (UIntSet::const_iterator it = allImgs.begin(); it !=  allImgs.end(); ++it)
00109         {
00110             const unsigned srcImg2 = *it;
00111             if ( fabs(firstExposureValue - pano.getImage(srcImg2).getExposureValue()) < maxEVDiff )
00112             {
00113                 layer.insert(srcImg2);
00114             }
00115         }
00116         for (UIntSet::const_iterator it = layer.begin(); it != layer.end(); ++it)
00117         {
00118             allImgs.erase(*it);
00119         };
00120         result.push_back(layer);
00121         layer.clear();
00122     } while (!allImgs.empty());
00123 
00124     return result;
00125 }
00126 
00127 UIntSet getImagesinROI (const PanoramaData& pano, const UIntSet activeImages)
00128 {
00129     return getImagesinROI(pano, activeImages, pano.getOptions().getROI());
00130 }
00131 
00132 UIntSet getImagesinROI(const PanoramaData& pano, const UIntSet activeImages, vigra::Rect2D panoROI)
00133 {
00134     UIntSet images;
00135     PanoramaOptions opts = pano.getOptions();
00136     opts.setROI(panoROI);
00137     for (UIntSet::const_iterator it = activeImages.begin(); it != activeImages.end(); ++it)
00138     {
00139         vigra::Rect2D roi = estimateOutputROI(pano, opts, *it);
00140         if (!(roi.isEmpty()))
00141         {
00142             images.insert(*it);
00143         }
00144     }
00145     return images;
00146 }
00147 
00148 struct SortVectorByExposure
00149 {
00150     explicit SortVectorByExposure(const HuginBase::Panorama* pano) : m_pano(pano) {};
00151     bool operator()(const size_t& img1, const size_t& img2)
00152     {
00153         return m_pano->getImage(img1).getExposureValue() < m_pano->getImage(img2).getExposureValue();
00154     }
00155 private:
00156     const HuginBase::Panorama* m_pano;
00157 };
00158 
00159 std::vector<HuginBase::UIntVector> getSortedStacks(const HuginBase::Panorama* pano)
00160 {
00161     std::vector<HuginBase::UIntVector> stacks;
00162     if (pano->getNrOfImages() == 0)
00163     {
00164         return stacks;
00165     };
00166     HuginBase::ConstStandardImageVariableGroups variable_groups(*pano);
00167     HuginBase::UIntSetVector imageGroups = variable_groups.getStacks().getPartsSet();
00168     //get image with median exposure for search with cp generator
00169     for (size_t imgGroup = 0; imgGroup < imageGroups.size(); ++imgGroup)
00170     {
00171         HuginBase::UIntVector stackImages(imageGroups[imgGroup].begin(), imageGroups[imgGroup].end());
00172         std::sort(stackImages.begin(), stackImages.end(), SortVectorByExposure(pano));
00173         stacks.push_back(stackImages);
00174     };
00175     return stacks;
00176 };
00177 
00178 class GraphVisitor:public HuginGraph::BreadthFirstSearchVisitor
00179 {
00180 public:
00181     virtual void Visit(const size_t vertex, const HuginBase::UIntSet& visitedNeighbors, const HuginBase::UIntSet& unvisitedNeighbors)
00182     {
00183         images.push_back(vertex);
00184     };
00185     UIntVector GetTranslatedImageNumbers(const UIntVector& translatedImgNumbers) const
00186     {
00187         UIntVector result(images.size(), 0);
00188         for (size_t i = 0; i < images.size(); ++i)
00189         {
00190             result[i] = translatedImgNumbers[images[i]];
00191         };
00192         return result;
00193     };
00194 private:
00195     UIntVector images;
00196 };
00197 
00198 UIntVector getEstimatedBlendingOrder(const PanoramaData & pano, const UIntSet& images, const unsigned int referenceImage)
00199 {
00200     if (images.empty())
00201     {
00202         return UIntVector();
00203     };
00204     unsigned int refImage;
00205     if (set_contains(images, referenceImage))
00206     {
00207         refImage = referenceImage;
00208     }
00209     else
00210     {
00211         refImage = *images.begin();
00212     }
00213     // store a vector for translating image numbers later
00214     HuginBase::UIntVector subpanoImages;
00215     std::copy(images.begin(), images.end(), std::back_inserter(subpanoImages));
00216     // create subpano with all active images, don't forget to delete at end
00217     HuginBase::PanoramaData* subPano = pano.getNewSubset(images);
00218     // calculate overlap
00219     CalculateImageOverlap overlap(subPano);
00220     overlap.calculate(10);  // we are testing 10*10=100 points
00221     // now build ImageGraph and iterate all images
00222     HuginGraph::ImageGraph graph(overlap);
00223     GraphVisitor graphVisitor;
00224     graph.VisitAllImages(refImage, true, &graphVisitor);
00225     delete subPano;
00226     // translate image numbers to original images
00227     return graphVisitor.GetTranslatedImageNumbers(subpanoImages);
00228 };
00229 
00230 }

Generated on 25 Sep 2016 for Hugintrunk by  doxygen 1.4.7