1

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;
        }
    }

before

after

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

Miki
  • 40,887
  • 13
  • 123
  • 202
  • 1
    When you rotate an image, the height and width will change. – 1201ProgramAlarm Jul 18 '19 at 15:10
  • If you were allowed to use OpenCV functions, this would be a duplicate: https://stackoverflow.com/questions/22041699/rotate-an-image-without-cropping-in-opencv-in-c. Since you are not, you need to figure out yourself how much borders you need to add on each side (or how much you can crop). – chtz Jul 18 '19 at 15:25
  • N.B. To reduce the number of branches, I would calculate once per row what is the first and last column for which the rotated pixel is valid. – chtz Jul 18 '19 at 15:28

1 Answers1

2

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 width w, 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 is x * y <= x' * y' and for rads != k*pi/2 with k = 1, 2, ... it is x * 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 and rads=pi/4. You need a new image with h'=sqrt(2)=1.41421356237 and w'=sqrt(2)=1.41421356237 to store all pixel values. The pixel from (1,1) is translated to (0, sqrt(2)).

Thomas Sablik
  • 16,127
  • 7
  • 34
  • 62