rotateImage.cpp
Go to the documentation of this file.
1  /**************************************************************************************************
2  Software License Agreement (BSD License)
3 
4  Copyright (c) 2011-2013, LAR toolkit developers - University of Aveiro - http://lars.mec.ua.pt
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without modification, are permitted
8  provided that the following conditions are met:
9 
10  *Redistributions of source code must retain the above copyright notice, this list of
11  conditions and the following disclaimer.
12  *Redistributions in binary form must reproduce the above copyright notice, this list of
13  conditions and the following disclaimer in the documentation and/or other materials provided
14  with the distribution.
15  *Neither the name of the University of Aveiro nor the names of its contributors may be used to
16  endorse or promote products derived from this software without specific prior written permission.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
19  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  ***************************************************************************************************/
27 
49 
50 
51 double rotateImage::round(double number) {
52  return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5);
53 }
54 
55 double rotateImage::degreeToRadian(double degree) {
56  return (M_PI*degree)/180.0;
57 }
58 
59 double rotateImage::radianToDegree(double radian) {
60  return (180*radian)/M_PI;
61 }
62 
63 Size rotateImage::rotationNewCanvasSize(double degree,double angle,double h) {
64  Size canvas(0,0);
65  double radian = degreeToRadian(degree);
66  if((degree >= 0 && degree <= 90) || (degree >= 181 && degree <= 270)) {
67  canvas.height = round((h*fabs(sin(angle+radian)))*2);
68  canvas.width = round((h*fabs(cos(M_PI-angle+radian)))*2);
69  } else {
70  canvas.height = round((h*fabs(sin(M_PI-angle+radian)))*2);
71  canvas.width = round((h*fabs(cos(angle+radian)))*2);
72  }
73  return canvas;
74 }
75 
76 double rotateImage::solveEquationY(Equ e,double x) {
77 
78  cout << x << endl;
79 
80  if(e.isVertical) return x;
81 
82  return e.m*x+e.c;
83 }
84 
85 double rotateImage::solveEquationX(Equ e, double y) {
86 
87  if(e.isVertical) return e.c;
88  if(e.isHorizontal) return 0;
89 
90  return (y-e.c)/e.m;
91 }
92 
93 map<string,int> rotateImage::rotationExtraMargins(Size &original, Size &newSize) {
94 
95  map<string,int> m = map<string,int>();
96 
97  if(newSize.height >= original.height) {
98  m["top"] = round((newSize.height-original.height)/2.0);
99  m["bottom"] = round((newSize.height-original.height)/2.0);
100  } else {
101  m["top"] = 0;
102  m["bottom"] = 0;
103  }
104 
105  if(newSize.width >= original.width) {
106  m["left"] = round((newSize.width-original.width)/2.0);
107  m["right"] = round((newSize.width-original.width)/2.0);
108  } else {
109  m["left"] = 0;
110  m["right"] = 0;
111  }
112 
113  return m;
114 }
115 
116 map<string,Point> rotateImage::getCorners(Size &original,map<string,int> &margins) {
117  map<string,Point> m = map<string,Point>();
118 
119  m["tl"] = Point(margins["left"],margins["top"]);
120  m["tr"] = Point(margins["left"]+original.width,margins["top"]);
121  m["bl"] = Point(margins["left"],margins["top"]+original.height);
122  m["br"] = Point(margins["left"]+original.width,margins["top"]+original.height);
123 
124  return m;
125 
126 }
127 
128 map<string,Point> rotateImage::getProjectedCorners(Size &s,double h,double degree,double angle) {
129 
130  map<string,Point> m = map<string,Point>();
131  double radian = degreeToRadian(degree);
132  int top,left;
133 
134  m["tl"] = Point(
135  round(s.width/2.0+h*cos(M_PI-angle+radian)),
136  round(s.height/2.0-h*sin(M_PI-angle+radian)));
137 
138  top = m["tl"].y;
139  left = m["tl"].x;
140 
141  m["tr"] = Point(
142  round(s.width/2.0+h*cos(angle+radian)),
143  round(s.height/2.0-h*sin(angle+radian)));
144 
145  if(top>m["tr"].y) top=m["tr"].y;
146  if(left>m["tr"].x) left=m["tr"].x;
147 
148  m["br"] = Point(
149  round(s.width/2.0+h*cos(-angle+radian)),
150  round(s.height/2.0-h*sin(-angle+radian)));
151 
152  if(top>m["br"].y) top=m["br"].y;
153  if(left>m["br"].x) left=m["br"].x;
154 
155  m["bl"] = Point(
156  round(s.width/2.0+h*cos(M_PI+angle+radian)),
157  round(s.height/2.0-h*sin(M_PI+angle+radian)));
158 
159  if(top>m["bl"].y) top=m["bl"].y;
160  if(left>m["bl"].x) left=m["bl"].x;
161 
162  m["tl"].x -= left;
163  m["tr"].x -= left;
164  m["bl"].x -= left;
165  m["br"].x -= left;
166 
167  m["tl"].y -= top;
168  m["tr"].y -= top;
169  m["bl"].y -= top;
170  m["br"].y -= top;
171 
172 
173  return m;
174 
175 }
176 
177 Point rotateImage::getCentreBetweenPoints(Point &a, Point &b) {
178  Point c(0,0);
179  double tmp;
180 
181  tmp = abs(a.x-b.x)/2.0;
182 
183  if(b.x <= a.x) c.x = round(tmp+b.x);
184  else c.x = round(tmp+a.x);
185 
186  tmp = abs(a.y-b.y)/2.0;
187 
188  if(b.y <= a.y) c.y = round(tmp+b.y);
189  else c.y = round(tmp+a.y);
190 
191  return c;
192 }
193 
194 map<string,Point> rotateImage::getCentreBetweenOriginalsAndProjections(map<string,Point> &originals,map<string,Point> &projections) {
195  map<string,Point> m = map<string,Point>();
196 
197  m["tl"] = getCentreBetweenPoints(originals["tl"],projections["tl"]);
198  m["tr"] = getCentreBetweenPoints(originals["tr"],projections["tr"]);
199  m["bl"] = getCentreBetweenPoints(originals["bl"],projections["bl"]);
200  m["br"] = getCentreBetweenPoints(originals["br"],projections["br"]);
201 
202  return m;
203 
204 }
205 
207 
208  Equ equation;
209 
210  equation.isVertical = false;
211  equation.isHorizontal = false;
212 
213  if(a.x-b.x==0) {
214  equation.c = a.x;
215  equation.m = 0;
216  equation.isVertical = true;
217  } else if(a.y-b.y==0) {
218  equation.c = a.y;
219  equation.m = 0;
220  equation.isHorizontal = true;
221  } else {
222  equation.m = (double)(a.y-b.y)/(a.x-b.x);
223  equation.c = a.y-equation.m*a.x;
224  }
225 
226  return equation;
227 
228 }
229 
231  Equ equation;
232 
233  equation.isVertical = false;
234  equation.isHorizontal = false;
235 
236  if(e.isHorizontal) {
237  equation.c = p.x;
238  equation.m = 0;
239  equation.isVertical = true;
240  } else if(e.isVertical) {
241  equation.c = p.y;
242  equation.m = 0;
243  equation.isHorizontal = true;
244  } else {
245  equation.m = -1.0/e.m;
246  equation.c = -p.x*equation.m+p.y;
247  }
248 
249  return equation;
250 
251 }
252 
253 map<string,Equ> rotateImage::getLinearEquationBetweenOriginalsAndProjections(map<string,Point> &originals,map<string,Point> &projections) {
254  map<string,Equ> m = map<string,Equ>();
255 
256  m["tl"] = getLinearEquation(originals["tl"],projections["tl"]);
257  m["tr"] = getLinearEquation(originals["tr"],projections["tr"]);
258  m["bl"] = getLinearEquation(originals["bl"],projections["bl"]);
259  m["br"] = getLinearEquation(originals["br"],projections["br"]);
260 
261  return m;
262 }
263 
264 map<string,Equ> rotateImage::getPerpendicularLinearEquation(map<string,Point> &originals,map<string,Point> &projections,map<string,Point> &centre) {
265  map<string,Equ> m = map<string,Equ>();
266 
267  m["tl"] = getPerpendicular(getLinearEquation(originals["tl"],projections["tl"]),centre["tl"]);
268  m["tr"] = getPerpendicular(getLinearEquation(originals["tr"],projections["tr"]),centre["tr"]);
269  m["bl"] = getPerpendicular(getLinearEquation(originals["bl"],projections["bl"]),centre["bl"]);
270  m["br"] = getPerpendicular(getLinearEquation(originals["br"],projections["br"]),centre["br"]);
271 
272  return m;
273 }
274 
276 
277  Point2d p = Point2d(0,0);
278 
279  if(e1.isHorizontal && e2.isVertical) {
280 
281  p.x = e2.c;
282  p.y = e1.c;
283 
284  } else if(e1.isVertical && e2.isHorizontal) {
285 
286  p.x = e1.c;
287  p.y = e2.c;
288 
289  } else if(e1.isHorizontal) {
290 
291  p.y = e1.c;
292  p.x = (p.y-e2.c)/e2.m;
293 
294  } else if(e2.isHorizontal) {
295 
296  p.y = e2.c;
297  p.x = (p.y-e1.c)/e1.m;
298 
299  } else if(e1.isVertical) {
300 
301  p.x = e1.c;
302  p.y = p.x*e2.m+e2.c;
303 
304  } else if(e2.isVertical) {
305 
306  p.x = e2.c;
307  p.y = p.x*e1.m+e1.c;
308 
309  } else {
310 
311  p.y = fabs(e1.c*e2.m-e2.c*e1.m)/fabs(e1.m-e2.m);
312  p.x = (p.y-e1.c)/e1.m;
313 
314  }
315 
316  return Point(round(p.x),round(p.y));
317 }
322 void rotateImage::rotate_image(Mat & src, Mat & dst,const double degree)
323  {
324 
325  Mat copy,schema,rot_mat;
326  map<string,int> margins; //?? index por "string" e guarda inteiros
327  Size img,canvas,workspace;// estrutura do tipo size!
328 
329  double h,angle;//degree;
330  map<string,Point> original, projection, centre; //??
331 
332  map<string,Equ> pEqu;
333 
334  Point2f src_centre; //center point
335 
336  img = Size(src.cols,src.rows);
337  h = sqrt(pow(img.width/2.0,2) + pow(img.height/2.0,2));
338  angle = atan((double)img.height/img.width);
339 
340  canvas = rotationNewCanvasSize(degree,angle,h);
341  margins = rotationExtraMargins(img,canvas);
342  copyMakeBorder(src,copy,margins["top"],margins["bottom"],margins["left"],
343  margins["right"],BORDER_CONSTANT,Scalar(0,0,0));
344  copy.copyTo(schema);
345  workspace = Size(copy.cols,copy.rows);
346 
347  original = getCorners(img,margins);
348  projection = getProjectedCorners(canvas,h,degree,angle);
349  centre = getCentreBetweenOriginalsAndProjections(original,projection);
350  pEqu = getPerpendicularLinearEquation(original,projection,centre);
351 
352 
353  if(img.width > canvas.width || img.height > canvas.height) {
354  Point p = getColisionPoint(pEqu["tl"],pEqu["tr"]);
355  src_centre = Point2f(p.x,p.y);
356  } else {
357  src_centre = Point2f(canvas.width/2.0,canvas.height/2.0);
358  }
359 
360 
361  dst.create(canvas.height,canvas.width,src.channels());
362  rot_mat = getRotationMatrix2D(src_centre, degree, 1.0);
363  cv::warpAffine(copy, dst, rot_mat,canvas);
364 
365 }
static Point getColisionPoint(Equ e1, Equ e2)
double c
Definition: rotateImage.h:72
static double radianToDegree(double radian)
Definition: rotateImage.cpp:59
static double solveEquationX(Equ e, double y)
Definition: rotateImage.cpp:85
static map< string, Point > getCorners(Size &original, map< string, int > &margins)
static Equ getPerpendicular(Equ e, Point p)
static map< string, Point > getCentreBetweenOriginalsAndProjections(map< string, Point > &originals, map< string, Point > &projections)
bool isHorizontal
Definition: rotateImage.h:74
static double degreeToRadian(double degree)
Definition: rotateImage.cpp:55
static map< string, Equ > getLinearEquationBetweenOriginalsAndProjections(map< string, Point > &originals, map< string, Point > &projections)
double m
Definition: rotateImage.h:71
static map< string, Point > getProjectedCorners(Size &s, double h, double degree, double angle)
static double round(double number)
Definition: rotateImage.cpp:51
static Point getCentreBetweenPoints(Point &a, Point &b)
static double solveEquationY(Equ e, double x)
Definition: rotateImage.cpp:76
static void rotate_image(Mat &src, Mat &dst, const double degree)
helper function to rotate an image.
static Size rotationNewCanvasSize(double degree, double angle, double h)
Definition: rotateImage.cpp:63
bool isVertical
Definition: rotateImage.h:73
static map< string, Equ > getPerpendicularLinearEquation(map< string, Point > &originals, map< string, Point > &projections, map< string, Point > &centre)
static map< string, int > rotationExtraMargins(Size &original, Size &newSize)
Definition: rotateImage.cpp:93
static Equ getLinearEquation(Point &a, Point &b)


arrow_detection
Author(s): César Sousa
autogenerated on Mon Mar 2 2015 01:31:21