1 // -*- c-basic-offset: 4 -*-
2
3 /** @file ExtractPoints.h
4 *
5 * @brief helper procedure for photometric optimizer on command line
6 *
7 * @author Pablo d'Angelo <pablo.dangelo@web.de>
8 *
9 * $Id$
10 *
11 */
12
13 /**
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public
16 * License as published by the Free Software Foundation; either
17 * version 2 of the License, or (at your option) any later version.
18 *
19 * This software is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this software. If not, see
26 * <http://www.gnu.org/licenses/>.
27 *
28 */
29
30 #include <hugin_basic.h>
31
32 #include <vigra/error.hxx>
33 #include <vigra/impex.hxx>
34
35 #include <vigra_ext/Pyramid.h>
36 #include <vigra_ext/impexalpha.hxx>
37 #include <algorithms/point_sampler/PointSampler.h>
38
39 template<class ImageType>
loadImagesPyr(std::vector<std::string> files,int pyrLevel,int verbose,HuginBase::LimitIntensityVector & limits,float & imageStepSize)40 std::vector<ImageType *> loadImagesPyr(std::vector<std::string> files, int pyrLevel, int verbose, HuginBase::LimitIntensityVector& limits, float& imageStepSize)
41 {
42 std::vector<ImageType *> srcImgs(files.size());
43 limits.resize(srcImgs.size());
44 #ifdef _WIN32
45 // init vigra codec manager before threaded section
46 // otherwise there could be sometimes race conditions
47 // which results in exceptions
48 std::string s = vigra::impexListExtensions();
49 #endif
50 #pragma omp parallel for schedule(dynamic)
51 for (int i=0; i < files.size(); i++) {
52 ImageType * tImg = new ImageType();
53 ImageType * tImg2 = new ImageType();
54 std::ostringstream buf;
55 vigra::ImageImportInfo info(files[i].c_str());
56 tImg->resize(info.size());
57 if (verbose)
58 buf << "loading: " << files[i] << std::endl;
59
60 const std::string pixelType(info.getPixelType());
61 if (info.numExtraBands() == 1) {
62 // dummy mask
63 vigra::BImage mask(info.size());
64 vigra::importImageAlpha(info, vigra::destImage(*tImg), vigra::destImage(mask));
65 if (pixelType == "FLOAT" || pixelType == "DOUBLE")
66 {
67 vigra_ext::FindComponentsMinMax<float> minmax;
68 vigra::inspectImageIf(vigra::srcImageRange(*tImg), vigra::srcImage(mask), minmax);
69 imageStepSize = std::min(imageStepSize, (minmax.max - minmax.min) / 16384.0f);
70 };
71 } else {
72 vigra::importImage(info, vigra::destImage(*tImg));
73 if (pixelType == "FLOAT" || pixelType == "DOUBLE")
74 {
75 vigra_ext::FindComponentsMinMax<float> minmax;
76 vigra::inspectImage(vigra::srcImageRange(*tImg), minmax);
77 imageStepSize = std::min(imageStepSize, (minmax.max - minmax.min) / 16384.0f);
78 };
79 }
80 float div = 1;
81 limits[i] = HuginBase::LimitIntensity(HuginBase::LimitIntensity::LIMIT_FLOAT);
82 if (pixelType== "UINT8") {
83 div = 255;
84 limits[i] = HuginBase::LimitIntensity(HuginBase::LimitIntensity::LIMIT_UINT8);
85 imageStepSize = std::min(imageStepSize, 1 / 255.0f);
86
87 } else if (pixelType=="UINT16") {
88 div = (1<<16)-1;
89 limits[i] = HuginBase::LimitIntensity(HuginBase::LimitIntensity::LIMIT_UINT16);
90 imageStepSize = std::min(imageStepSize, 1 / 65536.0f);
91 }
92
93 if (pyrLevel) {
94 ImageType * swap;
95 // create downscaled image
96 if (verbose > 0) {
97 buf << "downscaling: ";
98 }
99 for (int l=pyrLevel; l > 0; l--) {
100 if (verbose > 0) {
101 buf << tImg->size().x << "x" << tImg->size().y << " " << std::flush;
102 }
103 vigra_ext::reduceToNextLevel(*tImg, *tImg2);
104 swap = tImg;
105 tImg = tImg2;
106 tImg2 = swap;
107 }
108 if (verbose > 0)
109 buf << std::endl;
110 }
111 if (div > 1) {
112 div = 1/div;
113 transformImage(vigra::srcImageRange(*tImg), vigra::destImage(*tImg),
114 vigra::functor::Arg1()*vigra::functor::Param(div));
115 }
116 srcImgs[i]=tImg;
117 delete tImg2;
118 if (verbose > 0)
119 {
120 std::cout << buf.str();
121 };
122 }
123 return srcImgs;
124 }
125
126
127 // needs 2.0 progress steps
loadImgsAndExtractPoints(HuginBase::Panorama pano,int nPoints,int pyrLevel,bool randomPoints,AppBase::ProgressDisplay & progress,std::vector<vigra_ext::PointPairRGB> & points,int verbose,float & imageStepSize)128 void loadImgsAndExtractPoints(HuginBase::Panorama pano, int nPoints, int pyrLevel, bool randomPoints, AppBase::ProgressDisplay& progress, std::vector<vigra_ext::PointPairRGB> & points, int verbose, float& imageStepSize)
129 {
130 // extract file names
131 std::vector<std::string> files;
132 for (size_t i=0; i < pano.getNrOfImages(); i++)
133 files.push_back(pano.getImage(i).getFilename());
134
135 std::vector<vigra::FRGBImage*> images;
136 HuginBase::LimitIntensityVector limits;
137 imageStepSize = 1 / 255.0f;
138
139 // try to load the images.
140 images = loadImagesPyr<vigra::FRGBImage>(files, pyrLevel, verbose, limits, imageStepSize);
141
142 progress.setMessage("Sampling points");
143 if(randomPoints)
144 points = HuginBase::RandomPointSampler(pano, &progress, images, limits, nPoints).execute().getResultPoints();
145 else
146 points = HuginBase::AllPointSampler(pano, &progress, images, limits, nPoints).execute().getResultPoints();
147 progress.taskFinished();
148 }
149