SoFunction
Updated on 2024-12-20

Example of rotating a picture at any angle in opencv

I Calculation of rotation angle coordinates

1. If point O is the center of the circle, then after point P rotates around point O by redian radians, the coordinates of point P are transformed to point Q by the following formula.

=*cos(redian)-*sin(redian)

=*sin(redian)+*cos(redian)

The redian is in radians.

The formula for transforming radians to angles is.

redian=pi*180/angle

2. If point O is not the center of the circle, the transformation of the coordinates of point P into Q after the point P has been rotated around point O by redian radians is given by.

=()*cos(redian)-()*sin(redian)+

=()*sin(redian)+()*cos(redian)+

II Steps for rotating an arbitrary angle

1. First of all, the default rotation of 45 degrees, the maximum expansion of the image, that is, for the root of two times the length or width of the maximum value of the image will be filled to the maximum possible

2 use getRotationMatrix2D function to obtain the rotation matrix, using the warpAffine function to rotate the matrix

3 Find the largest rectangle that includes the image after rotation.

4 Remove excess black border

III. Realization

#include <iostream>
#include<opencv2/>
 
using namespace cv;
 
void rotate_arbitrarily_angle(Mat &src,Mat &dst,float angle)
{
    float radian = (float) (angle /180.0 * CV_PI);
 
    //fill image
    int maxBorder =(int) (max(, )* 1.414 ); //that is sqrt(2)*max
    int dx = (maxBorder - )/2;
    int dy = (maxBorder - )/2;
    copyMakeBorder(src, dst, dy, dy, dx, dx, BORDER_CONSTANT);
 
    //Rotation
    Point2f center( (float)(/2) , (float) (/2));
    Mat affine_matrix = getRotationMatrix2D( center, angle, 1.0 );// Find the rotation matrix
    warpAffine(dst, dst, affine_matrix, ());
 
    // Calculate the largest rectangle that contains the image after rotation.
    float sinVal = abs(sin(radian));
    float cosVal = abs(cos(radian));
    Size targetSize( (int)( * cosVal + * sinVal),
                     (int)( * sinVal +  * cosVal) );
 
    //Cut off excess border
    int x = ( - ) / 2;
    int y = ( - ) / 2;
    Rect rect(x, y, , );
    dst = Mat(dst,rect);
}
 
int main() {
    cv::Mat src=cv::imread("../");
    cv::Mat dst;
    rotate_arbitrarily_angle(src,dst,30);
    cv::imshow("src",src);
    cv::imshow("dst",dst);
    cv::waitKey(0);
    return 0;
}

original figure

The result of a 30 degree rotation around the center point

It should be noted that the method only applies to the horizontal image rotated to an angle of the image, as for the method can be randomly rotated angle I do not know how to complete, later have the opportunity to do.

The above approach also has a major drawback is that after the rotation of the pixel size changes, if you want to manipulate the pixel will cause a lot of problems, the next code will fix the pixel, but also for the rotation to a certain angle and then return to the horizontal position of the code, has a great limitation, research to understand and then update the other situations

cv::Mat rotate_arbitrarily_angle1(cv::Mat matSrc, float angle, bool direction,int height,int width) {
    float theta = angle * CV_PI / 180.0;
    int nRowsSrc = ;
    int nColsSrc = ; // If clockwise rotation
    if (!direction) theta = 2 * CV_PI - theta; // All calculated in counterclockwise rotation
    // Rotate the matrix counterclockwise
    float matRotate[3][3]{ {
                                   std::cos(theta), -std::sin(theta), 0},
                           {std::sin(theta), std::cos(theta), 0 },
                           {0, 0, 1} };
 
    float pt[3][2]{
            { 0, nRowsSrc },
            {nColsSrc, nRowsSrc},
            {nColsSrc, 0} };
 
    for (int i = 0; i < 3; i++) {
        float x = pt[i][0] * matRotate[0][0] + pt[i][1] * matRotate[1][0];
        float y = pt[i][0] * matRotate[0][1] + pt[i][1] * matRotate[1][1];
        pt[i][0] = x; pt[i][1] = y;
    }
    // Calculate the extreme points and dimensions of the rotated image
    float fMin_x = std::min(std::min(std::min(pt[0][0], pt[1][0]), pt[2][0]), (float)0.0);
    float fMin_y = std::min(std::min(std::min(pt[0][1], pt[1][1]), pt[2][1]), (float)0.0);
    float fMax_x = std::max(std::max(std::max(pt[0][0], pt[1][0]), pt[2][0]), (float)0.0);
    float fMax_y = std::max(std::max(std::max(pt[0][1], pt[1][1]), pt[2][1]), (float)0.0);
    int nRows = cvRound(fMax_y - fMin_y + 0.5) + 1;
    int nCols = cvRound(fMax_x - fMin_x + 0.5) + 1;
    int nMin_x = cvRound(fMin_x + 0.5);
    int nMin_y = cvRound(fMin_y + 0.5);
    // Copy the output image
    cv::Mat matRet(nRows, nCols, (), cv::Scalar(0));
    for (int j = 0; j < nRows; j++) {
        for (int i = 0; i < nCols; i++) {
            // Calculate the coordinates of the corresponding point of the output image in the original image, and then copy the grayscale value of that coordinate
            // Since the conversion is counterclockwise, the mapping to the original image here can be seen as, well, an output image
            // to the clockwise rotation to the original image, and the clockwise rotation matrix just happens to be the transpose of the counterclockwise rotation matrix
            // Also consider moving the upper left corner of the rotated image to the coordinate origin.
            int x = (i + nMin_x) * matRotate[0][0] + (j + nMin_y) * matRotate[0][1];
            int y = (i + nMin_x) * matRotate[1][0] + (j + nMin_y) * matRotate[1][1];
            if (x >= 0 && x < nColsSrc && y >= 0 && y < nRowsSrc) {
                <uchar>(j, i) = <uchar>(y, x);
            }
        }
    }
    if(direction== false){// When clockwise rotation back to the horizontal position is required
        int x = ( -width) / 2;
        int y = ( -height) / 2;
 
        //width and height are the width and height of the image under horizontal conditions
        cv::Rect rect(x, y, width, height);
        matRet = cv::Mat(matRet,rect);
    }
    return matRet;
}

to this article on the opencv image rotation at any angle to achieve the example of the article is introduced to this, more related opencv image rotation at any angle content please search my previous posts or continue to browse the following related articles I hope that you will support me in the future more!