37 #ifndef VIGRA_RESIZEIMAGE_HXX 
   38 #define VIGRA_RESIZEIMAGE_HXX 
   42 #include "numerictraits.hxx" 
   43 #include "stdimage.hxx" 
   44 #include "recursiveconvolution.hxx" 
   45 #include "separableconvolution.hxx" 
   46 #include "resampling_convolution.hxx" 
   47 #include "splines.hxx" 
   48 #include "multi_shape.hxx" 
  134         return prefilterCoefficients_;
 
  144 ArrayVector<double> CoscotFunction<T>::prefilterCoefficients_;
 
  158 template <
class SrcIterator, 
class SrcAccessor,
 
  159           class DestIterator, 
class DestAccessor>
 
  161 resizeLineNoInterpolation(SrcIterator i1, SrcIterator iend, SrcAccessor as,
 
  162                            DestIterator 
id, DestIterator idend, DestAccessor ad)
 
  164     int wold = iend - i1;
 
  165     int wnew = idend - id;
 
  173     double dx = (double)(wold - 1) / (wnew - 1);
 
  175     for(; 
id != idend; ++id, x += dx)
 
  178         ad.set(as(i1, ix), 
id);
 
  274 template <
class SrcIterator, 
class SrcAccessor,
 
  275           class DestIterator, 
class DestAccessor>
 
  278                       DestIterator 
id, DestIterator idend, DestAccessor da)
 
  280     int w = iend.x - is.x;
 
  281     int h = iend.y - is.y;
 
  283     int wnew = idend.x - 
id.x;
 
  284     int hnew = idend.y - 
id.y;
 
  286     vigra_precondition((w > 1) && (h > 1),
 
  287                  "resizeImageNoInterpolation(): " 
  288                  "Source image too small.\n");
 
  289     vigra_precondition((wnew > 1) && (hnew > 1),
 
  290                  "resizeImageNoInterpolation(): " 
  291                  "Destination image too small.\n");
 
  293     typedef BasicImage<typename SrcAccessor::value_type> TmpImage;
 
  294     typedef typename TmpImage::traverser TmpImageIterator;
 
  296     TmpImage tmp(w, hnew);
 
  298     TmpImageIterator yt = tmp.upperLeft();
 
  300     for(
int x=0; x<w; ++x, ++is.x, ++yt.x)
 
  302         typename SrcIterator::column_iterator c1 = is.columnIterator();
 
  303         typename TmpImageIterator::column_iterator ct = yt.columnIterator();
 
  305         resizeLineNoInterpolation(c1, c1 + h, sa, ct, ct + hnew, tmp.accessor());
 
  308     yt = tmp.upperLeft();
 
  310     for(
int y=0; y < hnew; ++y, ++yt.y, ++
id.y)
 
  312         typename DestIterator::row_iterator rd = 
id.rowIterator();
 
  313         typename TmpImageIterator::row_iterator rt = yt.rowIterator();
 
  315         resizeLineNoInterpolation(rt, rt + w, tmp.accessor(), rd, rd + wnew, da);
 
  319 template <
class SrcIterator, 
class SrcAccessor,
 
  320           class DestIterator, 
class DestAccessor>
 
  323                            triple<DestIterator, DestIterator, DestAccessor> dest)
 
  326                                dest.first, dest.second, dest.third);
 
  329 template <
class T1, 
class S1,
 
  333                            MultiArrayView<2, T2, S2> dest)
 
  336                                destImageRange(dest));
 
  345 template <
class SrcIterator, 
class SrcAccessor,
 
  346           class DestIterator, 
class DestAccessor>
 
  348 resizeLineLinearInterpolation(SrcIterator i1, SrcIterator iend, SrcAccessor as,
 
  349                            DestIterator 
id, DestIterator idend, DestAccessor ad)
 
  351     int wold = iend - i1;
 
  352     int wnew = idend - id;
 
  354     if((wold <= 1) || (wnew <= 1)) 
return; 
 
  357         NumericTraits<typename DestAccessor::value_type> DestTraits;
 
  358     typedef typename DestTraits::RealPromote RealPromote;
 
  360     ad.set(DestTraits::fromRealPromote(as(i1)), 
id);
 
  364     ad.set(DestTraits::fromRealPromote(as(iend)), idend);
 
  366     double dx = (double)(wold - 1) / (wnew - 1);
 
  369     for(; 
id != idend; ++id, x += dx)
 
  379         ad.set(DestTraits::fromRealPromote(RealPromote(x1 * as(i1) + x * as(i1, 1))), 
id);
 
  489 template <
