36#ifndef VIGRA_SPLINEIMAGEVIEW_HXX
37#define VIGRA_SPLINEIMAGEVIEW_HXX
39#include "mathutil.hxx"
40#include "recursiveconvolution.hxx"
42#include "array_vector.hxx"
43#include "basicimage.hxx"
44#include "copyimage.hxx"
45#include "tinyvector.hxx"
46#include "fixedpoint.hxx"
47#include "multi_array.hxx"
98template <
int ORDER,
class VALUETYPE>
101 typedef typename NumericTraits<VALUETYPE>::RealPromote InternalValue;
131 typedef typename InternalTraverser::row_iterator InternalRowIterator;
132 typedef typename InternalTraverser::column_iterator InternalColumnIterator;
135 constexpr static int ksize_ =
ORDER + 1;
136 constexpr static int kcenter_ =
ORDER / 2;
147 template <
class U,
class S>
149 : w_(s.
shape(0)), h_(s.
shape(1)), w1_(w_-1), h1_(h_-1),
150 x0_(kcenter_), x1_(w_ - kcenter_ - 2), y0_(kcenter_), y1_(h_ - kcenter_ - 2),
155 copyImage(srcImageRange(s), destImage(image_));
167 template <
class SrcIterator,
class SrcAccessor>
169 : w_(
iend.x -
is.x), h_(
iend.y -
is.y), w1_(w_-1), h1_(h_-1),
170 x0_(kcenter_), x1_(w_ - kcenter_ - 2), y0_(kcenter_), y1_(h_ - kcenter_ - 2),
187 template <
class SrcIterator,
class SrcAccessor>
189 : w_(s.second.x - s.first.x), h_(s.second.y - s.first.y), w1_(w_-1), h1_(h_-1),
190 x0_(kcenter_), x1_(w_ - kcenter_ - 2), y0_(kcenter_), y1_(h_ - kcenter_ - 2),
195 copyImage(srcIterRange(s.first, s.second, s.third), destImage(image_));
284 {
return dx(d[0], d[1]); }
290 {
return dy(d[0], d[1]); }
296 {
return dxx(d[0], d[1]); }
302 {
return dxy(d[0], d[1]); }
308 {
return dyy(d[0], d[1]); }
314 {
return dx3(d[0], d[1]); }
320 {
return dy3(d[0], d[1]); }
326 {
return dxxy(d[0], d[1]); }
332 {
return dxyy(d[0], d[1]); }
366 {
return g2(d[0], d[1]); }
372 {
return g2x(d[0], d[1]); }
378 {
return g2y(d[0], d[1]); }
384 {
return g2xx(d[0], d[1]); }
390 {
return g2xy(d[0], d[1]); }
396 {
return g2yy(d[0], d[1]); }
466 template <
class Array>
474 return x >= 0.0 && x <=
width()-1.0;
482 return y >= 0.0 && y <=
height()-1.0;
512 x0 = VIGRA_CSTD::floor((
ORDER % 2) ?
x0 :
x0 + 0.5);
513 y0 = VIGRA_CSTD::floor((
ORDER % 2) ?
y0 :
y0 + 0.5);
514 x1 = VIGRA_CSTD::floor((
ORDER % 2) ?
x1 :
x1 + 0.5);
515 y1 = VIGRA_CSTD::floor((
ORDER % 2) ?
y1 :
y1 + 0.5);
522 void calculateIndices(
double x,
double y)
const;
523 void coefficients(
double t,
double *
const & c)
const;
524 void derivCoefficients(
double t,
unsigned int d,
double *
const & c)
const;
529 double x0_, x1_, y0_, y1_;
532 mutable double x_, y_, u_, v_, kx_[ksize_], ky_[ksize_];
533 mutable int ix_[ksize_], iy_[ksize_];
536template <
int ORDER,
class VALUETYPE>
537void SplineImageView<ORDER, VALUETYPE>::init()
539 ArrayVector<double>
const & b = k_.prefilterCoefficients();
541 for(
unsigned int i=0;
i<b.size(); ++
i)
543 recursiveFilterX(srcImageRange(image_), destImage(image_), b[
i], BORDER_TREATMENT_REFLECT);
544 recursiveFilterY(srcImageRange(image_), destImage(image_), b[
i], BORDER_TREATMENT_REFLECT);
552struct SplineImageViewUnrollLoop1
554 template <
class Array>
555 static void exec(
int c0, Array c)
557 SplineImageViewUnrollLoop1<i-1>::exec(c0, c);
563struct SplineImageViewUnrollLoop1<0>
565 template <
class Array>
566 static void exec(
int c0, Array c)
572template <
int i,
class ValueType>
573struct SplineImageViewUnrollLoop2
575 template <
class Array1,
class RowIterator,
class Array2>
577 exec(Array1 k, RowIterator r, Array2 x)
579 return ValueType(k[i] * r[x[i]]) + SplineImageViewUnrollLoop2<i-1, ValueType>::exec(k, r, x);
583template <
class ValueType>
584struct SplineImageViewUnrollLoop2<0, ValueType>
586 template <
class Array1,
class RowIterator,
class Array2>
588 exec(Array1 k, RowIterator r, Array2 x)
590 return ValueType(k[0] * r[x[0]]);
596template <
int ORDER,
class VALUETYPE>
598SplineImageView<ORDER, VALUETYPE>::calculateIndices(
double x,
double y)
const
600 if(x == x_ && y == y_)
605 detail::SplineImageViewUnrollLoop1<ORDER>::exec(
606 (
ORDER % 2) ?
int(x - kcenter_) :
int(x + 0.5 - kcenter_), ix_);
607 detail::SplineImageViewUnrollLoop1<ORDER>::exec(
608 (
ORDER % 2) ?
int(y - kcenter_) :
int(y + 0.5 - kcenter_), iy_);
610 u_ = x - ix_[kcenter_];
611 v_ = y - iy_[kcenter_];
615 vigra_precondition(isValid(x,y),
616 "SplineImageView::calculateIndices(): coordinates out of range.");
619 (
int)VIGRA_CSTD::floor(x) :
622 (
int)VIGRA_CSTD::floor(y) :
627 for(
int i = 0;
i < ksize_; ++
i)
628 ix_[
i] = w1_ - vigra::abs(w1_ -
xCenter - (
i - kcenter_));
632 for(
int i = 0;
i < ksize_; ++
i)
633 ix_[
i] = vigra::abs(
xCenter - (kcenter_ -
i));
637 for(
int i = 0;
i < ksize_; ++
i)
638 iy_[
i] = h1_ - vigra::abs(h1_ -
yCenter - (
i - kcenter_));
642 for(
int i = 0;
i < ksize_; ++
i)
643 iy_[
i] = vigra::abs(
yCenter - (kcenter_ -
i));
652template <
int ORDER,
class VALUETYPE>
653void SplineImageView<ORDER, VALUETYPE>::coefficients(
double t,
double *
const & c)
const
656 for(
int i = 0;
i<ksize_; ++
i)
660template <
int ORDER,
class VALUETYPE>
661void SplineImageView<ORDER, VALUETYPE>::derivCoefficients(
double t,
662 unsigned int d,
double *
const & c)
const
665 for(
int i = 0;
i<ksize_; ++
i)
669template <
int ORDER,
class VALUETYPE>
670VALUETYPE SplineImageView<ORDER, VALUETYPE>::convolve()
const
675 ky_[0]*detail::SplineImageViewUnrollLoop2<ORDER, RealPromote>::exec(kx_, image_.rowBegin(iy_[0]), ix_));
677 for(
int j=1;
j<ksize_; ++
j)
680 ky_[
j]*detail::SplineImageViewUnrollLoop2<ORDER, RealPromote>::exec(kx_, image_.rowBegin(iy_[
j]), ix_));
682 return detail::RequiresExplicitCast<VALUETYPE>::cast(
sum);
685template <
int ORDER,
class VALUETYPE>
686template <
class Array>
690 typedef typename Array::value_type
ResType;
694 calculateIndices(x, y);
695 for(
int j=0;
j<ksize_; ++
j)
697 for(
int i=0;
i<ksize_; ++
i)
700 for(
int k=0;
k<ksize_; ++
k)
702 tmp[
i][
j] += weights[
i][
k]*image_(ix_[
k], iy_[
j]);
706 for(
int j=0;
j<ksize_; ++
j)
708 for(
int i=0;
i<ksize_; ++
i)
711 for(
int k=0;
k<ksize_; ++
k)
719template <
int ORDER,
class VALUETYPE>
722 calculateIndices(x, y);
723 coefficients(u_, kx_);
724 coefficients(v_, ky_);
728template <
int ORDER,
class VALUETYPE>
730 unsigned int dx,
unsigned int dy)
const
732 calculateIndices(x, y);
733 derivCoefficients(u_, dx, kx_);
734 derivCoefficients(v_, dy, ky_);
738template <
int ORDER,
class VALUETYPE>
745template <
int ORDER,
class VALUETYPE>
749 return SquaredNormType(2.0)*(dot(dx(x,y), dxx(x,y)) + dot(dy(x,y), dxy(x,y)));
752template <
int ORDER,
class VALUETYPE>
756 return SquaredNormType(2.0)*(dot(dx(x,y), dxy(x,y)) + dot(dy(x,y), dyy(x,y)));
759template <
int ORDER,
class VALUETYPE>
767template <
int ORDER,
class VALUETYPE>
775template <
int ORDER,
class VALUETYPE>
779 return SquaredNormType(2.0)*(dot(dx(x,y), dxxy(x,y)) + dot(dy(x,y), dxyy(x,y)) +
780 dot(dxy(x,y), dxx(x,y) + dyy(x,y)));
788template <
class VALUETYPE,
class INTERNAL_INDEXER>
789class SplineImageView0Base
791 typedef typename INTERNAL_INDEXER::value_type InternalValue;
794 typedef typename NormTraits<VALUETYPE>::SquaredNormType SquaredNormType;
797 enum StaticOrder { order = 0 };
801 SplineImageView0Base(
unsigned int w,
unsigned int h)
805 SplineImageView0Base(
int w,
int h, INTERNAL_INDEXER i)
806 : w_(w), h_(h), internalIndexer_(i)
809 template <
unsigned IntBits1,
unsigned FractionalBits1,
810 unsigned IntBits2,
unsigned FractionalBits2>
811 value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x,
812 FixedPoint<IntBits2, FractionalBits2> y)
const
817 template <
unsigned IntBits1,
unsigned FractionalBits1,
818 unsigned IntBits2,
unsigned FractionalBits2>
819 value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x,
820 FixedPoint<IntBits2, FractionalBits2> y,
821 unsigned int dx,
unsigned int dy)
const
823 if((dx != 0) || (dy != 0))
824 return NumericTraits<VALUETYPE>::zero();
825 return unchecked(x, y);
828 value_type unchecked(
double x,
double y)
const
830 return internalIndexer_((
int)(x + 0.5), (
int)(y + 0.5));
833 value_type unchecked(
double x,
double y,
unsigned int dx,
unsigned int dy)
const
835 if((dx != 0) || (dy != 0))
836 return NumericTraits<VALUETYPE>::zero();
837 return unchecked(x, y);
840 value_type operator()(
double x,
double y)
const
845 ix = (int)(-x + 0.5);
846 vigra_precondition(ix <= (
int)w_ - 1,
847 "SplineImageView::operator(): coordinates out of range.");
855 vigra_precondition(ix >= 0,
856 "SplineImageView::operator(): coordinates out of range.");
861 iy = (int)(-y + 0.5);
862 vigra_precondition(iy <= (
int)h_ - 1,
863 "SplineImageView::operator(): coordinates out of range.");
871 vigra_precondition(iy >= 0,
872 "SplineImageView::operator(): coordinates out of range.");
875 return internalIndexer_(ix, iy);
878 value_type operator()(
double x,
double y,
unsigned int dx,
unsigned int dy)
const
880 if((dx != 0) || (dy != 0))
881 return NumericTraits<VALUETYPE>::zero();
882 return operator()(x, y);
885 value_type dx(
double ,
double )
const
886 {
return NumericTraits<VALUETYPE>::zero(); }
888 value_type dy(
double ,
double )
const
889 {
return NumericTraits<VALUETYPE>::zero(); }
891 value_type dxx(
double ,
double )
const
892 {
return NumericTraits<VALUETYPE>::zero(); }
894 value_type dxy(
double ,
double )
const
895 {
return NumericTraits<VALUETYPE>::zero(); }
897 value_type dyy(
double ,
double )
const
898 {
return NumericTraits<VALUETYPE>::zero(); }
900 value_type dx3(
double ,
double )
const
901 {
return NumericTraits<VALUETYPE>::zero(); }
903 value_type dy3(
double ,
double )
const
904 {
return NumericTraits<VALUETYPE>::zero(); }
906 value_type dxxy(
double ,
double )
const
907 {
return NumericTraits<VALUETYPE>::zero(); }
909 value_type dxyy(
double ,
double )
const
910 {
return NumericTraits<VALUETYPE>::zero(); }
912 value_type operator()(difference_type
const & d)
const
913 {
return operator()(d[0], d[1]); }
915 value_type operator()(difference_type
const & d,
unsigned int dx,
unsigned int dy)
const
916 {
return operator()(d[0], d[1], dx, dy); }
918 value_type dx(difference_type
const & )
const
919 {
return NumericTraits<VALUETYPE>::zero(); }
921 value_type dy(difference_type
const & )
const
922 {
return NumericTraits<VALUETYPE>::zero(); }
924 value_type dxx(difference_type
const & )
const
925 {
return NumericTraits<VALUETYPE>::zero(); }
927 value_type dxy(difference_type
const & )
const
928 {
return NumericTraits<VALUETYPE>::zero(); }
930 value_type dyy(difference_type
const & )
const
931 {
return NumericTraits<VALUETYPE>::zero(); }
933 value_type dx3(difference_type
const & )
const
934 {
return NumericTraits<VALUETYPE>::zero(); }
936 value_type dy3(difference_type
const & )
const
937 {
return NumericTraits<VALUETYPE>::zero(); }
939 value_type dxxy(difference_type
const & )
const
940 {
return NumericTraits<VALUETYPE>::zero(); }
942 value_type dxyy(difference_type
const & )
const
943 {
return NumericTraits<VALUETYPE>::zero(); }
945 SquaredNormType g2(
double ,
double )
const
946 {
return NumericTraits<SquaredNormType>::zero(); }
948 SquaredNormType g2x(
double ,
double )
const
949 {
return NumericTraits<SquaredNormType>::zero(); }
951 SquaredNormType g2y(
double ,
double )
const
952 {
return NumericTraits<SquaredNormType>::zero(); }
954 SquaredNormType g2xx(
double ,
double )
const
955 {
return NumericTraits<SquaredNormType>::zero(); }
957 SquaredNormType g2xy(
double ,
double )
const
958 {
return NumericTraits<SquaredNormType>::zero(); }
960 SquaredNormType g2yy(
double ,
double )
const
961 {
return NumericTraits<SquaredNormType>::zero(); }
963 SquaredNormType g2(difference_type
const & )
const
964 {
return NumericTraits<SquaredNormType>::zero(); }
966 SquaredNormType g2x(difference_type
const & )
const
967 {
return NumericTraits<SquaredNormType>::zero(); }
969 SquaredNormType g2y(difference_type
const & )
const
970 {
return NumericTraits<SquaredNormType>::zero(); }
972 SquaredNormType g2xx(difference_type
const & )
const
973 {
return NumericTraits<SquaredNormType>::zero(); }
975 SquaredNormType g2xy(difference_type
const & )
const
976 {
return NumericTraits<SquaredNormType>::zero(); }
978 SquaredNormType g2yy(difference_type
const & )
const
979 {
return NumericTraits<SquaredNormType>::zero(); }
981 unsigned int width()
const
984 unsigned int height()
const
987 size_type size()
const
988 {
return size_type(w_, h_); }
990 TinyVector<unsigned int, 2> shape()
const
991 {
return TinyVector<unsigned int, 2>(w_, h_); }
993 template <
class Array>
994 void coefficientArray(
double x,
double y, Array & res)
const
996 res(0, 0) = operator()(x,y);
999 bool isInsideX(
double x)
const
1001 return x >= 0.0 && x <= width() - 1.0;
1004 bool isInsideY(
double y)
const
1006 return y >= 0.0 && y <= height() - 1.0;
1009 bool isInside(
double x,
double y)
const
1011 return isInsideX(x) && isInsideY(y);
1014 bool isValid(
double x,
double y)
const
1016 return x < 2.0*w_-2.0 && x > 1.0-w_ && y < 2.0*h_-2.0 && y > 1.0-h_;
1019 bool sameFacet(
double x0,
double y0,
double x1,
double y1)
const
1021 x0 = VIGRA_CSTD::floor(x0 + 0.5);
1022 y0 = VIGRA_CSTD::floor(y0 + 0.5);
1023 x1 = VIGRA_CSTD::floor(x1 + 0.5);
1024 y1 = VIGRA_CSTD::floor(y1 + 0.5);
1025 return x0 == x1 && y0 == y1;
1029 unsigned int w_, h_;
1030 INTERNAL_INDEXER internalIndexer_;
1042template <class VALUETYPE, class INTERNAL_TRAVERSER = typename BasicImage<VALUETYPE>::const_traverser>
1044:
public SplineImageView0Base<VALUETYPE, INTERNAL_TRAVERSER>
1051 typedef typename Base::difference_type difference_type;
1052 enum StaticOrder { order = Base::order };
1071 :
Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first)
1079 :
Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first)
1082 template<
class T,
class SU>
1084 :
Base(
i.shape(0),
i.shape(1)),
1085 image_(
i.shape(0),
i.shape(1))
1087 for(
unsigned int y=0; y<this->height(); ++y)
1088 for(
unsigned int x=0; x<this->width(); ++x)
1089 image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast(
i(x,y));
1090 this->internalIndexer_ = image_.
upperLeft();
1093 template <
class SrcIterator,
class SrcAccessor>
1099 this->internalIndexer_ = image_.
upperLeft();
1102 template <
class SrcIterator,
class SrcAccessor>
1104 :
Base(s.second.x - s.first.x, s.second.y - s.first.y),
1105 image_(s.second - s.first)
1108 this->internalIndexer_ = image_.
upperLeft();
1118template <
class VALUETYPE,
class Str
idedOrUnstr
ided>
1120:
public SplineImageView0Base<VALUETYPE, MultiArrayView<2, VALUETYPE, StridedOrUnstrided> >
1126 typedef typename Base::size_type size_type;
1127 typedef typename Base::difference_type difference_type;
1128 enum StaticOrder { order = Base::order };
1129 typedef BasicImage<VALUETYPE> InternalImage;
1132 typedef MultiArrayView<2, VALUETYPE, StridedOrUnstrided> InternalIndexer;
1139 SplineImageView0(InternalIndexer
const & i)
1140 : Base(i.shape(0), i.shape(1), i)
1143 template<
class T,
class SU>
1144 SplineImageView0(MultiArrayView<2, T, SU>
const & i)
1145 : Base(i.shape(0), i.shape(1)),
1146 image_(i.shape(0), i.shape(1))
1148 for(
unsigned int y=0; y<this->height(); ++y)
1149 for(
unsigned int x=0; x<this->width(); ++x)
1150 image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast(i(x,y));
1151 this->internalIndexer_ = InternalIndexer(
typename InternalIndexer::difference_type(this->width(), this->height()),
1155 template <
class SrcIterator,
class SrcAccessor>
1156 SplineImageView0(SrcIterator is, SrcIterator iend, SrcAccessor sa)
1157 : Base(iend.x - is.x, iend.y - is.y),
1160 copyImage(srcIterRange(is, iend, sa), destImage(image_));
1161 this->internalIndexer_ = InternalIndexer(
typename InternalIndexer::difference_type(this->width(), this->height()),
1165 template <
class SrcIterator,
class SrcAccessor>
1166 SplineImageView0(triple<SrcIterator, SrcIterator, SrcAccessor> s)
1167 : Base(s.second.x - s.first.x, s.second.y - s.first.y),
1168 image_(s.second - s.first)
1171 this->internalIndexer_ = InternalIndexer(
typename InternalIndexer::difference_type(this->width(), this->height()),
1175 InternalImage
const & image()
const
1179 InternalImage image_;
1182template <
class VALUETYPE>
1183class SplineImageView<0, VALUETYPE>
1184:
public SplineImageView0<VALUETYPE>
1186 typedef SplineImageView0<VALUETYPE> Base;
1188 typedef typename Base::value_type
value_type;
1190 typedef typename Base::size_type
size_type;
1192 enum StaticOrder {
order = Base::order };
1196 typedef typename Base::InternalTraverser InternalTraverser;
1197 typedef typename Base::InternalAccessor InternalAccessor;
1198 typedef typename Base::InternalConstTraverser InternalConstTraverser;
1199 typedef typename Base::InternalConstAccessor InternalConstAccessor;
1206 SplineImageView(InternalTraverser is, InternalTraverser iend, InternalAccessor sa,
bool =
false)
1207 : Base(is, iend, sa)
1210 SplineImageView(triple<InternalTraverser, InternalTraverser, InternalAccessor> s,
bool =
false)
1214 SplineImageView(InternalConstTraverser is, InternalConstTraverser iend, InternalConstAccessor sa,
bool =
false)
1215 : Base(is, iend, sa)
1218 SplineImageView(triple<InternalConstTraverser, InternalConstTraverser, InternalConstAccessor> s,
bool =
false)
1222 template <
class SrcIterator,
class SrcAccessor>
1223 SplineImageView(SrcIterator is, SrcIterator iend, SrcAccessor sa,
bool =
false)
1224 : Base(is, iend, sa)
1226 copyImage(srcIterRange(is, iend, sa), destImage(this->image_));
1229 template <
class SrcIterator,
class SrcAccessor>
1230 SplineImageView(triple<SrcIterator, SrcIterator, SrcAccessor> s,
bool =
false)
1242template <
class VALUETYPE,
class INTERNAL_INDEXER>
1243class SplineImageView1Base
1245 typedef typename INTERNAL_INDEXER::value_type InternalValue;
1247 typedef VALUETYPE value_type;
1248 typedef Size2D size_type;
1249 typedef typename NormTraits<VALUETYPE>::SquaredNormType SquaredNormType;
1250 typedef TinyVector<double, 2> difference_type;
1251 enum StaticOrder { order = 1 };
1255 SplineImageView1Base(
unsigned int w,
unsigned int h)
1259 SplineImageView1Base(
int w,
int h, INTERNAL_INDEXER i)
1260 : w_(w), h_(h), internalIndexer_(i)
1263 template <
unsigned IntBits1,
unsigned FractionalBits1,
1264 unsigned IntBits2,
unsigned FractionalBits2>
1265 value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x,
1266 FixedPoint<IntBits2, FractionalBits2> y)
const
1269 FixedPoint<0, FractionalBits1> tx =
frac(x - FixedPoint<IntBits1, FractionalBits1>(ix));
1270 FixedPoint<0, FractionalBits1> dtx =
dual_frac(tx);
1271 if(ix == (
int)w_ - 1)
1274 tx.value = FixedPoint<0, FractionalBits1>::ONE;
1278 FixedPoint<0, FractionalBits2> ty =
frac(y - FixedPoint<IntBits2, FractionalBits2>(iy));
1279 FixedPoint<0, FractionalBits2> dty =
dual_frac(ty);
1280 if(iy == (
int)h_ - 1)
1283 ty.value = FixedPoint<0, FractionalBits2>::ONE;
1286 return fixed_point_cast<value_type>(
1287 dty*(dtx*fixedPoint(internalIndexer_(ix,iy)) +
1288 tx*fixedPoint(internalIndexer_(ix+1,iy))) +
1289 ty *(dtx*fixedPoint(internalIndexer_(ix,iy+1)) +
1290 tx*fixedPoint(internalIndexer_(ix+1,iy+1))));
1293 template <
unsigned IntBits1,
unsigned FractionalBits1,
1294 unsigned IntBits2,
unsigned FractionalBits2>
1295 value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x,
1296 FixedPoint<IntBits2, FractionalBits2> y,
1297 unsigned int dx,
unsigned int dy)
const
1300 FixedPoint<0, FractionalBits1> tx =
frac(x - FixedPoint<IntBits1, FractionalBits1>(ix));
1301 FixedPoint<0, FractionalBits1> dtx =
dual_frac(tx);
1302 if(ix == (
int)w_ - 1)
1305 tx.value = FixedPoint<0, FractionalBits1>::ONE;
1309 FixedPoint<0, FractionalBits2> ty =
frac(y - FixedPoint<IntBits2, FractionalBits2>(iy));
1310 FixedPoint<0, FractionalBits2> dty =
dual_frac(ty);
1311 if(iy == (
int)h_ - 1)
1314 ty.value = FixedPoint<0, FractionalBits2>::ONE;
1323 return fixed_point_cast<value_type>(
1324 dty*(dtx*fixedPoint(internalIndexer_(ix,iy)) +
1325 tx*fixedPoint(internalIndexer_(ix+1,iy))) +
1326 ty *(dtx*fixedPoint(internalIndexer_(ix,iy+1)) +
1327 tx*fixedPoint(internalIndexer_(ix+1,iy+1))));
1329 return fixed_point_cast<value_type>(
1330 (dtx*fixedPoint(internalIndexer_(ix,iy+1)) + tx*fixedPoint(internalIndexer_(ix+1,iy+1))) -
1331 (dtx*fixedPoint(internalIndexer_(ix,iy)) + tx*fixedPoint(internalIndexer_(ix+1,iy))));
1333 return NumericTraits<VALUETYPE>::zero();
1339 return fixed_point_cast<value_type>(
1340 dty*(fixedPoint(internalIndexer_(ix+1,iy)) - fixedPoint(internalIndexer_(ix,iy))) +
1341 ty *(fixedPoint(internalIndexer_(ix+1,iy+1)) - fixedPoint(internalIndexer_(ix,iy+1))));
1343 return detail::RequiresExplicitCast<value_type>::cast(
1344 (internalIndexer_(ix+1,iy+1) - internalIndexer_(ix,iy+1)) -
1345 (internalIndexer_(ix+1,iy) - internalIndexer_(ix,iy)));
1347 return NumericTraits<VALUETYPE>::zero();
1350 return NumericTraits<VALUETYPE>::zero();
1354 value_type unchecked(
double x,
double y)
const
1356 int ix = (int)std::floor(x);
1357 if(ix == (
int)w_ - 1)
1360 int iy = (int)std::floor(y);
1361 if(iy == (
int)h_ - 1)
1364 return NumericTraits<value_type>::fromRealPromote(
1365 (1.0-ty)*((1.0-tx)*internalIndexer_(ix,iy) + tx*internalIndexer_(ix+1,iy)) +
1366 ty *((1.0-tx)*internalIndexer_(ix,iy+1) + tx*internalIndexer_(ix+1,iy+1)));
1369 value_type unchecked(
double x,
double y,
unsigned int dx,
unsigned int dy)
const
1371 int ix = (int)std::floor(x);
1372 if(ix == (
int)w_ - 1)
1375 int iy = (int)std::floor(y);
1376 if(iy == (
int)h_ - 1)
1385 return detail::RequiresExplicitCast<value_type>::cast(
1386 (1.0-ty)*((1.0-tx)*internalIndexer_(ix,iy) + tx*internalIndexer_(ix+1,iy)) +
1387 ty *((1.0-tx)*internalIndexer_(ix,iy+1) + tx*internalIndexer_(ix+1,iy+1)));
1389 return detail::RequiresExplicitCast<value_type>::cast(
1390 ((1.0-tx)*internalIndexer_(ix,iy+1) + tx*internalIndexer_(ix+1,iy+1)) -
1391 ((1.0-tx)*internalIndexer_(ix,iy) + tx*internalIndexer_(ix+1,iy)));
1393 return NumericTraits<VALUETYPE>::zero();
1399 return detail::RequiresExplicitCast<value_type>::cast(
1400 (1.0-ty)*(internalIndexer_(ix+1,iy) - internalIndexer_(ix,iy)) +
1401 ty *(internalIndexer_(ix+1,iy+1) - internalIndexer_(ix,iy+1)));
1403 return detail::RequiresExplicitCast<value_type>::cast(
1404 (internalIndexer_(ix+1,iy+1) - internalIndexer_(ix,iy+1)) -
1405 (internalIndexer_(ix+1,iy) - internalIndexer_(ix,iy)));
1407 return NumericTraits<VALUETYPE>::zero();
1410 return NumericTraits<VALUETYPE>::zero();
1414 value_type operator()(
double x,
double y)
const
1416 return operator()(x, y, 0, 0);
1419 value_type operator()(
double x,
double y,
unsigned int dx,
unsigned int dy)
const
1421 value_type
mul = NumericTraits<value_type>::one();
1425 vigra_precondition(x <= w_ - 1.0,
1426 "SplineImageView::operator(): coordinates out of range.");
1430 else if(x > w_ - 1.0)
1433 vigra_precondition(x >= 0.0,
1434 "SplineImageView::operator(): coordinates out of range.");
1441 vigra_precondition(y <= h_ - 1.0,
1442 "SplineImageView::operator(): coordinates out of range.");
1446 else if(y > h_ - 1.0)
1449 vigra_precondition(y >= 0.0,
1450 "SplineImageView::operator(): coordinates out of range.");
1454 return mul*unchecked(x, y, dx, dy);
1457 value_type dx(
double x,
double y)
const
1458 {
return operator()(x, y, 1, 0); }
1460 value_type dy(
double x,
double y)
const
1461 {
return operator()(x, y, 0, 1); }
1463 value_type dxx(
double ,
double )
const
1464 {
return NumericTraits<VALUETYPE>::zero(); }
1466 value_type dxy(
double x,
double y)
const
1467 {
return operator()(x, y, 1, 1); }
1469 value_type dyy(
double ,
double )
const
1470 {
return NumericTraits<VALUETYPE>::zero(); }
1472 value_type dx3(
double ,
double )
const
1473 {
return NumericTraits<VALUETYPE>::zero(); }
1475 value_type dy3(
double ,
double )
const
1476 {
return NumericTraits<VALUETYPE>::zero(); }
1478 value_type dxxy(
double ,
double )
const
1479 {
return NumericTraits<VALUETYPE>::zero(); }
1481 value_type dxyy(
double ,
double )
const
1482 {
return NumericTraits<VALUETYPE>::zero(); }
1484 value_type operator()(difference_type
const & d)
const
1485 {
return operator()(d[0], d[1]); }
1487 value_type operator()(difference_type
const & d,
unsigned int dx,
unsigned int dy)
const
1488 {
return operator()(d[0], d[1], dx, dy); }
1490 value_type dx(difference_type
const & d)
const
1491 {
return operator()(d[0], d[1], 1, 0); }
1493 value_type dy(difference_type
const & d)
const
1494 {
return operator()(d[0], d[1], 0, 1); }
1496 value_type dxx(difference_type
const & )
const
1497 {
return NumericTraits<VALUETYPE>::zero(); }
1499 value_type dxy(difference_type
const & d)
const
1500 {
return operator()(d[0], d[1], 1, 1); }
1502 value_type dyy(difference_type
const & )
const
1503 {
return NumericTraits<VALUETYPE>::zero(); }
1505 value_type dx3(difference_type
const & )
const
1506 {
return NumericTraits<VALUETYPE>::zero(); }
1508 value_type dy3(difference_type
const & )
const
1509 {
return NumericTraits<VALUETYPE>::zero(); }
1511 value_type dxxy(difference_type
const & )
const
1512 {
return NumericTraits<VALUETYPE>::zero(); }
1514 value_type dxyy(difference_type
const & )
const
1515 {
return NumericTraits<VALUETYPE>::zero(); }
1517 SquaredNormType g2(
double x,
double y)
const
1520 SquaredNormType g2x(
double ,
double )
const
1521 {
return NumericTraits<SquaredNormType>::zero(); }
1523 SquaredNormType g2y(
double ,
double )
const
1524 {
return NumericTraits<SquaredNormType>::zero(); }
1526 SquaredNormType g2xx(
double ,
double )
const
1527 {
return NumericTraits<SquaredNormType>::zero(); }
1529 SquaredNormType g2xy(
double ,
double )
const
1530 {
return NumericTraits<SquaredNormType>::zero(); }
1532 SquaredNormType g2yy(
double ,
double )
const
1533 {
return NumericTraits<SquaredNormType>::zero(); }
1535 SquaredNormType g2(difference_type
const & d)
const
1536 {
return g2(d[0], d[1]); }
1538 SquaredNormType g2x(difference_type
const & )
const
1539 {
return NumericTraits<SquaredNormType>::zero(); }
1541 SquaredNormType g2y(difference_type
const & )
const
1542 {
return NumericTraits<SquaredNormType>::zero(); }
1544 SquaredNormType g2xx(difference_type
const & )
const
1545 {
return NumericTraits<SquaredNormType>::zero(); }
1547 SquaredNormType g2xy(difference_type
const & )
const
1548 {
return NumericTraits<SquaredNormType>::zero(); }
1550 SquaredNormType g2yy(difference_type
const & )
const
1551 {
return NumericTraits<SquaredNormType>::zero(); }
1553 unsigned int width()
const
1556 unsigned int height()
const
1559 size_type size()
const
1560 {
return size_type(w_, h_); }
1562 TinyVector<unsigned int, 2> shape()
const
1563 {
return TinyVector<unsigned int, 2>(w_, h_); }
1565 template <
class Array>
1566 void coefficientArray(
double x,
double y, Array & res)
const;
1568 void calculateIndices(
double x,
double y,
int & ix,
int & iy,
int & ix1,
int & iy1)
const;
1570 bool isInsideX(
double x)
const
1572 return x >= 0.0 && x <= width() - 1.0;
1575 bool isInsideY(
double y)
const
1577 return y >= 0.0 && y <= height() - 1.0;
1580 bool isInside(
double x,
double y)
const
1582 return isInsideX(x) && isInsideY(y);
1585 bool isValid(
double x,
double y)
const
1587 return x < 2.0*w_-2.0 && x > 1.0-w_ && y < 2.0*h_-2.0 && y > 1.0-h_;
1590 bool sameFacet(
double x0,
double y0,
double x1,
double y1)
const
1592 x0 = VIGRA_CSTD::floor(x0);
1593 y0 = VIGRA_CSTD::floor(y0);
1594 x1 = VIGRA_CSTD::floor(x1);
1595 y1 = VIGRA_CSTD::floor(y1);
1596 return x0 == x1 && y0 == y1;
1600 unsigned int w_, h_;
1601 INTERNAL_INDEXER internalIndexer_;
1604template <
class VALUETYPE,
class INTERNAL_INDEXER>
1605template <
class Array>
1606void SplineImageView1Base<VALUETYPE, INTERNAL_INDEXER>::coefficientArray(
double x,
double y, Array & res)
const
1610 res(0,0) = internalIndexer_(
ix,
iy);
1611 res(1,0) = internalIndexer_(
ix1,
iy) - internalIndexer_(
ix,
iy);
1612 res(0,1) = internalIndexer_(
ix,
iy1) - internalIndexer_(
ix,
iy);
1613 res(1,1) = internalIndexer_(
ix,
iy) - internalIndexer_(
ix1,
iy) -
1614 internalIndexer_(
ix,
iy1) + internalIndexer_(
ix1,
iy1);
1617template <
class VALUETYPE,
class INTERNAL_INDEXER>
1618void SplineImageView1Base<VALUETYPE, INTERNAL_INDEXER>::calculateIndices(
double x,
double y,
int & ix,
int & iy,
int & ix1,
int & iy1)
const
1623 vigra_precondition(x <= w_ - 1.0,
1624 "SplineImageView::calculateIndices(): coordinates out of range.");
1625 ix = (
int)VIGRA_CSTD::ceil(x);
1628 else if(x >= w_ - 1.0)
1631 vigra_precondition(x > 0.0,
1632 "SplineImageView::calculateIndices(): coordinates out of range.");
1633 ix = (
int)VIGRA_CSTD::ceil(x);
1638 ix = (
int)VIGRA_CSTD::floor(x);
1644 vigra_precondition(y <= h_ - 1.0,
1645 "SplineImageView::calculateIndices(): coordinates out of range.");
1646 iy = (
int)VIGRA_CSTD::ceil(y);
1649 else if(y >= h_ - 1.0)
1652 vigra_precondition(y > 0.0,
1653 "SplineImageView::calculateIndices(): coordinates out of range.");
1654 iy = (
int)VIGRA_CSTD::ceil(y);
1659 iy = (
int)VIGRA_CSTD::floor(y);
1679template <class VALUETYPE, class INTERNAL_TRAVERSER = typename BasicImage<VALUETYPE>::const_traverser>
1681:
public SplineImageView1Base<VALUETYPE, INTERNAL_TRAVERSER>
1688 typedef typename Base::difference_type difference_type;
1689 enum StaticOrder { order = Base::order };
1708 :
Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first)
1716 :
Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first)
1719 template<
class T,
class SU>
1721 :
Base(
i.shape(0),
i.shape(1)),
1722 image_(
i.shape(0),
i.shape(1))
1724 for(
unsigned int y=0; y<this->height(); ++y)
1725 for(
unsigned int x=0; x<this->width(); ++x)
1726 image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast(
i(x,y));
1727 this->internalIndexer_ = image_.
upperLeft();
1730 template <
class SrcIterator,
class SrcAccessor>
1736 this->internalIndexer_ = image_.
upperLeft();
1739 template <
class SrcIterator,
class SrcAccessor>
1741 :
Base(s.second.x - s.first.x, s.second.y - s.first.y),
1742 image_(s.second - s.first)
1745 this->internalIndexer_ = image_.
upperLeft();
1755template <
class VALUETYPE,
class Str
idedOrUnstr
ided>
1757:
public SplineImageView1Base<VALUETYPE, MultiArrayView<2, VALUETYPE, StridedOrUnstrided> >
1763 typedef typename Base::size_type size_type;
1764 typedef typename Base::difference_type difference_type;
1765 enum StaticOrder { order = Base::order };
1766 typedef BasicImage<VALUETYPE> InternalImage;
1769 typedef MultiArrayView<2, VALUETYPE, StridedOrUnstrided> InternalIndexer;
1776 SplineImageView1(InternalIndexer
const & i)
1777 : Base(i.shape(0), i.shape(1), i)
1780 template<
class T,
class SU>
1781 SplineImageView1(MultiArrayView<2, T, SU>
const & i)
1782 : Base(i.shape(0), i.shape(1)),
1783 image_(i.shape(0), i.shape(1))
1785 copyImage(srcImageRange(i), destImage(image_));
1789 this->internalIndexer_ = InternalIndexer(
typename InternalIndexer::difference_type(this->width(), this->height()),
1793 template <
class SrcIterator,
class SrcAccessor>
1794 SplineImageView1(SrcIterator is, SrcIterator iend, SrcAccessor sa)
1795 : Base(iend.x - is.x, iend.y - is.y),
1798 copyImage(srcIterRange(is, iend, sa), destImage(image_));
1799 this->internalIndexer_ = InternalIndexer(
typename InternalIndexer::difference_type(this->width(), this->height()),
1803 template <
class SrcIterator,
class SrcAccessor>
1804 SplineImageView1(triple<SrcIterator, SrcIterator, SrcAccessor> s)
1805 : Base(s.second.x - s.first.x, s.second.y - s.first.y),
1806 image_(s.second - s.first)
1809 this->internalIndexer_ = InternalIndexer(
typename InternalIndexer::difference_type(this->width(), this->height()),
1813 InternalImage
const & image()
const
1817 InternalImage image_;
1820template <
class VALUETYPE>
1821class SplineImageView<1, VALUETYPE>
1822:
public SplineImageView1<VALUETYPE>
1824 typedef SplineImageView1<VALUETYPE> Base;
1826 typedef typename Base::value_type
value_type;
1828 typedef typename Base::size_type
size_type;
1830 enum StaticOrder {
order = Base::order };
1834 typedef typename Base::InternalTraverser InternalTraverser;
1835 typedef typename Base::InternalAccessor InternalAccessor;
1836 typedef typename Base::InternalConstTraverser InternalConstTraverser;
1837 typedef typename Base::InternalConstAccessor InternalConstAccessor;
1844 SplineImageView(InternalTraverser is, InternalTraverser iend, InternalAccessor sa,
bool =
false)
1845 : Base(is, iend, sa)
1848 SplineImageView(triple<InternalTraverser, InternalTraverser, InternalAccessor> s,
bool =
false)
1852 SplineImageView(InternalConstTraverser is, InternalConstTraverser iend, InternalConstAccessor sa,
bool =
false)
1853 : Base(is, iend, sa)
1856 SplineImageView(triple<InternalConstTraverser, InternalConstTraverser, InternalConstAccessor> s,
bool =
false)
1860 template <
class SrcIterator,
class SrcAccessor>
1861 SplineImageView(SrcIterator is, SrcIterator iend, SrcAccessor sa,
bool =
false)
1862 : Base(is, iend, sa)
1864 copyImage(srcIterRange(is, iend, sa), destImage(this->image_));
1867 template <
class SrcIterator,
class SrcAccessor>
1868 SplineImageView(triple<SrcIterator, SrcIterator, SrcAccessor> s,
bool =
false)
1874 template<
class T,
class SU>
const_pointer data() const
Definition basicimage.hxx:1059
traverser upperLeft()
Definition basicimage.hxx:925
Base class for, and view to, vigra::MultiArray.
Definition multi_array.hxx:705
Class for a single RGB value.
Definition rgbvalue.hxx:128
RGBValue()
Definition rgbvalue.hxx:209
Base::value_type value_type
Definition rgbvalue.hxx:141
Base::SquaredNormType SquaredNormType
Definition rgbvalue.hxx:150
Two dimensional size object.
Definition diff2d.hxx:483
Create an image view for nearest-neighbor interpolation.
Definition splineimageview.hxx:1045
Create an image view for bi-linear interpolation.
Definition splineimageview.hxx:1682
Create a continuous view onto a discrete image using splines.
Definition splineimageview.hxx:100
value_type dy3(double x, double y) const
Definition splineimageview.hxx:253
value_type dx(double x, double y) const
Definition splineimageview.hxx:217
value_type dyy(difference_type const &d) const
Definition splineimageview.hxx:307
SquaredNormType g2(double x, double y) const
Definition splineimageview.hxx:740
value_type operator()(difference_type const &d, unsigned int dx, unsigned int dy) const
Definition splineimageview.hxx:277
bool isInside(double x, double y) const
Definition splineimageview.hxx:488
bool isInsideY(double y) const
Definition splineimageview.hxx:480
SquaredNormType g2y(double x, double y) const
Definition splineimageview.hxx:754
SplineImageView(triple< SrcIterator, SrcIterator, SrcAccessor > s, bool skipPrefiltering=false)
Definition splineimageview.hxx:188
value_type dy3(difference_type const &d) const
Definition splineimageview.hxx:319
SquaredNormType g2xx(double x, double y) const
Definition splineimageview.hxx:761
SquaredNormType g2xx(difference_type const &d) const
Definition splineimageview.hxx:383
SquaredNormType g2xy(double x, double y) const
Definition splineimageview.hxx:777
value_type dxx(double x, double y) const
Definition splineimageview.hxx:229
value_type operator()(double x, double y) const
Definition splineimageview.hxx:720
value_type operator()(difference_type const &d) const
Definition splineimageview.hxx:271
bool isInsideX(double x) const
Definition splineimageview.hxx:472
BasicImage< InternalValue > InternalImage
Definition splineimageview.hxx:127
value_type dxy(double x, double y) const
Definition splineimageview.hxx:235
SquaredNormType g2y(difference_type const &d) const
Definition splineimageview.hxx:377
size_type size() const
Definition splineimageview.hxx:414
value_type dx3(double x, double y) const
Definition splineimageview.hxx:247
NormTraits< VALUETYPE >::SquaredNormType SquaredNormType
Definition splineimageview.hxx:111
TinyVector< unsigned int, 2 > shape() const
Definition splineimageview.hxx:420
SquaredNormType g2yy(double x, double y) const
Definition splineimageview.hxx:769
Size2D size_type
Definition splineimageview.hxx:115
bool isValid(double x, double y) const
Definition splineimageview.hxx:498
value_type dy(double x, double y) const
Definition splineimageview.hxx:223
unsigned int width() const
Definition splineimageview.hxx:401
SquaredNormType g2(difference_type const &d) const
Definition splineimageview.hxx:365
value_type dxxy(difference_type const &d) const
Definition splineimageview.hxx:325
InternalImage const & image() const
Definition splineimageview.hxx:425
SquaredNormType g2xy(difference_type const &d) const
Definition splineimageview.hxx:389
bool sameFacet(double x0, double y0, double x1, double y1) const
Definition splineimageview.hxx:510
value_type dyy(double x, double y) const
Definition splineimageview.hxx:241
SquaredNormType g2x(difference_type const &d) const
Definition splineimageview.hxx:371
value_type dxx(difference_type const &d) const
Definition splineimageview.hxx:295
value_type dxyy(difference_type const &d) const
Definition splineimageview.hxx:331
value_type dxyy(double x, double y) const
Definition splineimageview.hxx:265
static constexpr int order
Definition splineimageview.hxx:123
VALUETYPE value_type
Definition splineimageview.hxx:107
SquaredNormType g2yy(difference_type const &d) const
Definition splineimageview.hxx:395
unsigned int height() const
Definition splineimageview.hxx:407
void coefficientArray(double x, double y, Array &res) const
Definition splineimageview.hxx:688
value_type dx(difference_type const &d) const
Definition splineimageview.hxx:283
TinyVector< double, 2 > difference_type
Definition splineimageview.hxx:119
value_type dxy(difference_type const &d) const
Definition splineimageview.hxx:301
value_type dy(difference_type const &d) const
Definition splineimageview.hxx:289
SplineImageView(MultiArrayView< 2, U, S > const &s, bool skipPrefiltering=false)
Definition splineimageview.hxx:148
value_type dx3(difference_type const &d) const
Definition splineimageview.hxx:313
SplineImageView(SrcIterator is, SrcIterator iend, SrcAccessor sa, bool skipPrefiltering=false)
Definition splineimageview.hxx:168
value_type dxxy(double x, double y) const
Definition splineimageview.hxx:259
SquaredNormType g2x(double x, double y) const
Definition splineimageview.hxx:747
int floor(FixedPoint< IntBits, FracBits > v)
rounding down.
Definition fixedpoint.hxx:667
FixedPoint< 0, FracBits > dual_frac(FixedPoint< IntBits, FracBits > v)
dual fractional part: 1 - frac(v).
Definition fixedpoint.hxx:658
int round(FixedPoint< IntBits, FracBits > v)
rounding to the nearest integer.
Definition fixedpoint.hxx:683
void mul(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r, FixedPoint< IntBits3, FracBits3 > &result)
multiplication with enforced result type.
Definition fixedpoint.hxx:605
void recursiveFilterY(...)
Performs 1 dimensional recursive filtering (1st and 2nd order) in y direction.
NumericTraits< V >::Promote sum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
sum of the vector's elements
Definition tinyvector.hxx:2073
void recursiveFilterX(...)
Performs 1 dimensional recursive filtering (1st and 2nd order) in x direction.
FFTWComplex< R >::SquaredNormType squaredNorm(const FFTWComplex< R > &a)
squared norm (= squared magnitude)
Definition fftw3.hxx:1044
FixedPoint< 0, FracBits > frac(FixedPoint< IntBits, FracBits > v)
fractional part.
Definition fixedpoint.hxx:650
void copyImage(...)
Copy source image into destination image.
Export associated information for each image iterator.
Definition iteratortraits.hxx:110