36 #ifndef VIGRA_AFFINEGEOMETRY_HXX
37 #define VIGRA_AFFINEGEOMETRY_HXX
39 #include "mathutil.hxx"
41 #include "tinyvector.hxx"
42 #include "splineimageview.hxx"
64 linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
77 linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
78 ret(0,0) = scalingFactor;
79 ret(1,1) = scalingFactor;
90 linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
103 linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
116 linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
241 template <
int ORDER,
class T,
242 class DestIterator,
class DestAccessor>
243 void rotateImage(SplineImageView<ORDER, T>
const & src,
244 DestIterator
id, DestAccessor dest,
245 double angleInDegree, TinyVector<double, 2>
const & center)
248 int h = src.height();
250 double angle = angleInDegree*M_PI/180.0;
258 int ai =
roundi(angleInDegree / 45.0) % 8;
262 static double sqrt2_2 = 0.5*M_SQRT2;
263 static double ss[8] = {0.0, sqrt2_2, 1.0, sqrt2_2, 0.0, -sqrt2_2, -1.0, -sqrt2_2};
264 static double cc[8] = {1.0, sqrt2_2, 0.0, -sqrt2_2, -1.0, -sqrt2_2, 0.0, sqrt2_2};
270 for(
int y = 0; y < h; ++y, ++
id.y)
272 typename DestIterator::row_iterator rd =
id.rowIterator();
273 double sy = (y - center[1])*c - center[0]*s + center[1];
274 double sx = -(y - center[1])*s - center[0]*c + center[0];
275 for(
int x=0; x < w; ++x, ++rd, sx += c, sy += s)
277 if(src.isInside(sx, sy))
278 dest.set(src(sx, sy), rd);
283 template <
int ORDER,
class T,
284 class DestIterator,
class DestAccessor>
287 pair<DestIterator, DestAccessor> dest,
288 double angleInDegree, TinyVector<double, 2>
const & center)
290 rotateImage(src, dest.first, dest.second, angleInDegree, center);
293 template <
int ORDER,
class T,
294 class DestIterator,
class DestAccessor>
297 DestIterator
id, DestAccessor dest,
298 double angleInDegree)
300 TinyVector<double, 2> center((src.width()-1.0) / 2.0, (src.height()-1.0) / 2.0);
304 template <
int ORDER,
class T,
305 class DestIterator,
class DestAccessor>
308 pair<DestIterator, DestAccessor> dest,
309 double angleInDegree)
311 TinyVector<double, 2> center((src.width()-1.0) / 2.0, (src.height()-1.0) / 2.0);
312 rotateImage(src, dest.first, dest.second, angleInDegree, center);
406 template <
int ORDER,
class T,
407 class DestIterator,
class DestAccessor,
410 DestIterator dul, DestIterator dlr, DestAccessor dest,
411 MultiArrayView<2, double, C>
const & affineMatrix)
414 affineMatrix(2,0) == 0.0 && affineMatrix(2,1) == 0.0 && affineMatrix(2,2) == 1.0,
415 "affineWarpImage(): matrix doesn't represent an affine transformation with homogeneous 2D coordinates.");
418 double w = dlr.x - dul.x;
419 double h = dlr.y - dul.y;
421 for(
double y = 0.0; y < h; ++y, ++dul.y)
423 typename DestIterator::row_iterator rd = dul.rowIterator();
424 for(
double x=0.0; x < w; ++x, ++rd)
426 double sx = x*affineMatrix(0,0) + y*affineMatrix(0,1) + affineMatrix(0,2);
427 double sy = x*affineMatrix(1,0) + y*affineMatrix(1,1) + affineMatrix(1,2);
428 if(src.isInside(sx, sy))
429 dest.set(src(sx, sy), rd);
434 template <
int ORDER,
class T,
435 class DestIterator,
class DestAccessor,
439 triple<DestIterator, DestIterator, DestAccessor> dest,
440 MultiArrayView<2, double, C>
const & affineMatrix)
442 affineWarpImage(src, dest.first, dest.second, dest.third, affineMatrix);