class SrcIterator, 
class SrcAccessor,
 
  490           class DestIterator, 
class DestAccessor>
 
  493                       DestIterator 
id, DestIterator idend, DestAccessor da)
 
  495     int w = iend.x - is.x;
 
  496     int h = iend.y - is.y;
 
  498     int wnew = idend.x - 
id.x;
 
  499     int hnew = idend.y - 
id.y;
 
  501     vigra_precondition((w > 1) && (h > 1),
 
  502                  "resizeImageLinearInterpolation(): " 
  503                  "Source image too small.\n");
 
  504     vigra_precondition((wnew > 1) && (hnew > 1),
 
  505                  "resizeImageLinearInterpolation(): " 
  506                  "Destination image too small.\n");
 
  508     double const scale = 2.0;
 
  510     typedef typename SrcAccessor::value_type SRCVT;
 
  511     typedef typename NumericTraits<SRCVT>::RealPromote TMPTYPE;
 
  512     typedef BasicImage<TMPTYPE> TmpImage;
 
  513     typedef typename TmpImage::traverser TmpImageIterator;
 
  515     BasicImage<TMPTYPE> tmp(w, hnew);
 
  516     BasicImage<TMPTYPE> line((h > w) ? h : w, 1);
 
  520     typename BasicImage<TMPTYPE>::Iterator yt = tmp.upperLeft();
 
  521     typename TmpImageIterator::row_iterator lt = line.upperLeft().rowIterator();
 
  523     for(x=0; x<w; ++x, ++is.x, ++yt.x)
 
  525         typename SrcIterator::column_iterator c1 = is.columnIterator();
 
  526         typename TmpImageIterator::column_iterator ct = yt.columnIterator();
 
  531                  lt, line.accessor(), (double)h/hnew/scale);
 
  533             resizeLineLinearInterpolation(lt, lt + h, line.accessor(),
 
  534                                           ct, ct + hnew, tmp.accessor());
 
  538             resizeLineLinearInterpolation(c1, c1 + h, sa,
 
  539                                           ct, ct + hnew, tmp.accessor());
 
  543     yt = tmp.upperLeft();
 
  545     for(y=0; y < hnew; ++y, ++yt.y, ++
id.y)
 
  547         typename DestIterator::row_iterator rd = 
id.rowIterator();
 
  548         typename TmpImageIterator::row_iterator rt = yt.rowIterator();
 
  553                               lt, line.accessor(), (double)w/wnew/scale);
 
  555             resizeLineLinearInterpolation(lt, lt + w, line.accessor(),
 
  560             resizeLineLinearInterpolation(rt, rt + w, tmp.accessor(),
 
  566 template <
class SrcIterator, 
class SrcAccessor,
 
  567           class DestIterator, 
class DestAccessor>
 
  570                                triple<DestIterator, DestIterator, DestAccessor> dest)
 
  573                                    dest.first, dest.second, dest.third);
 
  576 template <
class T1, 
class S1,
 
  580                                MultiArrayView<2, T2, S2> dest)
 
  583                                    destImageRange(dest));
 
  720 template <
class SrcIterator, 
class SrcAccessor,
 
  721           class DestIterator, 
class DestAccessor,
 
  725     SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc,
 
  726     DestIterator dest_iter, DestIterator dest_iter_end, DestAccessor dest_acc,
 
  727     SPLINE 
const & spline)
 
  730     int width_old = src_iter_end.x - src_iter.x;
 
  731     int height_old = src_iter_end.y - src_iter.y;
 
  733     int width_new = dest_iter_end.x - dest_iter.x;
 
  734     int height_new = dest_iter_end.y - dest_iter.y;
 
  736     vigra_precondition((width_old > 1) && (height_old > 1),
 
  737                  "resizeImageSplineInterpolation(): " 
  738                  "Source image too small.\n");
 
  740     vigra_precondition((width_new > 1) && (height_new > 1),
 
  741                  "resizeImageSplineInterpolation(): " 
  742                  "Destination image too small.\n");
 
  744     Rational<int> xratio(width_new - 1, width_old - 1);
 
  745     Rational<int> yratio(height_new - 1, height_old - 1);
 
  746     Rational<int> offset(0);
 
  747     resampling_detail::MapTargetToSourceCoordinate xmapCoordinate(xratio, offset);
 
  748     resampling_detail::MapTargetToSourceCoordinate ymapCoordinate(yratio, offset);
 
  749     int xperiod = 
