Hugin trunk 0.1
Loading...
Searching...
No Matches
PanoramaOptions.cpp
Go to the documentation of this file.
1// -*- c-basic-offset: 4 -*-
2
51#include <hugin_config.h>
52
53#include "PanoramaOptions.h"
54
55#include <hugin_utils/utils.h>
58
59
60namespace HuginBase {
61
63{
64 assert((int)f <= (int)FILEFORMAT_NULL);
65 return fileformatNames[(int) f];
66}
67
68const std::string & PanoramaOptions::getOutputExtension() const
69{
72}
73
75{
76 int max = (int) FILEFORMAT_NULL;
77 int i;
78 for (i=0; i<max; i++) {
79 if (name == fileformatNames[i]) {
80 break;
81 }
82 }
83 if (i+1 == max) {
84 DEBUG_ERROR("could not parse format " << name );
85 return TIFF_m;
86 }
87 return (FileFormat) i;
88}
89
90
91void PanoramaOptions::printScriptLine(std::ostream & o, bool forPTOptimizer) const
92{
93 o << "p f" << m_projectionFormat << " w" << getWidth()<< " h" << getHeight()
94 << " v" << getHFOV() << " ";
95
96 if (! forPTOptimizer) {
97 // anchor for photometric optimizer
98 o << " k" << colorReferenceImage;
99 // the new exposure options
100 o << " E" << outputExposureValue;
101 o << " R" << outputMode;
102 if (!outputPixelType.empty()) {
103 o << " T" << outputPixelType;
104 }
105 if (m_roi != vigra::Rect2D(m_size)) {
106 o << " S" << m_roi.left() << "," << m_roi.right() << "," << m_roi.top() << "," << m_roi.bottom();
107 }
108 }
109
110 if (!m_projectionParams.empty()) {
111 o << " P\"";
112 for (int i=0; i < (int) m_projectionParams.size(); i++) {
113 o << m_projectionParams[i];
114 if (i+1 < (int)m_projectionParams.size())
115 o << " ";
116 }
117 o << "\"";
118 }
119 o << " n\"" << getFormatName(outputFormat);
120 if ( outputFormat == JPEG || outputFormat == JPEG_m) {
121 o << " q" << quality;
122 } else if ( outputFormat == TIFF ||
123 outputFormat == TIFF_m ||
127 {
128 o << " c:" << tiffCompression;
129 if (tiff_saveROI) {
130 o << " r:CROP";
131 }
132 }
133 o << "\"";
134 o << std::endl;
135
136 // misc options
137 o << "m i" << interpolator;
138
139 o << std::endl;
140}
141
143{
144 // post new projection type
145 if ((int) f >= panoProjectionFormatCount()) {
146 // reset to equirect if this projection is not known
147 f = EQUIRECTANGULAR;
148 }
150
151 /* Load constant features of the new projection */
153 /* post default projection parameters and corresponding FOV limits */
154 m_projectionParams.resize(m_projFeatures.numberOfParameters);
155 // reset projection parameters to default, determine also new fov limits, clip current fovs...
157}
158
159
160void PanoramaOptions::setProjectionParameters(const std::vector<double> & params)
161{
162 assert(m_projFeatures.numberOfParameters == (int) params.size());
163 // check if the parameters are good.
164 if (m_projFeatures.numberOfParameters == (int) params.size()) {
166 // enforce limits.
167 for (size_t i=0; i < params.size(); i++) {
168 if (m_projectionParams[i] > m_projFeatures.parm[i].maxValue) {
169 m_projectionParams[i] = m_projFeatures.parm[i].maxValue;
170 }
171 if (m_projectionParams[i] < m_projFeatures.parm[i].minValue) {
172 m_projectionParams[i] = m_projFeatures.parm[i].minValue;
173 }
174 }
175 }
176 /* get dynamic FOV limits corresponding to the new parameters,
177 clip current fovs to those limits, and post the results
178 */
180 double fovs[2];
181 int i;
182 for( i = 0; i < m_projFeatures.numberOfParameters; i++){
184 }
186 m_projFeatures.maxHFOV = fovs[0];
187 m_projFeatures.maxVFOV = fovs[1];
188 }
189 setHFOV( m_hfov, false );
190 setVFOV( getVFOV() );
191}
192
194{
195 std::vector<double> defParam(m_projFeatures.numberOfParameters);
196 for(int i = 0; i < m_projFeatures.numberOfParameters; i++)
197 {
198 defParam[i] = m_projFeatures.parm[i].defValue;
199 };
201};
202
204{
205 /* Ideally this attribute should come from libpano */
206 return ( f == RECTILINEAR
207 || f == CYLINDRICAL
208 || f == EQUIRECTANGULAR
209 || f == MERCATOR
210 || f == SINUSOIDAL
211 || f == MILLER_CYLINDRICAL
212 || f == PANINI
213 || f == ARCHITECTURAL
214 || f == EQUI_PANINI
215 || f == BIPLANE
216 || f == TRIPLANE
217 || f == GENERAL_PANINI
218 );
219}
220
221
222void PanoramaOptions::setWidth(unsigned int w, bool keepView)
223{
225 if (w%2 == 1) {
226 w = w+1;
227 }
228 }
229 bool nocrop = (m_roi == vigra::Rect2D(m_size));
230 double scale = w / (double) m_size.x;
231 m_size.x = w;
232 if (nocrop) {
233 m_roi = vigra::Rect2D(m_size);
234 } else {
235 // for now, do a simple proportional scaling
236 m_roi.setUpperLeft(vigra::Point2D(hugin_utils::roundi(scale*m_roi.left()), m_roi.top()));
237 m_roi.setLowerRight(vigra::Point2D(hugin_utils::roundi(scale*m_roi.right()), m_roi.bottom()));
238 // ensure ROI is inside the panorama
239 m_roi &= vigra::Rect2D(m_size);
240 }
241
242 if (keepView) {
243 m_size.y = hugin_utils::roundi(m_size.y*scale);
244 if (nocrop) {
245 m_roi = vigra::Rect2D(m_size);
246 } else {
247 m_roi.setUpperLeft(vigra::Point2D(m_roi.left(), hugin_utils::roundi(scale*m_roi.top())));
248 m_roi.setLowerRight(vigra::Point2D(m_roi.right(), hugin_utils::roundi(scale*m_roi.bottom())));
249 // ensure ROI is inside the panorama
250 m_roi &= vigra::Rect2D(m_size);
251 }
253 if (getVFOV() > getMaxVFOV()) {
255 }
256 }
257 }
258
259 DEBUG_DEBUG(" HFOV: " << m_hfov << " size: " << m_size << " roi: " << m_roi << " => vfov: " << getVFOV());
260}
261
262void PanoramaOptions::setHeight(unsigned int h)
263{
264 bool nocrop = (m_roi == vigra::Rect2D(m_size));
265
266 if (h == 0) {
267 h = 1;
268 }
269 int dh = h - m_size.y;
270 m_size.y = h;
271 if (nocrop) {
272 m_roi = vigra::Rect2D(m_size);
273 } else {
274 // move ROI
275 m_roi.moveBy(0,dh/2);
276 m_roi &= vigra::Rect2D(m_size);
277 }
278
279 DEBUG_DEBUG(" HFOV: " << m_hfov << " size: " << m_size << " roi:" << m_roi << " => vfov: " << getVFOV() );
280}
281
283{
285 DEBUG_NOTICE("Ignoring keepView");
286 keepView = false;
287 }
288
289 if (h <= 0) {
290 h = 1;
291 }
292 double vfov;
293 if (keepView) {
294 vfov = getVFOV();
295 }
296 m_hfov = std::min(h, getMaxHFOV());
297 if (keepView) {
298 setVFOV(std::min(vfov, getMaxVFOV()));
299 }
300}
301
303{
304 VFOV = std::min(VFOV, getMaxVFOV());
305
307 return;
308 }
309
310 bool nocrop = (m_roi == vigra::Rect2D(m_size));
311
312 if (VFOV <= 0) {
313 VFOV = 1;
314 }
315 // TODO: create transform from equirect to target projection and
316 // set additional
319 src.setProjection(SrcPanoImage::EQUIRECTANGULAR);
320 src.setHFOV(360);
321 src.setSize(vigra::Size2D(360,180));
322 transf.createInvTransform(src, *this);
323
325
326 if (VFOV>180 && getMaxVFOV() > 180) {
327 // we have crossed the pole
328 transf.transform(pmiddle, hugin_utils::FDiff2D(180, 180 - VFOV / 2 - 0.01));
329 } else {
330 transf.transform(pmiddle, hugin_utils::FDiff2D(0, VFOV / 2));
331 }
332 // try to keep the same ROI
333 vigra::Size2D oldSize = m_size;
335
336 if (nocrop) {
337 m_roi = vigra::Rect2D(m_size);
338 } else {
339 // adjust ROI to stay in previous position
340 int dh = m_size.y - oldSize.y;
341 m_roi.moveBy(0, dh/2);
342 // ensure ROI is visible
343 m_roi &= vigra::Rect2D(m_size);
344 }
345
346 DEBUG_DEBUG(" HFOV: " << m_hfov << " size: " << m_size << " roi: " << m_roi << " => vfov: " << VFOV);
347
348}
349
351{
352 // calcuale VFOV based on current panorama
355 src.setProjection(SrcPanoImage::EQUIRECTANGULAR);
356 src.setHFOV(360);
357 src.setSize(vigra::Size2D(360,180));
358 transf.createTransform(src, *this);
359
361 if (transf.transform(pmiddle, hugin_utils::FDiff2D(0, m_size.y / 2.0)))
362 {
363 double VFOV;
364 if (pmiddle.x > 90 || pmiddle.y < -90)
365 {
366 // the pole has been crossed
367 VFOV = 2 * (180 - pmiddle.y);
368 }
369 else
370 {
371 VFOV = 2 * pmiddle.y;
372 }
373 DEBUG_DEBUG(" HFOV: " << m_hfov << " size: " << m_size << " roi: " << m_roi << " => vfov: " << VFOV);
374 return VFOV;
375 }
376 else
377 {
378 DEBUG_DEBUG(" HFOV: " << m_hfov << " size: " << m_size << " roi: " << m_roi << " => vfov: " << getMaxVFOV() << " (setting to max)");
379 return getMaxVFOV();
380 }
381}
382
383const std::string PanoramaOptions::fileformatNames[] =
384{
385 "JPEG",
386 "JPEG_m",
387 "PNG",
388 "PNG_m",
389 "TIFF",
390 "TIFF_m",
391 "TIFF_mask",
392 "TIFF_multilayer",
393 "TIFF_multilayer_mask",
394 "PICT",
395 "PSD",
396 "PSD_m",
397 "PSD_mask",
398 "PAN",
399 "IVR",
400 "IVR_java",
401 "VRML",
402 "QTVR",
403 "HDR",
404 "HDR_m",
405 "EXR",
406 "EXR_m"
407};
408
409
410const std::string PanoramaOptions::fileformatExt[] =
411{
412 "jpg",
413 "jpg",
414 "png",
415 "png",
416 "tif",
417 "tif",
418 "tif",
419 "tif",
420 "tif",
421 "pict",
422 "psd",
423 "psd",
424 "psd",
425 "pan",
426 "ivr",
427 "IVR_java",
428 "wrl",
429 "mov",
430 "hdr",
431 "hdr",
432 "exr",
433 "exr"
434};
435
436
437
438
439
440} //namespace
Holds transformations for Image -> Pano and the other way.
void setHFOV(double h, bool keepView=true)
set the horizontal field of view.
void setProjection(ProjectionFormat f)
set the Projection format and adjust the hfov/vfov if nessecary
bool fovCalcSupported(ProjectionFormat f) const
true, if FOV calcuations are supported for projection f
std::vector< double > m_projectionParams
double getMaxHFOV() const
get maximum possible hfov with current projection
static const std::string & getFormatName(FileFormat f)
return string name of output file format
vigra_ext::Interpolator interpolator
void setHeight(unsigned int h)
set panorama height
const std::string & getOutputExtension() const
return the extension used by the current output format
void setWidth(unsigned int w, bool keepView=true)
set panorama width keep the HFOV, if keepView=true
double getMaxVFOV() const
get maximum possible vfov with current projection
static const std::string fileformatNames[]
static const std::string fileformatExt[]
void printScriptLine(std::ostream &o, bool forPTOptimizer=false) const
ProjectionFormat m_projectionFormat
unsigned int getWidth() const
void resetProjectionParameters()
sets the optional parameters to their default values
ProjectionFormat
Projection of final panorama.
void setProjectionParameters(const std::vector< double > &params)
set the optional parameters (they need to be of the correct size)
pano_projection_features m_projFeatures
static FileFormat getFormatFromName(const std::string &name)
returns the FileFormat corrosponding to name.
unsigned int getHeight() const
get panorama height
All variables of a source image.
void setSize(vigra::Size2D val)
Set the image size in pixels.
misc math function & classes used by other parts of the program
#define DEBUG_ERROR(msg)
Definition utils.h:76
#define DEBUG_DEBUG(msg)
Definition utils.h:68
#define DEBUG_NOTICE(msg)
Definition utils.h:70
mainly consists of wrapper around the pano tools library, to assist in ressource management and to pr...
Definition wxcms.cpp:39
int roundi(T x)
Definition hugin_math.h:73
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41