vil_rotate.hxx
Go to the documentation of this file.
1 // This is core/vil/vil_rotate.hxx
2 #ifndef vil_rotate_hxx_
3 #define vil_rotate_hxx_
4 //:
5 // \file
6 // \brief rotate an image, using the resampling functions
7 // \author dac
8 //
9 // A front end to the resampling functions that allows
10 // an image to be rotated by any angle theta
11 
12 #include <cmath>
13 #include "vil_rotate.h"
14 #include <vil/vil_resample_bilin.h>
15 #include <cassert>
16 #ifdef _MSC_VER
17 # include <vcl_msvc_warnings.h>
18 #endif
19 
20 //: Calculate theta in range 0 to x
21 static inline double calc_theta_mod(double theta, double x)
22 {
23  if (x<0) x=-x;
24  double theta_x = std::fmod(theta,x);
25  if (theta_x<0)
26  theta_x += x;
27  return theta_x;
28 }
29 
30 //: Rotate image by angle theta ( here theta is in degrees)
31 template <class sType, class dType>
33  vil_image_view<dType>& dest_image,
34  double theta_deg)
35 {
36  // nb if theta = 0, 90, 180 or 270 should employ a simpler + faster method
37  // of rotating the image! But at least, in those cases, d[xy][12] are 0 or 1.
38 
39  double theta_90= calc_theta_mod( theta_deg, 90.0 );
40  double theta_360= calc_theta_mod( theta_deg, 360.0 );
41 #ifdef DEBUG
42  std::cout<<"theta_90 = "<<theta_90<<std::endl
43  <<"theta_360= "<<theta_360<<std::endl;
44 #endif
45 
46  // calculate dimensions of rotated image
47  // a---b
48  // | |
49  // c---d
50  int src_ni = src_image.ni();
51  int src_nj = src_image.nj();
52  double c= std::cos(theta_90*3.14159265358979323846/180);
53  double s= std::sin(theta_90*3.14159265358979323846/180);
54 
55  // calc corners of grid to sample (in original image frame)
56  double ai= -src_nj*s*c;
57  double aj= src_nj*s*s;
58  double bi= src_ni*c*c;
59  double bj= -src_ni*s*c;
60  double ci= src_ni*s*s;
61  double cj= src_nj-bj;
62  double di= src_ni-ai;
63  double dj= src_nj*c*c;
64 
65  // size of destination image
66  int l1= int( src_nj*s+ src_ni*c );
67  int l2= int( src_nj*c+ src_ni*s );
68 
69  // set up directions for sampling src image
70  // nb varies every 90 degrees ( ie different corner at top of image!)
71  double dx1, dy1, dx2, dy2, x0, y0;
72  int n1,n2;
73 
74  assert(theta_360>= 0.0 && theta_360 < 360.0);
75 
76  if ( theta_360< 90.0 )
77  {
78  dx1= (bi-ai)/l1;
79  dy1= (bj-aj)/l1;
80  dx2= (ci-ai)/l2;
81  dy2= (cj-aj)/l2;
82  x0 = ai;
83  y0 = aj;
84  n1 = l1;
85  n2 = l2;
86  }
87  else if (theta_360< 180.0 )
88  {
89  dx1= (ai-ci)/l2;
90  dy1= (aj-cj)/l2;
91  dx2= (di-ci)/l1;
92  dy2= (dj-cj)/l1;
93  x0 = ci;
94  y0 = cj;
95  n1 = l2;
96  n2 = l1;
97  }
98  else if (theta_360< 270.0 )
99  {
100  dx1= (ci-di)/l1;
101  dy1= (cj-dj)/l1;
102  dx2= (bi-di)/l2;
103  dy2= (bj-dj)/l2;
104  x0 = di;
105  y0 = dj;
106  n1 = l1;
107  n2 = l2;
108  }
109  else // if (theta_360< 360.0 )
110  {
111  dx1= (di-bi)/l2;
112  dy1= (dj-bj)/l2;
113  dx2= (ai-bi)/l1;
114  dy2= (aj-bj)/l1;
115  x0 = bi;
116  y0 = bj;
117  n1 = l2;
118  n2 = l1;
119  }
120 
121  vil_resample_bilin(src_image, dest_image, x0, y0, dx1, dy1, dx2, dy2, n1, n2 );
122 }
123 
124 #define VIL_ROTATE_INSTANTIATE( sType, dType ) \
125 template void vil_rotate_image(const vil_image_view<sType >& src_image, \
126  vil_image_view<dType >& dest_image, \
127  double theta)
128 
129 #endif // vil_rotate_hxx_
Concrete view of image data of type T held in memory.
Definition: vil_fwd.h:13
void vil_rotate_image(const vil_image_view< sType > &src_image, vil_image_view< dType > &dest_image, double theta_deg)
Rotate image by angle theta.
Sample grid of points with bilinear interpolation in one image and place in another.
rotate an image, using the resampling functions
unsigned ni() const
Width.
unsigned nj() const
Height.
void vil_resample_bilin(const vil_image_view< sType > &src_image, vil_image_view< dType > &dest_image, double x0, double y0, double dx1, double dy1, double dx2, double dy2, int n1, int n2)
Sample grid of points in one image and place in another, using bilinear interpolation.