CenterHorizontally.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00026 #include "CenterHorizontally.h"
00027 
00028 #include <vigra/copyimage.hxx>
00029 #include <panodata/PanoramaData.h>
00030 #include <nona/RemappedPanoImage.h>
00031 
00032 
00033 
00034 namespace HuginBase {
00035 
00036 
00037 void CenterHorizontally::centerHorizontically(PanoramaData& panorama)
00038 {
00039     vigra::Size2D panoSize(360,180);
00040     
00041     // remap into minature pano.
00042     PanoramaOptions opts;
00043     opts.setHFOV(360);
00044     opts.setProjection(PanoramaOptions::EQUIRECTANGULAR);
00045     opts.setWidth(360);
00046     opts.setHeight(180);
00047     
00048     // remap image
00049     vigra::BImage panoAlpha(panoSize);
00050     Nona::RemappedPanoImage<vigra::BImage, vigra::BImage> remapped;
00051     
00052     // use selected images.
00053     UIntSet allActiveImgs = panorama.getActiveImages();
00054 
00055     if (allActiveImgs.size() == 0) {
00056         // do nothing if there are no images
00057         return;
00058     }
00059     
00060     //only check unlinked images
00061     UIntSet activeImgs;
00062     for (UIntSet::const_iterator it = allActiveImgs.begin(); it!= allActiveImgs.end(); ++it)
00063     {
00064         const SrcPanoImage & img=panorama.getImage(*it);
00065         bool consider=true;
00066         if(img.YawisLinked())
00067         {
00068             for(UIntSet::const_iterator it2=activeImgs.begin(); it2!=activeImgs.end(); ++it2)
00069             {
00070                 if(img.YawisLinkedWith(panorama.getSrcImage(*it2)))
00071                 {
00072                     consider=false;
00073                     break;
00074                 };
00075             };
00076         };
00077         if(img.getX()!=0 || img.getY()!=0 || img.getZ()!=0)
00078         {
00079             //if translation parameters are non-zero break, 
00080             //because centering by modifying yaw does not work in this case
00081             return;
00082         };
00083         if(consider)
00084             activeImgs.insert(*it);
00085     };
00086 
00087     for (UIntSet::iterator it = activeImgs.begin(); it != activeImgs.end(); ++it) {
00088         //    for (unsigned int imgNr=0; imgNr < getNrOfImages(); imgNr++) {
00089         //        const PanoImage & img = getImage(*it);
00090         //        Size2D sz(img.getWidth(), img.getHeight());
00091         //        remapped.setPanoImage(*this, *it, sz, opts);
00092         remapped.setPanoImage(panorama.getSrcImage(*it), opts, vigra::Rect2D(0,0,360,180));
00093         // calculate alpha channel
00094         remapped.calcAlpha();
00095         // copy into global alpha channel.
00096         vigra::copyImageIf(vigra_ext::applyRect(remapped.boundingBox(),
00097                                                 vigra_ext::srcMaskRange(remapped)),
00098                            vigra_ext::applyRect(remapped.boundingBox(),
00099                                                 vigra_ext::srcMask(remapped)),
00100                            vigra_ext::applyRect(remapped.boundingBox(),
00101                                                 destImage(panoAlpha)));
00102         }
00103     
00104     // get field of view
00105     std::vector<int> borders;
00106     bool colOccupied = false;
00107     for (int h=0; h < 360; h++) {
00108         bool curColOccupied = false;
00109         for (int v=0; v< 180; v++) {
00110             if (panoAlpha(h,v)) {
00111                 // pixel is valid
00112                 curColOccupied = true;
00113             }
00114         }
00115         if ((colOccupied && !curColOccupied) ||
00116             (!colOccupied && curColOccupied))
00117         {
00118             // change in position, save point.
00119             borders.push_back(h-180);
00120             colOccupied = curColOccupied;
00121         }
00122     }
00123     
00124     
00125     int lastidx = borders.size() -1;
00126     if (lastidx == -1) {
00127         // empty pano
00128         return;
00129     }
00130     
00131     if (colOccupied) {
00132         // we have reached the right border, and the pano is still valid
00133         // shift right fragments by 360 deg
00134         // |11    2222|  -> |      222211     |
00135         std::vector<int> newBorders;
00136         newBorders.push_back(borders[lastidx]);
00137         for (int i = 0; i < lastidx; i++) {
00138             newBorders.push_back(borders[i]+360);
00139         }
00140         borders = newBorders;
00141     }
00142     
00143     double dYaw=(borders[0] + borders[lastidx])/2;
00144     
00145     // apply yaw shift
00146     unsigned int nImg = panorama.getNrOfImages();
00147     for (unsigned int i=0; i < nImg; i++) {
00148         const SrcPanoImage & image = panorama.getImage(i);
00149         // only adjust yaw if we haven't already done so because of linking.
00150         bool update=true;
00151         if(image.YawisLinked())
00152         {
00153             for(unsigned int j=0; j<i; j++)
00154             {
00155                 if(image.YawisLinkedWith(panorama.getImage(j)))
00156                 {
00157                     update=false;
00158                     break;
00159                 };
00160             };
00161         };
00162         if (update)
00163         {
00164             double yaw = image.getYaw();
00165             yaw = yaw - dYaw;
00166             while (yaw < 180) {
00167                 yaw += 360;
00168             }
00169             while (yaw > 180) {
00170                 yaw -= 360;
00171             }
00172             SrcPanoImage newImage = image;
00173             newImage.setYaw(yaw);
00174             panorama.setImage(i, newImage);
00175             panorama.imageChanged(i);
00176         }
00177     }
00178 }
00179 
00180 } 

Generated on 27 Aug 2015 for Hugintrunk by  doxygen 1.4.7