Hugin trunk 0.1
Loading...
Searching...
No Matches
ImageTransforms.h
Go to the documentation of this file.
1// -*- c-basic-offset: 4 -*-
27#ifndef _VIGRA_EXT_IMAGETRANSFORMS_H
28#define _VIGRA_EXT_IMAGETRANSFORMS_H
29
30#include <fstream>
31
32#include <vigra/basicimage.hxx>
33#include <vigra_ext/ROIImage.h>
35#include <vigra_ext/pyramid2.h>
36
38#include <hugin_utils/utils.h>
40
41namespace vigra_ext
42{
43
45template <class T>
47{
48 if (p < 0) {
49 return vigra::NumericTraits<T>::zero();
50 } else {
51 return p;
52 }
53}
54
56template <class T>
57vigra::RGBValue<T> zeroNegative(vigra::RGBValue<T> p)
58{
59 if (p.red() < 0) p.setRed(vigra::NumericTraits<T>::zero());
60 if (p.green() < 0) p.setGreen(vigra::NumericTraits<T>::zero());
61 if (p.blue() < 0) p.setBlue(vigra::NumericTraits<T>::zero());
62 return p;
63}
64
65
91template <class SrcImageIterator, class SrcAccessor,
93 class TRANSFORM,
94 class PixelTransform,
96 class Interpolator>
97void transformImageIntern(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
98 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
99 std::pair<AlphaImageIterator, AlphaAccessor> alpha,
100 TRANSFORM & transform,
102 vigra::Diff2D destUL,
104 bool warparound,
106 bool singleThreaded)
107{
108 const vigra::Diff2D destSize = dest.second - dest.first;
109
110 const int xstart = destUL.x;
111 const int xend = destUL.x + destSize.x;
112 const int ystart = destUL.y;
113 const int yend = destUL.y + destSize.y;
114
117
118 // loop over the image and transform
119#pragma omp parallel for if(!singleThreaded) schedule(dynamic)
120 for (int y = ystart; y < yend; ++y)
121 {
122 // create x iterators
124 xd.y += y - ystart;
125 AlphaImageIterator xdm(alpha.first);
126 xdm.y += y - ystart;
127 typename SrcAccessor::value_type tempval;
128 for (int x = xstart; x < xend; ++x, ++xd.x, ++xdm.x)
129 {
130 double sx, sy;
131 if (transform.transformImgCoord(sx, sy, x, y)) {
132 if (interpol.operator()(sx, sy, tempval)){
133 // apply pixel transform and write to output
135 alpha.second.set(pixelTransform.hdrWeight(tempval, vigra::UInt8(255)), xdm);
136 }
137 else {
138 alpha.second.set(0, xdm);
139 }
140 }
141 else {
142 alpha.second.set(0, xdm);
143 }
144 }
145 }
146}
147
149template <class SrcImageIterator, class SrcAccessor,
151 class DestImageIterator, class DestAccessor,
152 class TRANSFORM,
153 class PixelTransform,
155 class Interpolator>
156void transformImageAlphaIntern(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
157 std::pair<SrcAlphaIterator, SrcAlphaAccessor> srcAlpha,
158 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
159 std::pair<AlphaImageIterator, AlphaAccessor> alpha,
160 TRANSFORM & transform,
162 vigra::Diff2D destUL,
164 bool warparound,
166 bool singleThreaded)
167{
168 const vigra::Diff2D destSize = dest.second - dest.first;
169
170 const int xstart = destUL.x;
171 const int xend = destUL.x + destSize.x;
172 const int ystart = destUL.y;
173 const int yend = destUL.y + destSize.y;
174
178
179 // loop over the image and transform
180#pragma omp parallel for if(!singleThreaded) schedule(dynamic)
181 for(int y=ystart; y < yend; ++y)
182 {
183 // create x iterators
185 xd.y += y - ystart;
186 AlphaImageIterator xdist(alpha.first);
187 xdist.y += y - ystart;
188 typename SrcAccessor::value_type tempval;
189 typename SrcAlphaAccessor::value_type alphaval;
190 for (int x = xstart; x < xend; ++x, ++xd.x, ++xdist.x)
191 {
192 double sx,sy;
193 if (transform.transformImgCoord(sx,sy,x,y)) {
194 // try to interpolate.
195 if (interpol(sx, sy, tempval, alphaval)) {
197 alpha.second.set(pixelTransform.hdrWeight(tempval, alphaval), xdist);
198 } else {
199 // point outside of image or mask
200 alpha.second.set(0, xdist);
201 }
202 } else {
203 alpha.second.set(0, xdist);
204 }
205 }
206 }
207};
208
210template <class SrcImageIterator, class SrcAccessor,
211 class DestImageIterator, class DestAccessor,
212 class TRANSFORM,
213 class PixelTransform,
215 class Interpolator>
216void transformImageInternAA(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
217 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
218 std::pair<AlphaImageIterator, AlphaAccessor> alpha,
219 TRANSFORM& transform,
221 vigra::Diff2D destUL,
223 bool warparound,
225 bool singleThreaded)
226{
227 const vigra::Diff2D destSize = dest.second - dest.first;
228
229 const int xstart = destUL.x;
230 const int xend = destUL.x + destSize.x;
231 const int ystart = destUL.y;
232 const int yend = destUL.y + destSize.y;
233
234 typedef typename vigra::NumericTraits<typename SrcImageIterator::value_type>::RealPromote RealAccessor;
235 // calculate max level for aa filtering depending on interpolator size
236 const size_t maxLevel = std::floor(std::log2(std::min(destSize.x, destSize.y) / (2 * Interpolator::size)));
237 std::cout << "MaxLevels=" << maxLevel << std::endl;
238 // pyramids stores lower level of source image
239 std::vector<vigra::BasicImage<typename SrcImageIterator::value_type>> pyramids(maxLevel);
240 std::vector<hugin_utils::FDiff2D> scales;
241 size_t w = (src.second - src.first).x;
242 size_t h = (src.second - src.first).y;
243 const size_t w0 = w;
244 const size_t h0 = h;
245 // now generate interpolator for level 0
246 std::vector<vigra_ext::ImageInterpolator<SrcImageIterator, SrcAccessor, Interpolator>> interpolators;
248 scales.push_back(hugin_utils::FDiff2D(1.0, 1.0));
249 // build pyramids and corresponding ImageInterpolators for all levels
250 if (maxLevel > 0)
251 {
252 for (size_t i = 0; i < maxLevel; ++i)
253 {
254 w = (w + 1) >> 1;
255 h = (h + 1) >> 1;
256 pyramids[i].resize(w, h);
257 if (i == 0)
258 {
259 enblend::reduce<RealAccessor>(warparound, src.first, src.second, src.third,
260 pyramids[i].upperLeft(), pyramids[i].lowerRight(), pyramids[i].accessor());
261 }
262 else
263 {
264 enblend::reduce<RealAccessor>(warparound, pyramids[i - 1].upperLeft(), pyramids[i - 1].lowerRight(), pyramids[i - 1].accessor(),
265 pyramids[i].upperLeft(), pyramids[i].lowerRight(), pyramids[i].accessor());
266 };
267 interpolators.push_back(
269 );
270 scales.push_back(hugin_utils::FDiff2D((double)w / w0, (double)h / h0));
271 };
272 };
273
274 // loop over the image and transform
275#pragma omp parallel for if(!singleThreaded) schedule(dynamic)
276 for (int y = ystart; y < yend; ++y)
277 {
278 // create x iterators
280 xd.y += y - ystart;
281 AlphaImageIterator xdm(alpha.first);
282 xdm.y += y - ystart;
283 typename SrcAccessor::value_type tempval;
284 // store last sucessful calculated position to speed up
285 // calculation of scale level for aa interpolator
286 bool last_valid = false;
287 double last_sx, last_sy;
288 for (int x = xstart; x < xend; ++x, ++xd.x, ++xdm.x)
289 {
290 double sx, sy;
291 if (transform.transformImgCoord(sx, sy, x, y))
292 {
293 double scale = 1.0;
294 // last position not valid, calculate new
295 if (!last_valid)
296 {
297 last_valid = transform.transformImgCoord(last_sx, last_sy, x, x + 1);
298 };
299 // calculate scale in x direction
300 if (last_valid)
301 {
302 // calculate scale and make sure it is >=1
303 scale = std::max(std::sqrt((last_sx - sx) * (last_sx - sx) + (last_sy - sy) * (last_sy - sy)), 1.0);
304 };
305 // now calculate scale in y direction
306 double sxy, syy;
307 if (transform.transformImgCoord(sxy, syy, x, y - 1))
308 {
309 scale = std::max(std::sqrt((sxy - sx) * (sxy - sx) + (syy - sy) * (syy - sy)), scale);
310 }
311 else
312 {
313 if (transform.transformImgCoord(sxy, syy, x, y + 1))
314 {
315 scale = std::max(std::sqrt((sxy - sx) * (sxy - sx) + (syy - sy) * (syy - sy)), scale);
316 };
317 };
318 const double fullLevel = std::max<double>(std::min<double>(std::log2(scale) - 1, maxLevel), 0.0);
319 const int level = std::floor(fullLevel);
320 if (x == xstart && y == ystart)
321 {
322 std::cout << "Using level " << level << std::endl;
323 };
324 double sxl, syl;
325 if (level > 0)
326 {
327 sxl = (sx + 0.5) * scales[level].x - 0.5;
328 syl = (sy + 0.5) * scales[level].y - 0.5;
329
330 }
331 else
332 {
333 sxl = sx;
334 syl = sy;
335 };
336 if (interpolators[level].operator()(sxl, syl, tempval))
337 {
338 const double fraction = fullLevel - level;
339 if (fraction > 0.2)
340 {
341 typename SrcAccessor::value_type tempval2;
342 if (interpolators[level + 1]((sx + 0.5)* scales[level + 1].x - 0.5, (sy + 0.5)* scales[level + 1].y - 0.5, tempval2))
343 {
344 tempval = (1.0 - fraction) * tempval + fraction * tempval2;
345 };
346 };
347 // apply pixel transform and write to output
349 alpha.second.set(pixelTransform.hdrWeight(tempval, vigra::UInt8(255)), xdm);
350 }
351 else
352 {
353 alpha.second.set(0, xdm);
354 };
355 last_valid = true;
356 last_sx = sx;
357 last_sy = sy;
358 }
359 else
360 {
361 alpha.second.set(0, xdm);
362 last_valid = false;
363 };
364 };
365 };
366};
367
369template <class SrcImageIterator, class SrcAccessor,
371 class DestImageIterator, class DestAccessor,
372 class TRANSFORM,
373 class PixelTransform,
375 class Interpolator>
376void transformImageAlphaInternAA(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
377 std::pair<SrcAlphaIterator, SrcAlphaAccessor> srcAlpha,
378 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
379 std::pair<AlphaImageIterator, AlphaAccessor> alpha,
380 TRANSFORM& transform,
382 vigra::Diff2D destUL,
384 bool warparound,
386 bool singleThreaded)
387{
388 const vigra::Diff2D destSize = dest.second - dest.first;
389
390 const int xstart = destUL.x;
391 const int xend = destUL.x + destSize.x;
392 const int ystart = destUL.y;
393 const int yend = destUL.y + destSize.y;
394
395 typedef typename vigra::NumericTraits<typename SrcImageIterator::value_type>::RealPromote RealAccessor;
396 typedef typename vigra::NumericTraits<typename SrcAlphaIterator::value_type>::Promote RealAlphaAccessor;
397 // calculate max level for aa filtering depending on interpolator size
398 const size_t maxLevel = std::floor(std::log2(std::min(destSize.x, destSize.y) / (2 * Interpolator::size)));
399 std::cout << "MaxLevels=" << maxLevel << std::endl;
400 // pyramids stores lower level of source image
401 typedef vigra::BasicImage<typename SrcImageIterator::value_type> PyramidImageType;
402 std::vector<PyramidImageType> pyramids(maxLevel);
403 std::vector<vigra::BasicImage<typename SrcAlphaIterator::value_type>> pyramidsMasks(maxLevel);
404 std::vector<hugin_utils::FDiff2D> scales;
405 size_t w = (src.second - src.first).x;
406 size_t h = (src.second - src.first).y;
407 const size_t w0 = w;
408 const size_t h0 = h;
409 std::cout << "(Alpha) Initial size " << w << "x" << h << ", max level=" << maxLevel << std::endl;
410 // now generate interpolator for level 0
411 std::vector<vigra_ext::ImageMaskInterpolator<SrcImageIterator, SrcAccessor, SrcAlphaIterator, SrcAlphaAccessor, Interpolator>> interpolators;
413 scales.push_back(hugin_utils::FDiff2D(1.0, 1.0));
414 // build pyramids and corresponding ImageInterpolators for all levels
415 if (maxLevel > 0)
416 {
417 for (size_t i = 0; i < maxLevel; ++i)
418 {
419 w = (w + 1) >> 1;
420 h = (h + 1) >> 1;
421 pyramids[i].resize(w, h);
422 pyramidsMasks[i].resize(w, h);
423 if (i == 0)
424 {
425 enblend::reduce<RealAccessor, RealAlphaAccessor>(warparound, src.first, src.second, src.third,
426 srcAlpha.first, srcAlpha.second,
427 pyramids[i].upperLeft(), pyramids[i].lowerRight(), pyramids[i].accessor(),
428 pyramidsMasks[i].upperLeft(), pyramidsMasks[i].lowerRight(), pyramidsMasks[i].accessor());
429 }
430 else
431 {
432 enblend::reduce<RealAccessor, RealAlphaAccessor>(warparound, pyramids[i - 1].upperLeft(), pyramids[i - 1].lowerRight(), pyramids[i - 1].accessor(),
433 pyramidsMasks[i - 1].upperLeft(), pyramidsMasks[i - 1].accessor(),
434 pyramids[i].upperLeft(), pyramids[i].lowerRight(), pyramids[i].accessor(),
435 pyramidsMasks[i].upperLeft(), pyramidsMasks[i].lowerRight(), pyramidsMasks[i].accessor());
436 };
437 interpolators.push_back(
439 pyramids[i].upperLeft(), pyramids[i].lowerRight(), src.third,
440 pyramidsMasks[i].upperLeft(), srcAlpha.second,
442 );
443 scales.push_back(hugin_utils::FDiff2D((double)w / w0, (double)h / h0));
444 };
445 };
446
447 // loop over the image and transform
448#pragma omp parallel for if(!singleThreaded) schedule(dynamic)
449 for (int y = ystart; y < yend; ++y)
450 {
451 // create x iterators
453 xd.y += y - ystart;
454 AlphaImageIterator xdist(alpha.first);
455 xdist.y += y - ystart;
456 typename SrcAccessor::value_type tempval;
457 typename SrcAlphaAccessor::value_type alphaval;
458 // store last sucessful calculated position to speed up
459 // calculation of scale level for aa interpolator
460 bool last_valid = false;
461 double last_sx, last_sy;
462 for (int x = xstart; x < xend; ++x, ++xd.x, ++xdist.x)
463 {
464 double sx, sy;
465 if (transform.transformImgCoord(sx, sy, x, y))
466 {
467 double scale = 1.0;
468 // last position not valid, calculate new
469 if (!last_valid)
470 {
471 last_valid = transform.transformImgCoord(last_sx, last_sy, x, x + 1);
472 };
473 // calculate scale in x direction
474 if (last_valid)
475 {
476 // calculate scale and make sure it is >=1
477 scale = std::max(std::sqrt((last_sx - sx) * (last_sx - sx) + (last_sy - sy) * (last_sy - sy)), 1.0);
478 };
479 // now calculate scale in y direction
480 double sxy, syy;
481 if (transform.transformImgCoord(sxy, syy, x, y - 1))
482 {
483 scale = std::max(std::sqrt((sxy - sx) * (sxy - sx) + (syy - sy) * (syy - sy)), scale);
484 }
485 else
486 {
487 if (transform.transformImgCoord(sxy, syy, x, y + 1))
488 {
489 scale = std::max(std::sqrt((sxy - sx) * (sxy - sx) + (syy - sy) * (syy - sy)), scale);
490 };
491 };
492 const double fullLevel = std::max<double>(std::min<double>(std::log2(scale) - 1, maxLevel), 0.0);
493 const int level = std::floor(fullLevel);
494 if (x == xstart && y == ystart)
495 {
496 std::cout << "Using level " << level << std::endl;
497 };
498 double sxl, syl;
499 if (level > 0)
500 {
501 sxl = (sx + 0.5) * scales[level].x - 0.5;
502 syl = (sy + 0.5) * scales[level].y - 0.5;
503 }
504 else
505 {
506 sxl = sx;
507 syl = sy;
508 };
509 // try to interpolate.
510 if (interpolators[level](sxl, syl, tempval, alphaval))
511 {
512 const double fraction = fullLevel - level;
513 if (fraction > 0.2)
514 {
515 typename SrcAccessor::value_type tempval2;
516 typename SrcAlphaAccessor::value_type alphaval2;
517 if (interpolators[level + 1]((sx + 0.5)* scales[level + 1].x - 0.5, (sy + 0.5)* scales[level + 1].y - 0.5, tempval2, alphaval2))
518 {
519 tempval = (1.0 - fraction) * tempval + fraction * tempval2;
521 };
522 };
524 alpha.second.set(pixelTransform.hdrWeight(tempval, alphaval), xdist);
525 }
526 else
527 {
528 // point outside of image or mask
529 alpha.second.set(0, xdist);
530 };
531 last_valid = true;
532 last_sx = sx;
533 last_sy = sy;
534 }
535 else
536 {
537 alpha.second.set(0, xdist);
538 last_valid = false;
539 };
540 };
541 };
542}
543
568template <class SrcImageIterator, class SrcAccessor,
569 class DestImageIterator, class DestAccessor,
571 class TRANSFORM,
572 class PixelTransform>
573void transformImage(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
574 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
575 std::pair<AlphaImageIterator, AlphaAccessor> alpha,
576 vigra::Diff2D destUL,
577 TRANSFORM & transform,
579 bool warparound,
582{
583 switch (interpol) {
584 case INTERP_CUBIC:
585 DEBUG_DEBUG("using cubic interpolator");
589 break;
590 case INTERP_SPLINE_16:
591 DEBUG_DEBUG("interpolator: spline16");
595 break;
596 case INTERP_SPLINE_36:
597 DEBUG_DEBUG("interpolator: spline36");
601 break;
602 case INTERP_SPLINE_64:
603 DEBUG_DEBUG("interpolator: spline64");
607 break;
608 case INTERP_SINC_256:
609 DEBUG_DEBUG("interpolator: sinc 256");
613 break;
614 case INTERP_BILINEAR:
618 break;
623 break;
624 case INTERP_SINC_1024:
628 break;
629 case INTERP_AABOX:
630 std::cout << "TransformImage AA, nearest" << std::endl;
634 break;
636 std::cout << "TransformImage AA, bilinear" << std::endl;
640 break;
641 case INTERP_AACUBIC:
642 std::cout << "TransformImage AA, cubic" << std::endl;
646 break;
647 case INTERP_AALANCZOS:
648 std::cout << "TransformImage AA, Lanzcos" << std::endl;
652 break;
653 }
654}
655
657template <class SrcImageIterator, class SrcAccessor,
659 class DestImageIterator, class DestAccessor,
661 class TRANSFORM, class PixelTransform>
662void transformImageAlpha(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
663 std::pair<SrcAlphaIterator, SrcAlphaAccessor> srcAlpha,
664 vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
665 std::pair<AlphaImageIterator, AlphaAccessor> alpha,
666 vigra::Diff2D destUL,
667 TRANSFORM & transform,
669 bool warparound,
672{
673 switch (interpol) {
674 case INTERP_CUBIC:
675 DEBUG_DEBUG("using cubic interpolator");
679 break;
680 case INTERP_SPLINE_16:
681 DEBUG_DEBUG("interpolator: spline16");
685 break;
686 case INTERP_SPLINE_36:
687 DEBUG_DEBUG("interpolator: spline36");
691 break;
692 case INTERP_SPLINE_64:
693 DEBUG_DEBUG("interpolator: spline64");
697 break;
698 case INTERP_SINC_256:
699 DEBUG_DEBUG("interpolator: sinc 256");
703 break;
704 case INTERP_BILINEAR:
708 break;
713 break;
714 case INTERP_SINC_1024:
718 break;
719 case INTERP_AABOX:
720 std::cout << "TransformImage alpha AA, nearest" << std::endl;
724 break;
726 std::cout << "TransformImage alpha AA, linear" << std::endl;
730 break;
731 case INTERP_AACUBIC:
732 std::cout << "TransformImage alpha AA, cubic" << std::endl;
736 break;
737 case INTERP_AALANCZOS:
738 std::cout << "TransformImage alpha AA, Lanzcos" << std::endl;
742 break;
743 }
744}
745
746}; // namespace
747
748#endif // _VIGRA_EXT_IMAGETRANSFORMS_H
The pano tools interpolators ported to vigra.
"wrapper" for efficient interpolation access to an image
"wrapper" for efficient interpolation access to an image
misc math function & classes used by other parts of the program
#define DEBUG_DEBUG(msg)
Definition utils.h:68
void transformImage(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, vigra::triple< DestImageIterator, DestImageIterator, DestAccessor > dest, std::pair< AlphaImageIterator, AlphaAccessor > alpha, vigra::Diff2D destUL, TRANSFORM &transform, PixelTransform &pixelTransform, bool warparound, Interpolator interpol, AppBase::ProgressDisplay *progress, bool singleThreaded=false)
Transform an image into the panorama.
T zeroNegative(T p)
Set negative elements of a pixel to zero.
void transformImageInternAA(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, vigra::triple< DestImageIterator, DestImageIterator, DestAccessor > dest, std::pair< AlphaImageIterator, AlphaAccessor > alpha, TRANSFORM &transform, PixelTransform &pixelTransform, vigra::Diff2D destUL, Interpolator interp, bool warparound, AppBase::ProgressDisplay *progress, bool singleThreaded)
Transform an image into the panorama using anti-aliasing.
void transformImageAlphaInternAA(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, std::pair< SrcAlphaIterator, SrcAlphaAccessor > srcAlpha, vigra::triple< DestImageIterator, DestImageIterator, DestAccessor > dest, std::pair< AlphaImageIterator, AlphaAccessor > alpha, TRANSFORM &transform, PixelTransform &pixelTransform, vigra::Diff2D destUL, Interpolator interp, bool warparound, AppBase::ProgressDisplay *progress, bool singleThreaded)
transform input images with alpha channel with anti-aliasing
void transformImageAlpha(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, std::pair< SrcAlphaIterator, SrcAlphaAccessor > srcAlpha, vigra::triple< DestImageIterator, DestImageIterator, DestAccessor > dest, std::pair< AlphaImageIterator, AlphaAccessor > alpha, vigra::Diff2D destUL, TRANSFORM &transform, PixelTransform &pixelTransform, bool warparound, Interpolator interpol, AppBase::ProgressDisplay *progress, bool singleThreaded=false)
Transform image, and respect a possible alpha channel.
void transformImageAlphaIntern(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, std::pair< SrcAlphaIterator, SrcAlphaAccessor > srcAlpha, vigra::triple< DestImageIterator, DestImageIterator, DestAccessor > dest, std::pair< AlphaImageIterator, AlphaAccessor > alpha, TRANSFORM &transform, PixelTransform &pixelTransform, vigra::Diff2D destUL, Interpolator interp, bool warparound, AppBase::ProgressDisplay *progress, bool singleThreaded)
transform input images with alpha channel
Interpolator
enum with all interpolation methods
@ INTERP_NEAREST_NEIGHBOUR
void transformImageIntern(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, vigra::triple< DestImageIterator, DestImageIterator, DestAccessor > dest, std::pair< AlphaImageIterator, AlphaAccessor > alpha, TRANSFORM &transform, PixelTransform &pixelTransform, vigra::Diff2D destUL, Interpolator interp, bool warparound, AppBase::ProgressDisplay *progress, bool singleThreaded)
Transform an image into the panorama.
simple bilinear interpolation
cubic interpolation
several classes to calculate interpolator weights,
sinc interpolation, with variable width
spline16 interpolation
spline36 interpolation
spline64 interpolation
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