36 #ifndef VIGRA_SPLINEIMAGEVIEW_HXX
37 #define VIGRA_SPLINEIMAGEVIEW_HXX
39 #include "mathutil.hxx"
40 #include "recursiveconvolution.hxx"
41 #include "splines.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"
98 template <
int ORDER,
class VALUETYPE>
101 typedef typename NumericTraits<VALUETYPE>::RealPromote InternalValue;
131 typedef typename InternalTraverser::row_iterator InternalRowIterator;
135 enum { ksize_ = ORDER + 1, kcenter_ = ORDER / 2 };
145 template <
class SrcIterator,
class SrcAccessor>
146 SplineImageView(SrcIterator is, SrcIterator iend, SrcAccessor sa,
bool skipPrefiltering =
false)
147 : w_(iend.x - is.x), h_(iend.y - is.y), w1_(w_-1), h1_(h_-1),
148 x0_(kcenter_), x1_(w_ - kcenter_ - 2), y0_(kcenter_), y1_(h_ - kcenter_ - 2),
153 copyImage(srcIterRange(is, iend, sa), destImage(image_));
154 if(!skipPrefiltering)
165 template <
class SrcIterator,
class SrcAccessor>
166 SplineImageView(triple<SrcIterator, SrcIterator, SrcAccessor> s,
bool skipPrefiltering =
false)
167 : w_(s.second.x - s.first.x), h_(s.second.y - s.first.y), w1_(w_-1), h1_(h_-1),
168 x0_(kcenter_), x1_(w_ - kcenter_ - 2), y0_(kcenter_), y1_(h_ - kcenter_ - 2),
173 copyImage(srcIterRange(s.first, s.second, s.third), destImage(image_));
174 if(!skipPrefiltering)
262 {
return dx(d[0], d[1]); }
268 {
return dy(d[0], d[1]); }
274 {
return dxx(d[0], d[1]); }
280 {
return dxy(d[0], d[1]); }
286 {
return dyy(d[0], d[1]); }
292 {
return dx3(d[0], d[1]); }
298 {
return dy3(d[0], d[1]); }
304 {
return dxxy(d[0], d[1]); }
310 {
return dxyy(d[0], d[1]); }
344 {
return g2(d[0], d[1]); }
350 {
return g2x(d[0], d[1]); }
356 {
return g2y(d[0], d[1]); }
362 {
return g2xx(d[0], d[1]); }
368 {
return g2xy(d[0], d[1]); }
374 {
return g2yy(d[0], d[1]); }
444 template <
class Array>
452 return x >= 0.0 && x <=
width()-1.0;
460 return y >= 0.0 && y <=
height()-1.0;
478 return x < w1_ + x1_ && x > -x1_ && y < h1_ + y1_ && y > -y1_;
488 bool sameFacet(
double x0,
double y0,
double x1,
double y1)
const
494 return x0 == x1 && y0 == y1;
500 void calculateIndices(
double x,
double y)
const;
501 void coefficients(
double t,
double *
const & c)
const;
502 void derivCoefficients(
double t,
unsigned int d,
double *
const & c)
const;
507 double x0_, x1_, y0_, y1_;
510 mutable double x_, y_, u_, v_, kx_[ksize_], ky_[ksize_];
511 mutable int ix_[ksize_], iy_[ksize_];
514 template <
int ORDER,
class VALUETYPE>
515 void SplineImageView<ORDER, VALUETYPE>::init()
517 ArrayVector<double>
const & b = k_.prefilterCoefficients();
519 for(
unsigned int i=0; i<b.size(); ++i)
521 recursiveFilterX(srcImageRange(image_), destImage(image_), b[i], BORDER_TREATMENT_REFLECT);
522 recursiveFilterY(srcImageRange(image_), destImage(image_), b[i], BORDER_TREATMENT_REFLECT);
530 struct SplineImageViewUnrollLoop1
532 template <
class Array>
533 static void exec(
int c0, Array c)
535 SplineImageViewUnrollLoop1<i-1>::exec(c0, c);
541 struct SplineImageViewUnrollLoop1<0>
543 template <
class Array>
544 static void exec(
int c0, Array c)
550 template <
int i,
class ValueType>
551 struct SplineImageViewUnrollLoop2
553 template <
class Array1,
class RowIterator,
class Array2>
555 exec(Array1 k, RowIterator r, Array2 x)
557 return ValueType(k[i] * r[x[i]]) + SplineImageViewUnrollLoop2<i-1, ValueType>::exec(k, r, x);
561 template <
class ValueType>
562 struct SplineImageViewUnrollLoop2<0, ValueType>
564 template <
class Array1,
class RowIterator,
class Array2>
566 exec(Array1 k, RowIterator r, Array2 x)
568 return ValueType(k[0] * r[x[0]]);
574 template <
int ORDER,
class VALUETYPE>
576 SplineImageView<ORDER, VALUETYPE>::calculateIndices(
double x,
double y)
const
578 if(x == x_ && y == y_)
581 if(x > x0_ && x < x1_ && y > y0_ && y < y1_)
583 detail::SplineImageViewUnrollLoop1<ORDER>::exec(
584 (ORDER % 2) ?
int(x - kcenter_) :
int(x + 0.5 - kcenter_), ix_);
585 detail::SplineImageViewUnrollLoop1<ORDER>::exec(
586 (ORDER % 2) ?
int(y - kcenter_) :
int(y + 0.5 - kcenter_), iy_);
588 u_ = x - ix_[kcenter_];
589 v_ = y - iy_[kcenter_];
593 vigra_precondition(isValid(x,y),
594 "SplineImageView::calculateIndices(): coordinates out of range.");
596 int xCenter = (ORDER % 2) ?
598 (int)VIGRA_CSTD::
floor(x + 0.5);
599 int yCenter = (ORDER % 2) ?
601 (int)VIGRA_CSTD::
floor(y + 0.5);
605 for(
int i = 0; i < ksize_; ++i)
606 ix_[i] = w1_ -
vigra::abs(w1_ - xCenter - (i - kcenter_));
610 for(
int i = 0; i < ksize_; ++i)
611 ix_[i] =
vigra::abs(xCenter - (kcenter_ - i));
615 for(
int i = 0; i < ksize_; ++i)
616 iy_[i] = h1_ -
vigra::abs(h1_ - yCenter - (i - kcenter_));
620 for(
int i = 0; i < ksize_; ++i)
621 iy_[i] =
vigra::abs(yCenter - (kcenter_ - i));
630 template <
int ORDER,
class VALUETYPE>
631 void SplineImageView<ORDER, VALUETYPE>::coefficients(
double t,
double *
const & c)
const
634 for(
int i = 0; i<ksize_; ++i)
638 template <
int ORDER,
class VALUETYPE>
639 void SplineImageView<ORDER, VALUETYPE>::derivCoefficients(
double t,
640 unsigned int d,
double *
const & c)
const
643 for(
int i = 0; i<ksize_; ++i)
647 template <
int ORDER,
class VALUETYPE>
648 VALUETYPE SplineImageView<ORDER, VALUETYPE>::convolve()
const
650 typedef typename NumericTraits<VALUETYPE>::RealPromote RealPromote;
653 ky_[0]*detail::SplineImageViewUnrollLoop2<ORDER, RealPromote>::exec(kx_, image_.rowBegin(iy_[0]), ix_));
655 for(
int j=1; j<ksize_; ++j)
658 ky_[j]*detail::SplineImageViewUnrollLoop2<ORDER, RealPromote>::exec(kx_, image_.rowBegin(iy_[j]), ix_));
660 return detail::RequiresExplicitCast<VALUETYPE>::cast(sum);
663 template <
int ORDER,
class VALUETYPE>
664 template <
class Array>
668 typedef typename Array::value_type ResType;
669 typename Spline::WeightMatrix & weights = Spline::weights();
670 ResType tmp[ksize_][ksize_];
672 calculateIndices(x, y);
673 for(
int j=0; j<ksize_; ++j)
675 for(
int i=0; i<ksize_; ++i)
677 tmp[i][j] = ResType();
678 for(
int k=0; k<ksize_; ++k)
680 tmp[i][j] += weights[i][k]*image_(ix_[k], iy_[j]);
684 for(
int j=0; j<ksize_; ++j)
686 for(
int i=0; i<ksize_; ++i)
688 res(i,j) = ResType();
689 for(
int k=0; k<ksize_; ++k)
691 res(i,j) += weights[j][k]*tmp[i][k];
697 template <
int ORDER,
class VALUETYPE>
700 calculateIndices(x, y);
701 coefficients(u_, kx_);
702 coefficients(v_, ky_);
706 template <
int ORDER,
class VALUETYPE>
708 unsigned int dx,
unsigned int dy)
const
710 calculateIndices(x, y);
711 derivCoefficients(u_, dx, kx_);
712 derivCoefficients(v_, dy, ky_);
716 template <
int ORDER,
class VALUETYPE>
723 template <
int ORDER,
class VALUETYPE>
730 template <
int ORDER,
class VALUETYPE>
737 template <
int ORDER,
class VALUETYPE>
745 template <
int ORDER,
class VALUETYPE>
753 template <
int ORDER,
class VALUETYPE>
758 dot(dxy(x,y), dxx(x,y) + dyy(x,y)));
766 template <
class VALUETYPE,
class INTERNAL_INDEXER>
767 class SplineImageView0Base
769 typedef typename INTERNAL_INDEXER::value_type InternalValue;
771 typedef VALUETYPE value_type;
772 typedef typename NormTraits<VALUETYPE>::SquaredNormType SquaredNormType;
775 enum StaticOrder { order = 0 };
779 SplineImageView0Base(
unsigned int w,
unsigned int h)
783 SplineImageView0Base(
int w,
int h, INTERNAL_INDEXER i)
784 : w_(w), h_(h), internalIndexer_(i)
787 template <
unsigned IntBits1,
unsigned FractionalBits1,
788 unsigned IntBits2,
unsigned FractionalBits2>
789 value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x,
790 FixedPoint<IntBits2, FractionalBits2> y)
const
795 template <
unsigned IntBits1,
unsigned FractionalBits1,
796 unsigned IntBits2,
unsigned FractionalBits2>
797 value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x,
798 FixedPoint<IntBits2, FractionalBits2> y,
799 unsigned int dx,
unsigned int dy)
const
801 if((dx != 0) || (dy != 0))
802 return NumericTraits<VALUETYPE>::zero();
803 return unchecked(x, y);
806 value_type unchecked(
double x,
double y)
const
808 return internalIndexer_((
int)(x + 0.5), (
int)(y + 0.5));
811 value_type unchecked(
double x,
double y,
unsigned int dx,
unsigned int dy)
const
813 if((dx != 0) || (dy != 0))
814 return NumericTraits<VALUETYPE>::zero();
815 return unchecked(x, y);
818 value_type operator()(
double x,
double y)
const
823 ix = (int)(-x + 0.5);
824 vigra_precondition(ix <= (
int)w_ - 1,
825 "SplineImageView::operator(): coordinates out of range.");
833 vigra_precondition(ix >= 0,
834 "SplineImageView::operator(): coordinates out of range.");
839 iy = (int)(-y + 0.5);
840 vigra_precondition(iy <= (
int)h_ - 1,
841 "SplineImageView::operator(): coordinates out of range.");
849 vigra_precondition(iy >= 0,
850 "SplineImageView::operator(): coordinates out of range.");
853 return internalIndexer_(ix, iy);
856 value_type operator()(
double x,
double y,
unsigned int dx,
unsigned int dy)
const
858 if((dx != 0) || (dy != 0))
859 return NumericTraits<VALUETYPE>::zero();
860 return operator()(x, y);
863 value_type dx(
double x,
double y)
const
864 {
return NumericTraits<VALUETYPE>::zero(); }
866 value_type dy(
double x,
double y)
const
867 {
return NumericTraits<VALUETYPE>::zero(); }
869 value_type dxx(
double x,
double y)
const
870 {
return NumericTraits<VALUETYPE>::zero(); }
872 value_type dxy(
double x,
double y)
const
873 {
return NumericTraits<VALUETYPE>::zero(); }
875 value_type dyy(
double x,
double y)
const
876 {
return NumericTraits<VALUETYPE>::zero(); }
878 value_type dx3(
double x,
double y)
const
879 {
return NumericTraits<VALUETYPE>::zero(); }
881 value_type dy3(
double x,
double y)
const
882 {
return NumericTraits<VALUETYPE>::zero(); }
884 value_type dxxy(
double x,
double y)
const
885 {
return NumericTraits<VALUETYPE>::zero(); }
887 value_type dxyy(
double x,
double y)
const
888 {
return NumericTraits<VALUETYPE>::zero(); }
890 value_type operator()(difference_type
const & d)
const
891 {
return operator()(d[0], d[1]); }
893 value_type operator()(difference_type
const & d,
unsigned int dx,
unsigned int dy)
const
894 {
return operator()(d[0], d[1], dx, dy); }
896 value_type dx(difference_type
const & d)
const
897 {
return NumericTraits<VALUETYPE>::zero(); }
899 value_type dy(difference_type
const & d)
const
900 {
return NumericTraits<VALUETYPE>::zero(); }
902 value_type dxx(difference_type
const & d)
const
903 {
return NumericTraits<VALUETYPE>::zero(); }
905 value_type dxy(difference_type
const & d)
const
906 {
return NumericTraits<VALUETYPE>::zero(); }
908 value_type dyy(difference_type
const & d)
const
909 {
return NumericTraits<VALUETYPE>::zero(); }
911 value_type dx3(difference_type
const & d)
const
912 {
return NumericTraits<VALUETYPE>::zero(); }
914 value_type dy3(difference_type
const & d)
const
915 {
return NumericTraits<VALUETYPE>::zero(); }
917 value_type dxxy(difference_type
const & d)
const
918 {
return NumericTraits<VALUETYPE>::zero(); }
920 value_type dxyy(difference_type
const & d)
const
921 {
return NumericTraits<VALUETYPE>::zero(); }
923 SquaredNormType g2(
double x,
double y)
const
924 {
return NumericTraits<SquaredNormType>::zero(); }
926 SquaredNormType g2x(
double x,
double y)
const
927 {
return NumericTraits<SquaredNormType>::zero(); }
929 SquaredNormType g2y(
double x,
double y)
const
930 {
return NumericTraits<SquaredNormType>::zero(); }
932 SquaredNormType g2xx(
double x,
double y)
const
933 {
return NumericTraits<SquaredNormType>::zero(); }
935 SquaredNormType g2xy(
double x,
double y)
const
936 {
return NumericTraits<SquaredNormType>::zero(); }
938 SquaredNormType g2yy(
double x,
double y)
const
939 {
return NumericTraits<SquaredNormType>::zero(); }
941 SquaredNormType g2(difference_type
const & d)
const
942 {
return NumericTraits<SquaredNormType>::zero(); }
944 SquaredNormType g2x(difference_type
const & d)
const
945 {
return NumericTraits<SquaredNormType>::zero(); }
947 SquaredNormType g2y(difference_type
const & d)
const
948 {
return NumericTraits<SquaredNormType>::zero(); }
950 SquaredNormType g2xx(difference_type
const & d)
const
951 {
return NumericTraits<SquaredNormType>::zero(); }
953 SquaredNormType g2xy(difference_type
const & d)
const
954 {
return NumericTraits<SquaredNormType>::zero(); }
956 SquaredNormType g2yy(difference_type
const & d)
const
957 {
return NumericTraits<SquaredNormType>::zero(); }
959 unsigned int width()
const
962 unsigned int height()
const
965 size_type size()
const
966 {
return size_type(w_, h_); }
968 TinyVector<unsigned int, 2> shape()
const
969 {
return TinyVector<unsigned int, 2>(w_, h_); }
971 template <
class Array>
972 void coefficientArray(
double x,
double y, Array & res)
const
974 res(0, 0) = operator()(x,y);
977 bool isInsideX(
double x)
const
979 return x >= 0.0 && x <= width() - 1.0;
982 bool isInsideY(
double y)
const
984 return y >= 0.0 && y <= height() - 1.0;
987 bool isInside(
double x,
double y)
const
989 return isInsideX(x) && isInsideY(y);
992 bool isValid(
double x,
double y)
const
994 return x < 2.0*w_-2.0 && x > 1.0-w_ && y < 2.0*h_-2.0 && y > 1.0-h_;
997 bool sameFacet(
double x0,
double y0,
double x1,
double y1)
const
1003 return x0 == x1 && y0 == y1;
1007 unsigned int w_, h_;
1008 INTERNAL_INDEXER internalIndexer_;
1020 template <class VALUETYPE, class INTERNAL_TRAVERSER = typename BasicImage<VALUETYPE>::const_traverser>
1022 :
public SplineImageView0Base<VALUETYPE, INTERNAL_TRAVERSER>
1024 typedef SplineImageView0Base<VALUETYPE, INTERNAL_TRAVERSER> Base;
1026 typedef typename Base::value_type value_type;
1027 typedef typename Base::SquaredNormType SquaredNormType;
1030 enum StaticOrder { order = Base::order };
1045 : Base(iend.x - is.x, iend.y - is.y, is)
1048 SplineImageView0(triple<InternalTraverser, InternalTraverser, InternalAccessor> s)
1049 : Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first)
1053 : Base(iend.x - is.x, iend.y - is.y, is)
1056 SplineImageView0(triple<InternalConstTraverser, InternalConstTraverser, InternalConstAccessor> s)
1057 : Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first)
1060 template<
class T,
class SU>
1065 for(
unsigned int y=0; y<this->height(); ++y)
1066 for(
unsigned int x=0; x<this->width(); ++x)
1067 image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast(i(x,y));
1068 this->internalIndexer_ = image_.
upperLeft();
1071 template <
class SrcIterator,
class SrcAccessor>
1073 : Base(iend.x - is.x, iend.y - is.y),
1076 copyImage(srcIterRange(is, iend, sa), destImage(image_));
1077 this->internalIndexer_ = image_.
upperLeft();
1080 template <
class SrcIterator,
class SrcAccessor>
1082 : Base(s.second.x - s.first.x, s.second.y - s.first.y),
1083 image_(s.second - s.first)
1086 this->internalIndexer_ = image_.
upperLeft();
1096 template <
class VALUETYPE,
class Str
idedOrUnstr
ided>
1098 :
public SplineImageView0Base<VALUETYPE, MultiArrayView<2, VALUETYPE, StridedOrUnstrided> >
1100 typedef SplineImageView0Base<VALUETYPE, MultiArrayView<2, VALUETYPE, StridedOrUnstrided> > Base;
1102 typedef typename Base::value_type value_type;
1103 typedef typename Base::SquaredNormType SquaredNormType;
1104 typedef typename Base::size_type size_type;
1105 typedef typename Base::difference_type difference_type;
1106 enum StaticOrder { order = Base::order };
1107 typedef BasicImage<VALUETYPE> InternalImage;
1110 typedef MultiArrayView<2, VALUETYPE, StridedOrUnstrided> InternalIndexer;
1117 SplineImageView0(InternalIndexer
const & i)
1118 : Base(i.shape(0), i.shape(1), i)
1121 template<
class T,
class SU>
1122 SplineImageView0(MultiArrayView<2, T, SU>
const & i)
1123 : Base(i.shape(0), i.shape(1)),
1124 image_(i.shape(0), i.shape(1))
1126 for(
unsigned int y=0; y<this->height(); ++y)
1127 for(
unsigned int x=0; x<this->width(); ++x)
1128 image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast(i(x,y));
1129 this->internalIndexer_ = InternalIndexer(
typename InternalIndexer::difference_type(this->width(), this->height()),
1133 template <
class SrcIterator,
class SrcAccessor>
1134 SplineImageView0(SrcIterator is, SrcIterator iend, SrcAccessor sa)
1135 : Base(iend.x - is.x, iend.y - is.y),
1138 copyImage(srcIterRange(is, iend, sa), destImage(image_));
1139 this->internalIndexer_ = InternalIndexer(
typename InternalIndexer::difference_type(this->width(), this->height()),
1143 template <
class SrcIterator,
class SrcAccessor>
1144 SplineImageView0(triple<SrcIterator, SrcIterator, SrcAccessor> s)
1145 : Base(s.second.x - s.first.x, s.second.y - s.first.y),
1146 image_(s.second - s.first)
1149 this->internalIndexer_ = InternalIndexer(
typename InternalIndexer::difference_type(this->width(), this->height()),
1153 InternalImage
const & image()
const
1157 InternalImage image_;
1160 template <
class VALUETYPE>
1161 class SplineImageView<0, VALUETYPE>
1162 :
public SplineImageView0<VALUETYPE>
1164 typedef SplineImageView0<VALUETYPE> Base;
1166 typedef typename Base::value_type
value_type;
1168 typedef typename Base::size_type
size_type;
1174 typedef typename Base::InternalTraverser InternalTraverser;
1175 typedef typename Base::InternalAccessor InternalAccessor;
1176 typedef typename Base::InternalConstTraverser InternalConstTraverser;
1177 typedef typename Base::InternalConstAccessor InternalConstAccessor;
1184 SplineImageView(InternalTraverser is, InternalTraverser iend, InternalAccessor sa,
bool =
false)
1185 : Base(is, iend, sa)
1188 SplineImageView(triple<InternalTraverser, InternalTraverser, InternalAccessor> s,
bool =
false)
1192 SplineImageView(InternalConstTraverser is, InternalConstTraverser iend, InternalConstAccessor sa,
bool =
false)
1193 : Base(is, iend, sa)
1196 SplineImageView(triple<InternalConstTraverser, InternalConstTraverser, InternalConstAccessor> s,
bool =
false)
1200 template <
class SrcIterator,
class SrcAccessor>
1201 SplineImageView(SrcIterator is, SrcIterator iend, SrcAccessor sa,
bool =
false)
1202 : Base(is, iend, sa)
1204 copyImage(srcIterRange(is, iend, sa), destImage(this->image_));
1207 template <
class SrcIterator,
class SrcAccessor>
1208 SplineImageView(triple<SrcIterator, SrcIterator, SrcAccessor> s,
bool =
false)
1220 template <
class VALUETYPE,
class INTERNAL_INDEXER>
1221 class SplineImageView1Base
1223 typedef typename INTERNAL_INDEXER::value_type InternalValue;
1225 typedef VALUETYPE value_type;
1226 typedef Size2D size_type;
1227 typedef typename NormTraits<VALUETYPE>::SquaredNormType SquaredNormType;
1228 typedef TinyVector<double, 2> difference_type;
1229 enum StaticOrder { order = 1 };
1233 SplineImageView1Base(
unsigned int w,
unsigned int h)
1237 SplineImageView1Base(
int w,
int h, INTERNAL_INDEXER i)
1238 : w_(w), h_(h), internalIndexer_(i)
1241 template <
unsigned IntBits1,
unsigned FractionalBits1,
1242 unsigned IntBits2,
unsigned FractionalBits2>
1243 value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x,
1244 FixedPoint<IntBits2, FractionalBits2> y)
const
1247 FixedPoint<0, FractionalBits1> tx =
frac(x - FixedPoint<IntBits1, FractionalBits1>(ix));
1248 FixedPoint<0, FractionalBits1> dtx =
dual_frac(tx);
1249 if(ix == (
int)w_ - 1)
1252 tx.value = FixedPoint<0, FractionalBits1>::ONE;
1256 FixedPoint<0, FractionalBits2> ty =
frac(y - FixedPoint<IntBits2, FractionalBits2>(iy));
1257 FixedPoint<0, FractionalBits2> dty =
dual_frac(ty);
1258 if(iy == (
int)h_ - 1)
1261 ty.value = FixedPoint<0, FractionalBits2>::ONE;
1265 dty*(dtx*fixedPoint(internalIndexer_(ix,iy)) +
1266 tx*fixedPoint(internalIndexer_(ix+1,iy))) +
1267 ty *(dtx*fixedPoint(internalIndexer_(ix,iy+1)) +
1268 tx*fixedPoint(internalIndexer_(ix+1,iy+1))));
1271 template <
unsigned IntBits1,
unsigned FractionalBits1,
1272 unsigned IntBits2,
unsigned FractionalBits2>
1273 value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x,
1274 FixedPoint<IntBits2, FractionalBits2> y,
1275 unsigned int dx,
unsigned int dy)
const
1278 FixedPoint<0, FractionalBits1> tx =
frac(x - FixedPoint<IntBits1, FractionalBits1>(ix));
1279 FixedPoint<0, FractionalBits1> dtx =
dual_frac(tx);
1280 if(ix == (
int)w_ - 1)
1283 tx.value = FixedPoint<0, FractionalBits1>::ONE;
1287 FixedPoint<0, FractionalBits2> ty =
frac(y - FixedPoint<IntBits2, FractionalBits2>(iy));
1288 FixedPoint<0, FractionalBits2> dty =
dual_frac(ty);
1289 if(iy == (
int)h_ - 1)
1292 ty.value = FixedPoint<0, FractionalBits2>::ONE;
1302 dty*(dtx*fixedPoint(internalIndexer_(ix,iy)) +
1303 tx*fixedPoint(internalIndexer_(ix+1,iy))) +
1304 ty *(dtx*fixedPoint(internalIndexer_(ix,iy+1)) +
1305 tx*fixedPoint(internalIndexer_(ix+1,iy+1))));
1308 (dtx*fixedPoint(internalIndexer_(ix,iy+1)) + tx*fixedPoint(internalIndexer_(ix+1,iy+1))) -
1309 (dtx*fixedPoint(internalIndexer_(ix,iy)) + tx*fixedPoint(internalIndexer_(ix+1,iy))));
1311 return NumericTraits<VALUETYPE>::zero();
1318 dty*(fixedPoint(internalIndexer_(ix+1,iy)) - fixedPoint(internalIndexer_(ix,iy))) +
1319 ty *(fixedPoint(internalIndexer_(ix+1,iy+1)) - fixedPoint(internalIndexer_(ix,iy+1))));
1321 return detail::RequiresExplicitCast<value_type>::cast(
1322 (internalIndexer_(ix+1,iy+1) - internalIndexer_(ix,iy+1)) -
1323 (internalIndexer_(ix+1,iy) - internalIndexer_(ix,iy)));
1325 return NumericTraits<VALUETYPE>::zero();
1328 return NumericTraits<VALUETYPE>::zero();
1332 value_type unchecked(
double x,
double y)
const
1335 if(ix == (
int)w_ - 1)
1339 if(iy == (
int)h_ - 1)
1342 return NumericTraits<value_type>::fromRealPromote(
1343 (1.0-ty)*((1.0-tx)*internalIndexer_(ix,iy) + tx*internalIndexer_(ix+1,iy)) +
1344 ty *((1.0-tx)*internalIndexer_(ix,iy+1) + tx*internalIndexer_(ix+1,iy+1)));
1347 value_type unchecked(
double x,
double y,
unsigned int dx,
unsigned int dy)
const
1350 if(ix == (
int)w_ - 1)
1354 if(iy == (
int)h_ - 1)
1363 return detail::RequiresExplicitCast<value_type>::cast(
1364 (1.0-ty)*((1.0-tx)*internalIndexer_(ix,iy) + tx*internalIndexer_(ix+1,iy)) +
1365 ty *((1.0-tx)*internalIndexer_(ix,iy+1) + tx*internalIndexer_(ix+1,iy+1)));
1367 return detail::RequiresExplicitCast<value_type>::cast(
1368 ((1.0-tx)*internalIndexer_(ix,iy+1) + tx*internalIndexer_(ix+1,iy+1)) -
1369 ((1.0-tx)*internalIndexer_(ix,iy) + tx*internalIndexer_(ix+1,iy)));
1371 return NumericTraits<VALUETYPE>::zero();
1377 return detail::RequiresExplicitCast<value_type>::cast(
1378 (1.0-ty)*(internalIndexer_(ix+1,iy) - internalIndexer_(ix,iy)) +
1379 ty *(internalIndexer_(ix+1,iy+1) - internalIndexer_(ix,iy+1)));
1381 return detail::RequiresExplicitCast<value_type>::cast(
1382 (internalIndexer_(ix+1,iy+1) - internalIndexer_(ix,iy+1)) -
1383 (internalIndexer_(ix+1,iy) - internalIndexer_(ix,iy)));
1385 return NumericTraits<VALUETYPE>::zero();
1388 return NumericTraits<VALUETYPE>::zero();
1392 value_type operator()(
double x,
double y)
const
1394 return operator()(x, y, 0, 0);
1397 value_type operator()(
double x,
double y,
unsigned int dx,
unsigned int dy)
const
1399 value_type
mul = NumericTraits<value_type>::one();
1403 vigra_precondition(x <= w_ - 1.0,
1404 "SplineImageView::operator(): coordinates out of range.");
1408 else if(x > w_ - 1.0)
1411 vigra_precondition(x >= 0.0,
1412 "SplineImageView::operator(): coordinates out of range.");
1419 vigra_precondition(y <= h_ - 1.0,
1420 "SplineImageView::operator(): coordinates out of range.");
1424 else if(y > h_ - 1.0)
1427 vigra_precondition(y >= 0.0,
1428 "SplineImageView::operator(): coordinates out of range.");
1432 return mul*unchecked(x, y, dx, dy);
1435 value_type dx(
double x,
double y)
const
1436 {
return operator()(x, y, 1, 0); }
1438 value_type dy(
double x,
double y)
const
1439 {
return operator()(x, y, 0, 1); }
1441 value_type dxx(
double x,
double y)
const
1442 {
return NumericTraits<VALUETYPE>::zero(); }
1444 value_type dxy(
double x,
double y)
const
1445 {
return operator()(x, y, 1, 1); }
1447 value_type dyy(
double x,
double y)
const
1448 {
return NumericTraits<VALUETYPE>::zero(); }
1450 value_type dx3(
double x,
double y)
const
1451 {
return NumericTraits<VALUETYPE>::zero(); }
1453 value_type dy3(
double x,
double y)
const
1454 {
return NumericTraits<VALUETYPE>::zero(); }
1456 value_type dxxy(
double x,
double y)
const
1457 {
return NumericTraits<VALUETYPE>::zero(); }
1459 value_type dxyy(
double x,
double y)
const
1460 {
return NumericTraits<VALUETYPE>::zero(); }
1462 value_type operator()(difference_type
const & d)
const
1463 {
return operator()(d[0], d[1]); }
1465 value_type operator()(difference_type
const & d,
unsigned int dx,
unsigned int dy)
const
1466 {
return operator()(d[0], d[1], dx, dy); }
1468 value_type dx(difference_type
const & d)
const
1469 {
return operator()(d[0], d[1], 1, 0); }
1471 value_type dy(difference_type
const & d)
const
1472 {
return operator()(d[0], d[1], 0, 1); }
1474 value_type dxx(difference_type
const & d)
const
1475 {
return NumericTraits<VALUETYPE>::zero(); }
1477 value_type dxy(difference_type
const & d)
const
1478 {
return operator()(d[0], d[1], 1, 1); }
1480 value_type dyy(difference_type
const & d)
const
1481 {
return NumericTraits<VALUETYPE>::zero(); }
1483 value_type dx3(difference_type
const & d)
const
1484 {
return NumericTraits<VALUETYPE>::zero(); }
1486 value_type dy3(difference_type
const & d)
const
1487 {
return NumericTraits<VALUETYPE>::zero(); }
1489 value_type dxxy(difference_type
const & d)
const
1490 {
return NumericTraits<VALUETYPE>::zero(); }
1492 value_type dxyy(difference_type
const & d)
const
1493 {
return NumericTraits<VALUETYPE>::zero(); }
1495 SquaredNormType g2(
double x,
double y)
const
1498 SquaredNormType g2x(
double x,
double y)
const
1499 {
return NumericTraits<SquaredNormType>::zero(); }
1501 SquaredNormType g2y(
double x,
double y)
const
1502 {
return NumericTraits<SquaredNormType>::zero(); }
1504 SquaredNormType g2xx(
double x,
double y)
const
1505 {
return NumericTraits<SquaredNormType>::zero(); }
1507 SquaredNormType g2xy(
double x,
double y)
const
1508 {
return NumericTraits<SquaredNormType>::zero(); }
1510 SquaredNormType g2yy(
double x,
double y)
const
1511 {
return NumericTraits<SquaredNormType>::zero(); }
1513 SquaredNormType g2(difference_type
const & d)
const
1514 {
return g2(d[0], d[1]); }
1516 SquaredNormType g2x(difference_type
const & d)
const
1517 {
return NumericTraits<SquaredNormType>::zero(); }
1519 SquaredNormType g2y(difference_type
const & d)
const
1520 {
return NumericTraits<SquaredNormType>::zero(); }
1522 SquaredNormType g2xx(difference_type
const & d)
const
1523 {
return NumericTraits<SquaredNormType>::zero(); }
1525 SquaredNormType g2xy(difference_type
const & d)
const
1526 {
return NumericTraits<SquaredNormType>::zero(); }
1528 SquaredNormType g2yy(difference_type
const & d)
const
1529 {
return NumericTraits<SquaredNormType>::zero(); }
1531 unsigned int width()
const
1534 unsigned int height()
const
1537 size_type size()
const
1538 {
return size_type(w_, h_); }
1540 TinyVector<unsigned int, 2> shape()
const
1541 {
return TinyVector<unsigned int, 2>(w_, h_); }
1543 template <
class Array>
1544 void coefficientArray(
double x,
double y, Array & res)
const;
1546 void calculateIndices(
double x,
double y,
int & ix,
int & iy,
int & ix1,
int & iy1)
const;
1548 bool isInsideX(
double x)
const
1550 return x >= 0.0 && x <= width() - 1.0;
1553 bool isInsideY(
double y)
const
1555 return y >= 0.0 && y <= height() - 1.0;
1558 bool isInside(
double x,
double y)
const
1560 return isInsideX(x) && isInsideY(y);
1563 bool isValid(
double x,
double y)
const
1565 return x < 2.0*w_-2.0 && x > 1.0-w_ && y < 2.0*h_-2.0 && y > 1.0-h_;
1568 bool sameFacet(
double x0,
double y0,
double x1,
double y1)
const
1574 return x0 == x1 && y0 == y1;
1578 unsigned int w_, h_;
1579 INTERNAL_INDEXER internalIndexer_;
1582 template <
class VALUETYPE,
class INTERNAL_INDEXER>
1583 template <
class Array>
1584 void SplineImageView1Base<VALUETYPE, INTERNAL_INDEXER>::coefficientArray(
double x,
double y, Array & res)
const
1586 int ix, iy, ix1, iy1;
1587 calculateIndices(x, y, ix, iy, ix1, iy1);
1588 res(0,0) = internalIndexer_(ix,iy);
1589 res(1,0) = internalIndexer_(ix1,iy) - internalIndexer_(ix,iy);
1590 res(0,1) = internalIndexer_(ix,iy1) - internalIndexer_(ix,iy);
1591 res(1,1) = internalIndexer_(ix,iy) - internalIndexer_(ix1,iy) -
1592 internalIndexer_(ix,iy1) + internalIndexer_(ix1,iy1);
1595 template <
class VALUETYPE,
class INTERNAL_INDEXER>
1596 void SplineImageView1Base<VALUETYPE, INTERNAL_INDEXER>::calculateIndices(
double x,
double y,
int & ix,
int & iy,
int & ix1,
int & iy1)
const
1601 vigra_precondition(x <= w_ - 1.0,
1602 "SplineImageView::calculateIndices(): coordinates out of range.");
1606 else if(x >= w_ - 1.0)
1609 vigra_precondition(x > 0.0,
1610 "SplineImageView::calculateIndices(): coordinates out of range.");
1622 vigra_precondition(y <= h_ - 1.0,
1623 "SplineImageView::calculateIndices(): coordinates out of range.");
1627 else if(y >= h_ - 1.0)
1630 vigra_precondition(y > 0.0,
1631 "SplineImageView::calculateIndices(): coordinates out of range.");
1657 template <class VALUETYPE, class INTERNAL_TRAVERSER = typename BasicImage<VALUETYPE>::const_traverser>
1659 :
public SplineImageView1Base<VALUETYPE, INTERNAL_TRAVERSER>
1661 typedef SplineImageView1Base<VALUETYPE, INTERNAL_TRAVERSER> Base;
1663 typedef typename Base::value_type value_type;
1664 typedef typename Base::SquaredNormType SquaredNormType;
1667 enum StaticOrder { order = Base::order };
1682 : Base(iend.x - is.x, iend.y - is.y, is)
1685 SplineImageView1(triple<InternalTraverser, InternalTraverser, InternalAccessor> s)
1686 : Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first)
1690 : Base(iend.x - is.x, iend.y - is.y, is)
1693 SplineImageView1(triple<InternalConstTraverser, InternalConstTraverser, InternalConstAccessor> s)
1694 : Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first)
1697 template<
class T,
class SU>
1702 for(
unsigned int y=0; y<this->height(); ++y)
1703 for(
unsigned int x=0; x<this->width(); ++x)
1704 image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast(i(x,y));
1705 this->internalIndexer_ = image_.
upperLeft();
1708 template <
class SrcIterator,
class SrcAccessor>
1710 : Base(iend.x - is.x, iend.y - is.y),
1713 copyImage(srcIterRange(is, iend, sa), destImage(image_));
1714 this->internalIndexer_ = image_.
upperLeft();
1717 template <
class SrcIterator,
class SrcAccessor>
1719 : Base(s.second.x - s.first.x, s.second.y - s.first.y),
1720 image_(s.second - s.first)
1723 this->internalIndexer_ = image_.
upperLeft();
1733 template <
class VALUETYPE,
class Str
idedOrUnstr
ided>
1735 :
public SplineImageView1Base<VALUETYPE, MultiArrayView<2, VALUETYPE, StridedOrUnstrided> >
1737 typedef SplineImageView1Base<VALUETYPE, MultiArrayView<2, VALUETYPE, StridedOrUnstrided> > Base;
1739 typedef typename Base::value_type value_type;
1740 typedef typename Base::SquaredNormType SquaredNormType;
1741 typedef typename Base::size_type size_type;
1742 typedef typename Base::difference_type difference_type;
1743 enum StaticOrder { order = Base::order };
1744 typedef BasicImage<VALUETYPE> InternalImage;
1747 typedef MultiArrayView<2, VALUETYPE, StridedOrUnstrided> InternalIndexer;
1754 SplineImageView1(InternalIndexer
const & i)
1755 : Base(i.shape(0), i.shape(1), i)
1758 template<
class T,
class SU>
1759 SplineImageView1(MultiArrayView<2, T, SU>
const & i)
1760 : Base(i.shape(0), i.shape(1)),
1761 image_(i.shape(0), i.shape(1))
1763 for(
unsigned int y=0; y<this->height(); ++y)
1764 for(
unsigned int x=0; x<this->width(); ++x)
1765 image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast(i(x,y));
1766 this->internalIndexer_ = InternalIndexer(
typename InternalIndexer::difference_type(this->width(), this->height()),
1770 template <
class SrcIterator,
class SrcAccessor>
1771 SplineImageView1(SrcIterator is, SrcIterator iend, SrcAccessor sa)
1772 : Base(iend.x - is.x, iend.y - is.y),
1775 copyImage(srcIterRange(is, iend, sa), destImage(image_));
1776 this->internalIndexer_ = InternalIndexer(
typename InternalIndexer::difference_type(this->width(), this->height()),
1780 template <
class SrcIterator,
class SrcAccessor>
1781 SplineImageView1(triple<SrcIterator, SrcIterator, SrcAccessor> s)
1782 : Base(s.second.x - s.first.x, s.second.y - s.first.y),
1783 image_(s.second - s.first)
1786 this->internalIndexer_ = InternalIndexer(
typename InternalIndexer::difference_type(this->width(), this->height()),
1790 InternalImage
const & image()
const
1794 InternalImage image_;
1797 template <
class VALUETYPE>
1798 class SplineImageView<1, VALUETYPE>
1799 :
public SplineImageView1<VALUETYPE>
1801 typedef SplineImageView1<VALUETYPE> Base;
1803 typedef typename Base::value_type
value_type;
1805 typedef typename Base::size_type
size_type;
1811 typedef typename Base::InternalTraverser InternalTraverser;
1812 typedef typename Base::InternalAccessor InternalAccessor;
1813 typedef typename Base::InternalConstTraverser InternalConstTraverser;
1814 typedef typename Base::InternalConstAccessor InternalConstAccessor;
1821 SplineImageView(InternalTraverser is, InternalTraverser iend, InternalAccessor sa,
bool =
false)
1822 : Base(is, iend, sa)
1825 SplineImageView(triple<InternalTraverser, InternalTraverser, InternalAccessor> s,
bool =
false)
1829 SplineImageView(InternalConstTraverser is, InternalConstTraverser iend, InternalConstAccessor sa,
bool =
false)
1830 : Base(is, iend, sa)
1833 SplineImageView(triple<InternalConstTraverser, InternalConstTraverser, InternalConstAccessor> s,
bool =
false)
1837 template <
class SrcIterator,
class SrcAccessor>
1838 SplineImageView(SrcIterator is, SrcIterator iend, SrcAccessor sa,
bool =
false)
1839 : Base(is, iend, sa)
1841 copyImage(srcIterRange(is, iend, sa), destImage(this->image_));
1844 template <
class SrcIterator,
class SrcAccessor>
1845 SplineImageView(triple<SrcIterator, SrcIterator, SrcAccessor> s,
bool =
false)
SquaredNormType g2(difference_type const &d) const
Definition: splineimageview.hxx:343
SquaredNormType g2(double x, double y) const
Definition: splineimageview.hxx:718
bool isInside(double x, double y) const
Definition: splineimageview.hxx:466
VALUETYPE value_type
Definition: splineimageview.hxx:107
bool isInsideY(double y) const
Definition: splineimageview.hxx:458
PromoteTraits< V1, V2 >::Promote dot(RGBValue< V1, RIDX1, GIDX1, BIDX1 > const &r1, RGBValue< V2, RIDX2, GIDX2, BIDX2 > const &r2)
dot product
Definition: rgbvalue.hxx:894
Export associated information for each image iterator.
Definition: iteratortraits.hxx:109
unsigned int width() const
Definition: splineimageview.hxx:379
value_type operator()(difference_type const &d) const
Definition: splineimageview.hxx:249
SquaredNormType g2y(double x, double y) const
Definition: splineimageview.hxx:732
void recursiveFilterY(...)
Performs 1 dimensional recursive filtering (1st and 2nd order) in y direction.
SquaredNormType g2x(difference_type const &d) const
Definition: splineimageview.hxx:349
const difference_type & shape() const
Definition: multi_array.hxx:1602
void coefficientArray(double x, double y, Array &res) const
Definition: splineimageview.hxx:666
value_type dyy(difference_type const &d) const
Definition: splineimageview.hxx:285
value_type dxx(difference_type const &d) const
Definition: splineimageview.hxx:273
FFTWComplex< R >::SquaredNormType squaredNorm(const FFTWComplex< R > &a)
squared norm (= squared magnitude)
Definition: fftw3.hxx:1044
SquaredNormType g2y(difference_type const &d) const
Definition: splineimageview.hxx:355
int round(FixedPoint< IntBits, FracBits > v)
rounding to the nearest integer.
Definition: fixedpoint.hxx:683
TARGET fixed_point_cast(FixedPoint< IntBits, FracBits > v)
Definition: fixedpoint.hxx:486
value_type dyy(double x, double y) const
Definition: splineimageview.hxx:219
value_type dxy(difference_type const &d) const
Definition: splineimageview.hxx:279
SquaredNormType g2x(double x, double y) const
Definition: splineimageview.hxx:725
SquaredNormType g2xy(difference_type const &d) const
Definition: splineimageview.hxx:367
StaticOrder
Definition: splineimageview.hxx:123
value_type operator()(double x, double y) const
Definition: splineimageview.hxx:698
SquaredNormType g2xx(double x, double y) const
Definition: splineimageview.hxx:739
value_type dy3(difference_type const &d) const
Definition: splineimageview.hxx:297
bool isValid(double x, double y) const
Definition: splineimageview.hxx:476
FixedPoint< 0, FracBits > dual_frac(FixedPoint< IntBits, FracBits > v)
dual fractional part: 1 - frac(v).
Definition: fixedpoint.hxx:658
value_type dx(difference_type const &d) const
Definition: splineimageview.hxx:261
Two dimensional size object.
Definition: diff2d.hxx:482
FixedPoint< 0, FracBits > frac(FixedPoint< IntBits, FracBits > v)
fractional part.
Definition: fixedpoint.hxx:650
SquaredNormType g2yy(double x, double y) const
Definition: splineimageview.hxx:747
SquaredNormType g2xx(difference_type const &d) const
Definition: splineimageview.hxx:361
value_type dxxy(double x, double y) const
Definition: splineimageview.hxx:237
Definition: basicimage.hxx:261
value_type dxx(double x, double y) const
Definition: splineimageview.hxx:207
InternalImage const & image() const
Definition: splineimageview.hxx:403
void mul(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r, FixedPoint< IntBits3, FracBits3 > &result)
multiplication with enforced result type.
Definition: fixedpoint.hxx:605
value_type operator()(difference_type const &d, unsigned int dx, unsigned int dy) const
Definition: splineimageview.hxx:255
void recursiveFilterX(...)
Performs 1 dimensional recursive filtering (1st and 2nd order) in x direction.
NumericTraits< V >::Promote sum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
sum of the vector's elements
Definition: tinyvector.hxx:1683
NormTraits< VALUETYPE >::SquaredNormType SquaredNormType
Definition: splineimageview.hxx:111
TinyVector< double, 2 > difference_type
Definition: splineimageview.hxx:119
Create an image view for bi-linear interpolation.
Definition: splineimageview.hxx:1658
size_type size() const
Definition: splineimageview.hxx:392
const_pointer data() const
Definition: basicimage.hxx:1057
TinyVector< unsigned int, 2 > shape() const
Definition: splineimageview.hxx:398
void copyImage(...)
Copy source image into destination image.
value_type dxxy(difference_type const &d) const
Definition: splineimageview.hxx:303
value_type dx3(double x, double y) const
Definition: splineimageview.hxx:225
value_type dx(double x, double y) const
Definition: splineimageview.hxx:195
value_type dy3(double x, double y) const
Definition: splineimageview.hxx:231
value_type dx3(difference_type const &d) const
Definition: splineimageview.hxx:291
value_type dxyy(difference_type const &d) const
Definition: splineimageview.hxx:309
Size2D size_type
Definition: splineimageview.hxx:115
SquaredNormType g2yy(difference_type const &d) const
Definition: splineimageview.hxx:373
SplineImageView(triple< SrcIterator, SrcIterator, SrcAccessor > s, bool skipPrefiltering=false)
Definition: splineimageview.hxx:166
bool sameFacet(double x0, double y0, double x1, double y1) const
Definition: splineimageview.hxx:488
FFTWComplex< R >::NormType abs(const FFTWComplex< R > &a)
absolute value (= magnitude)
Definition: fftw3.hxx:1002
Base class for, and view to, vigra::MultiArray.
Definition: multi_array.hxx:593
value_type dy(difference_type const &d) const
Definition: splineimageview.hxx:267
value_type dxyy(double x, double y) const
Definition: splineimageview.hxx:243
value_type dy(double x, double y) const
Definition: splineimageview.hxx:201
BasicImage< InternalValue > InternalImage
Definition: splineimageview.hxx:127
SquaredNormType g2xy(double x, double y) const
Definition: splineimageview.hxx:755
int ceil(FixedPoint< IntBits, FracBits > v)
rounding up.
Definition: fixedpoint.hxx:675
Encapsulate access to the values an iterator points to.
Definition: accessor.hxx:132
Quickly create 1-dimensional iterator adapters.
Definition: iteratoradapter.hxx:148
Create a continuous view onto a discrete image using splines.
Definition: splineimageview.hxx:99
int floor(FixedPoint< IntBits, FracBits > v)
rounding down.
Definition: fixedpoint.hxx:667
Create an image view for nearest-neighbor interpolation.
Definition: splineimageview.hxx:1021
value_type dxy(double x, double y) const
Definition: splineimageview.hxx:213
unsigned int height() const
Definition: splineimageview.hxx:385
bool isInsideX(double x) const
Definition: splineimageview.hxx:450
traverser upperLeft()
Definition: basicimage.hxx:923
SplineImageView(SrcIterator is, SrcIterator iend, SrcAccessor sa, bool skipPrefiltering=false)
Definition: splineimageview.hxx:146