Easiest way to rotate by 90 degrees an image using OpenCV?

后端 未结 7 990
轮回少年
轮回少年 2020-11-29 05:52

What is the best way (in c/c++) to rotate an IplImage/cv::Mat by 90 degrees? I would assume that there must be something better than transforming it using a matrix, but I ca

相关标签:
7条回答
  • 2020-11-29 06:06

    Here's my EmguCV (a C# port of OpenCV) solution:

    public static Image<TColor, TDepth> Rotate90<TColor, TDepth>(this Image<TColor, TDepth> img)
        where TColor : struct, IColor
        where TDepth : new()
    {
        var rot = new Image<TColor, TDepth>(img.Height, img.Width);
        CvInvoke.cvTranspose(img.Ptr, rot.Ptr);
        rot._Flip(FLIP.HORIZONTAL);
        return rot;
    }
    
    public static Image<TColor, TDepth> Rotate180<TColor, TDepth>(this Image<TColor, TDepth> img)
        where TColor : struct, IColor
        where TDepth : new()
    {
        var rot = img.CopyBlank();
        rot = img.Flip(FLIP.VERTICAL);
        rot._Flip(FLIP.HORIZONTAL);
        return rot;
    }
    
    public static void _Rotate180<TColor, TDepth>(this Image<TColor, TDepth> img)
        where TColor : struct, IColor
        where TDepth : new()
    {
        img._Flip(FLIP.VERTICAL);
        img._Flip(FLIP.HORIZONTAL);
    }
    
    public static Image<TColor, TDepth> Rotate270<TColor, TDepth>(this Image<TColor, TDepth> img)
        where TColor : struct, IColor
        where TDepth : new()
    {
        var rot = new Image<TColor, TDepth>(img.Height, img.Width);
        CvInvoke.cvTranspose(img.Ptr, rot.Ptr);
        rot._Flip(FLIP.VERTICAL);
        return rot;
    }
    

    Shouldn't be too hard to translate it back into C++.

    0 讨论(0)
  • 2020-11-29 06:07

    Well I was looking for some details and didn't find any example. So I am posting a transposeImage function which, I hope, will help others who are looking for a direct way to rotate 90° without losing data:

    IplImage* transposeImage(IplImage* image) {
    
        IplImage *rotated = cvCreateImage(cvSize(image->height,image->width),   
            IPL_DEPTH_8U,image->nChannels);
        CvPoint2D32f center;
        float center_val = (float)((image->width)-1) / 2;
        center.x = center_val;
        center.y = center_val;
        CvMat *mapMatrix = cvCreateMat( 2, 3, CV_32FC1 );        
        cv2DRotationMatrix(center, 90, 1.0, mapMatrix);
        cvWarpAffine(image, rotated, mapMatrix, 
            CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, 
            cvScalarAll(0));      
        cvReleaseMat(&mapMatrix);
    
        return rotated;
    }
    

    Question : Why this?

    float center_val = (float)((image->width)-1) / 2; 
    

    Answer : Because it works :) The only center I found that doesn't translate image. Though if somebody has an explanation I would be interested.

    0 讨论(0)
  • 2020-11-29 06:15

    This is an example without the new C++ interface (works for 90, 180 and 270 degrees, using param = 1, 2 and 3). Remember to call cvReleaseImage on the returned image after using it.

    IplImage *rotate_image(IplImage *image, int _90_degrees_steps_anti_clockwise)
    {
        IplImage *rotated;
    
        if(_90_degrees_steps_anti_clockwise != 2)
            rotated = cvCreateImage(cvSize(image->height, image->width), image->depth, image->nChannels);
        else
            rotated = cvCloneImage(image);
    
        if(_90_degrees_steps_anti_clockwise != 2)
            cvTranspose(image, rotated);
    
        if(_90_degrees_steps_anti_clockwise == 3)
            cvFlip(rotated, NULL, 1);
        else if(_90_degrees_steps_anti_clockwise == 1)
            cvFlip(rotated, NULL, 0);
        else if(_90_degrees_steps_anti_clockwise == 2)
            cvFlip(rotated, NULL, -1);
    
        return rotated;
    }
    
    0 讨论(0)
  • 2020-11-29 06:20

    Rotation is a composition of a transpose and a flip.

    R_{+90} = F_x \circ T

    R_{-90} = F_y \circ T

    Which in OpenCV can be written like this (Python example below):

    img = cv.LoadImage("path_to_image.jpg")
    timg = cv.CreateImage((img.height,img.width), img.depth, img.channels) # transposed image
    
    # rotate counter-clockwise
    cv.Transpose(img,timg)
    cv.Flip(timg,timg,flipMode=0)
    cv.SaveImage("rotated_counter_clockwise.jpg", timg)
    
    # rotate clockwise
    cv.Transpose(img,timg)
    cv.Flip(timg,timg,flipMode=1)
    cv.SaveImage("rotated_clockwise.jpg", timg)
    
    0 讨论(0)
  • 2020-11-29 06:22

    Here is my python cv2 implementation:

    import cv2
    
    img=cv2.imread("path_to_image.jpg")
    
    # rotate ccw
    out=cv2.transpose(img)
    out=cv2.flip(out,flipCode=0)
    
    # rotate cw
    out=cv2.transpose(img)
    out=cv2.flip(out,flipCode=1)
    
    cv2.imwrite("rotated.jpg", out)
    
    0 讨论(0)
  • 2020-11-29 06:23

    As of OpenCV3.2, life just got a bit easier, you can now rotate an image in a single line of code:

    cv::rotate(image, image, cv::ROTATE_90_CLOCKWISE);
    

    For the direction you can choose any of the following:

    ROTATE_90_CLOCKWISE
    ROTATE_180
    ROTATE_90_COUNTERCLOCKWISE
    
    0 讨论(0)
提交回复
热议问题