lcm(xratio.numerator(), xratio.denominator());
 
  750     int yperiod = 
lcm(yratio.numerator(), yratio.denominator());
 
  752     double const scale = 2.0;
 
  754     typedef typename SrcAccessor::value_type SRCVT;
 
  755     typedef typename NumericTraits<SRCVT>::RealPromote TMPTYPE;
 
  756     typedef BasicImage<TMPTYPE> TmpImage;
 
  757     typedef typename TmpImage::traverser TmpImageIterator;
 
  759     BasicImage<TMPTYPE> tmp(width_old, height_new);
 
  761     BasicImage<TMPTYPE> line((height_old > width_old) ? height_old : width_old, 1);
 
  762     typename BasicImage<TMPTYPE>::Accessor tmp_acc = tmp.accessor();
 
  763     ArrayVector<double> 
const & prefilterCoeffs = spline.prefilterCoefficients();
 
  767     ArrayVector<Kernel1D<double> > kernels(yperiod);
 
  768     createResamplingKernels(spline, ymapCoordinate, kernels);
 
  770     typename BasicImage<TMPTYPE>::Iterator y_tmp = tmp.upperLeft();
 
  771     typename TmpImageIterator::row_iterator line_tmp = line.upperLeft().rowIterator();
 
  773     for(x=0; x<width_old; ++x, ++src_iter.x, ++y_tmp.x)
 
  776         typename SrcIterator::column_iterator c_src = src_iter.columnIterator();
 
  777         typename TmpImageIterator::column_iterator c_tmp = y_tmp.columnIterator();
 
  779         if(prefilterCoeffs.size() == 0)
 
  781             if(height_new >= height_old)
 
  784                                        c_tmp, c_tmp + height_new, tmp_acc,
 
  785                                        kernels, ymapCoordinate);
 
  790                      line_tmp, line.accessor(), (double)height_old/height_new/scale);
 
  792                                        c_tmp, c_tmp + height_new, tmp_acc,
 
  793                                        kernels, ymapCoordinate);
 
  799                                 line_tmp, line.accessor(),
 
  800                                 prefilterCoeffs[0], BORDER_TREATMENT_REFLECT);
 
  801             for(
unsigned int b = 1; b < prefilterCoeffs.size(); ++b)
 
  804                                     line_tmp, line.accessor(),
 
  805                                     prefilterCoeffs[b], BORDER_TREATMENT_REFLECT);
 
  807             if(height_new < height_old)
 
  810                      line_tmp, line.accessor(), (double)height_old/height_new/scale);
 
  813                                    c_tmp, c_tmp + height_new, tmp_acc,
 
  814                                    kernels, ymapCoordinate);
 
  818     y_tmp = tmp.upperLeft();
 
  820     kernels.resize(xperiod);
 
  821     createResamplingKernels(spline, xmapCoordinate, kernels);
 
  823     for(y=0; y < height_new; ++y, ++y_tmp.y, ++dest_iter.y)
 
  825         typename DestIterator::row_iterator r_dest = dest_iter.rowIterator();
 
  826         typename TmpImageIterator::row_iterator r_tmp = y_tmp.rowIterator();
 
  828         if(prefilterCoeffs.size() == 0)
 
  830             if(width_new >= width_old)
 
  833                                        r_dest, r_dest + width_new, dest_acc,
 
  834                                        kernels, xmapCoordinate);
 
  839                                   line_tmp, line.accessor(), (double)width_old/width_new/scale);
 
  841                                        r_dest, r_dest + width_new, dest_acc,
 
  842                                        kernels, xmapCoordinate);
 
  848                                 line_tmp, line.accessor(),
 
  849                                 prefilterCoeffs[0], BORDER_TREATMENT_REFLECT);
 
  850             for(
unsigned int b = 1; b < prefilterCoeffs.size(); ++b)
 
  853                                     line_tmp, line.accessor(),
 
  854                                     prefilterCoeffs[b], BORDER_TREATMENT_REFLECT);
 
  856             if(width_new < width_old)
 
  859                                     line_tmp, line.accessor(), (double)width_old/width_new/scale);
 
  862                                    r_dest, r_dest + width_new, dest_acc,
 
  863                                    kernels, xmapCoordinate);
 
  868 template <
