Image Rotation without cropping
Dears, With the below code, I rotate my cv::Mat object (I'm not using any Cv's functions, apart from load/save/convertionColor.., as this is a academic project) and I receive a cropped Image
rotation function:
float rads = angle*3.1415926/180.0;
float _cos = cos(rads);
float _sin = sin(rads);
float xcenter = (float)(src.cols)/2.0;
float ycenter = (float)(src.rows)/2.0;
for(int i = 0; i < src.rows; i++)
for(int j = 0; j < src.cols; j++){
int x = ycenter + ((float)(i)ycenter)*_cos  ((float)(j)xcenter)*_sin;
int y = xcenter + ((float)(i)ycenter)*_sin + ((float)(j)xcenter)*_cos;
if (x >= 0 && x < src.rows && y >= 0 && y < src.cols) {
dst.at<cv::Vec4b>(i ,j) = src.at<cv::Vec4b>(x, y);
}
else {
dst.at<cv::Vec4b>(i ,j)[3] = 0;
}
}
I would like to know, How I can keep my Full image every time I want to rotate it. Am I missing something in my function maybe? thanks in advance
1 answer

The rotated image usually has to be large than the old image to store all pixel values.
Each point
(x,y)
is translated to(x', y') = (x*cos(rads)  y*sin(rads), x*sin(rads) + y*cos(rads))
An image with height
h
and widthw
, center at (0,0) and corners at(h/2, w/2) (h/2, w/2) (h/2, w/2) (h/2, w/2)
has a new height of
h' = 2*y' = 2 * (w/2*sin(rads) + h/2*cos(rads))
and a new width of
w' = 2*x' = 2 * (w/2*cos(rads) + h/2*sin(rads))
for
0 <= rads <= pi/4
. It isx * y <= x' * y'
and forrads != k*pi/2
withk = 1, 2, ...
it isx * y < x' * y'
In any case the area of the rotated image is same size as or larger than the area of the old image.
If you use the old size, you cut off the corners.
Example:
Your image has
h=1
,w=1
andrads=pi/4
. You need a new image withh'=sqrt(2)=1.41421356237
andw'=sqrt(2)=1.41421356237
to store all pixel values. The pixel from (1,1) is translated to (0, sqrt(2)).