KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
affine.h
Go to the documentation of this file.
1 // affine.h - image affine transform class
3 // Author: Doron Tal
4 // Date created: February, 1996
5 
6 #ifndef _AFFINE_H
7 #define _AFFINE_H
8 
9 #include "wrap_dtlib_cpp/img.h"
10 
11 namespace DTLib {
12 
13  // NOTE: affine transform performed by this class is followed
14  // by a bilinear interpolation step.
15  // NOTE: template functions must be inlined here, but non-template
16  // functions still reside in affine.cpp.
17 
18  class CAffine
19  {
20  public:
21  // To use, construct an affine object, then call
22  // Setup(), then call Transform().
23  CAffine();
24 
25  // Precompute affine transform parameters
26  void Setup(const int& in_x1, const int& in_y1,
27  const int& in_x2, const int& in_y2,
28  const int& out_x1, const int& out_y1,
29  const int& out_x2, const int& out_y2);
30 
31  // Using Affine coefficients of the last call to Setup() or
32  // Transform(), returns the point (ix, iy) in the input Img
33  // that maps into the given point (ox, oy) in the output Img.
34  // I.e. suppose we've transformed one image into another using
35  // CAffine and we want to know for some point in the transformed
36  // image where it came from, this function will give you the
37  // coordinates in the pre-transformed image of a point in the
38  // transformed image.
39  // POSTCOND: result is in 'ix' and 'iy'
40  inline void Out2In(const int& out_x, const int& out_y,
41  int& in_x, int& in_y) {
42  in_x = F2I(m_rct*out_x-m_rst*out_y+m_C);
43  in_y = F2I(m_rst*out_x+m_rct*out_y+m_c);
44  };
45 
46  // This is the function that does the work (main loop).
47  // PRECOND: you've called Setup() before
48  // POSTCODN: result of transform is in 'OutImg'
49  template <class T>
50  void Transform(CImg<T>& InImg, CImg<T>& OutImg, const T& BGVal = 0) {
51  const float oWidth = (float)OutImg.Width(),
52  oHeight = (float)OutImg.Height();
53  const int iWidth = InImg.Width(), iHeight = InImg.Height();
54  const int iWidthM1 = iWidth-1, iHeightM1 = iHeight-1;
55  T *pOut = OutImg.pBuffer(), *pIn = InImg.pBuffer();
56  for (float oy = 0.0f; oy < oHeight; oy++) {
57  for (float ox = 0.0f; ox < oWidth; ox++, pOut++) {
58  float ix = m_rct*ox-m_rst*oy+m_C;
59  float iy = m_rst*ox+m_rct*oy+m_c;
60  int ix_i = (int)ix;
61  int iy_i = (int)iy;
62  if ((ix_i < 0) ||
63  (ix_i > iWidthM1) ||
64  (iy_i < 0) ||
65  (iy_i > iHeightM1)) {
66  *pOut = BGVal;
67  continue;
68  }
69  float dx = ix-(float)ix_i;
70  float dx1 = 1.0f-dx;
71  float dy = iy-(float)iy_i;
72  float dy1 = 1.0f-dy;
73  T *pUL = pIn+iy_i*iWidth+ix_i, *pLL, *pUR, *pLR;
74  if (ix_i == iWidthM1) pUR = pUL;
75  else pUR = pUL+1;
76  if (iy_i == iHeightM1) { pLL = pUL; pLR = pUR; }
77  else {pLL = pUL+iWidth; pLR = pUR+iWidth; }
78  *pOut = (T)((float)*pUL*dx1*dy1+(float)*pUR*dx*dy1+
79  (float)*pLL*dx1*dy+(float)*pLR*dx*dy);
80  } // for ox
81  } // for oy
82  };
83 
84  private:
85 
86  float m_rho; // degree of dilation/expansion (in/out size change)
87  float m_theta; // degree of rotation
88  float m_rct; // rho*cos(Theta)
89  float m_rst; // rho*sin(Theta)
90  float m_C; // translation in x
91  float m_c; // translation in y
92  }; // class CAffine
93 } // namespace DTLib {
94 
95 #endif /* #ifndef _AFFINE_H */
#define F2I(x)
Definition: utils.h:111
void Transform(CImg< T > &InImg, CImg< T > &OutImg, const T &BGVal=0)
Definition: affine.h:50
Definition: img.h:51
int Width() const
Definition: img.h:135
void Out2In(const int &out_x, const int &out_y, int &in_x, int &in_y)
Definition: affine.h:40
Definition: affine.h:18
void Setup(const int &in_x1, const int &in_y1, const int &in_x2, const int &in_y2, const int &out_x1, const int &out_y1, const int &out_x2, const int &out_y2)
Definition: affine.cpp:22
int Height() const
Definition: img.h:138
T * pBuffer()
Definition: img.h:148
CAffine()
Definition: affine.cpp:12