class SrcIterator, 
class SrcAccessor,
 
  869           class DestIterator, 
class DestAccessor>
 
  872                       DestIterator 
id, DestIterator idend, DestAccessor da)
 
  877 template <
class SrcIterator, 
class SrcAccessor,
 
  878           class DestIterator, 
class DestAccessor,
 
  882                                triple<DestIterator, DestIterator, DestAccessor> dest,
 
  883                                SPLINE 
const & spline)
 
  886                                    dest.first, dest.second, dest.third, spline);
 
  889 template <
class SrcIterator, 
class SrcAccessor,
 
  890           class DestIterator, 
class DestAccessor>
 
  893                                triple<DestIterator, DestIterator, DestAccessor> dest)
 
  896                                    dest.first, dest.second, dest.third);
 
  899 template <
class T1, 
class S1,
 
  904                                MultiArrayView<2, T2, S2> dest,
 
  905                                SPLINE 
const & spline)
 
  908                                    destImageRange(dest), spline);
 
  911 template <
class T1, 
class S1,
 
  915                                MultiArrayView<2, T2, S2> dest)
 
  918                                    destImageRange(dest));
 
  982 template <
class SrcIterator, 
class SrcAccessor,
 
  983           class DestIterator, 
class DestAccessor>
 
  986                       DestIterator dest_iter, DestIterator dest_iter_end, DestAccessor dest_acc)
 
  989                                   CatmullRomSpline<double>());
 
  992 template <
class SrcIterator, 
class SrcAccessor,
 
  993           class DestIterator, 
class DestAccessor>
 
  996                                    triple<DestIterator, DestIterator, DestAccessor> dest)
 
  999                                        dest.first, dest.second, dest.third);
 
 1002 template <
class T1, 
class S1,
 
 1006                                    MultiArrayView<2, T2, S2> dest)
 
 1009                                        destImageRange(dest));
 
 1074 template <
class SrcIterator, 
class SrcAccessor,
 
 1075           class DestIterator, 
class DestAccessor>
 
 1078                       DestIterator dest_iter, DestIterator dest_iter_end, DestAccessor dest_acc)
 
 1081                                    CoscotFunction<double>());
 
 1084 template <
class SrcIterator, 
class SrcAccessor,
 
 1085           class DestIterator, 
class DestAccessor>
 
 1088                                triple<DestIterator, DestIterator, DestAccessor> dest)
 
 1091                                    dest.first, dest.second, dest.third);
 
 1094 template <
class T1, 
class S1,
 
 1098                                MultiArrayView<2, T2, S2> dest)
 
 1101                                    destImageRange(dest));
 
 1108 #endif // VIGRA_RESIZEIMAGE_HXX 
Definition: resizeimage.hxx:82
result_type operator()(argument_type x) const 
Definition: resizeimage.hxx:103
linalg::TemporaryMatrix< T > sin(MultiArrayView< 2, T, C > const &v)
void recursiveSmoothLine(...)
Convolves the image with a 1-dimensional exponential filter. 
double radius() const 
Definition: resizeimage.hxx:121
unsigned int derivativeOrder() const 
Definition: resizeimage.hxx:126
T argument_type
Definition: resizeimage.hxx:91
value_type operator[](value_type x) const 
Definition: resizeimage.hxx:115
void recursiveFilterLine(...)
Performs a 1-dimensional recursive convolution of the source signal. 
IntType lcm(IntType n, IntType m)
Definition: rational.hxx:122
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays. 
T result_type
Definition: resizeimage.hxx:94
T value_type
Definition: resizeimage.hxx:88
FFTWComplex< R >::NormType abs(const FFTWComplex< R > &a)
absolute value (= magnitude) 
Definition: fftw3.hxx:1002
ArrayVector< double > const & prefilterCoefficients() const 
Definition: resizeimage.hxx:132
linalg::TemporaryMatrix< T > tan(MultiArrayView< 2, T, C > const &v)
linalg::TemporaryMatrix< T > cos(MultiArrayView< 2, T, C > const &v)
void resamplingConvolveLine(...)
Performs a 1-dimensional resampling convolution of the source signal using the given set of kernels...