Rotate Image & Video

Rotate Image

Rotating images by a given angle is a common image processing task. Although it seems little bit complicated, OpenCV provides some built-in functions making it easy to do it. Here is a simple OpenCV C++ example code to rotate an image. Here I use a track bar to change the rotating angle dynamically.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;

 int main( int argc, char** argv )
 {
// Load the image
Mat imgOriginal = imread( "MyPic.JPG", 1 );

//show the original image
const char* pzOriginalImage = "Original Image";
namedWindow( pzOriginalImage, CV_WINDOW_AUTOSIZE );
imshow( pzOriginalImage, imgOriginal );

const char* pzRotatedImage = "Rotated Image";
namedWindow( pzRotatedImage, CV_WINDOW_AUTOSIZE );

int iAngle = 180;
createTrackbar("Angle", pzRotatedImage, &iAngle, 360);

int iImageHieght = imgOriginal.rows / 2;
int iImageWidth = imgOriginal.cols / 2;

while (true)
{
Mat matRotation = getRotationMatrix2D( Point(iImageWidth, iImageHieght), (iAngle - 180), 1 );

// Rotate the image
Mat imgRotated;
warpAffine( imgOriginal, imgRotated, matRotation, imgOriginal.size() );

imshow( pzRotatedImage, imgRotated );

int iRet = waitKey(30);
if ( iRet == 27 )
{
break;
}
}

     return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
You can download this visual C++ project from here.
Original Image
Original Image

Rotated Image
Rotated Image


Explanation

Here is the explanation for new OpenCV functions which are not found in previous lessons.
  • Mat getRotationMatrix2D( Point2f center, double angle, double scale )

This function returns 2x3 affine transformation matrix for the 2D rotation.

Arguments -

    • center - The center of the rotation of the the source image. 
    • angle - Angle of rotation in degrees (Positive values for counter-clockwise direction and negative values for clockwise rotation)
    • scale - The scaling factor of the image. (Scaling factor of 1 means its original size)
Try different values for center, angle and scale and observe the output image.

  • void warpAffine( InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR, int bordreMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar() )
This OpenCV function applies affine transformation to an image.

Arguments - 
    • src - Source Image
    • dst - Destination image which should have the same type as the source image(The transformed image is stored in this location)
    • M - 2x3 affine transformation matrix
    • dsize - Size of the destination image
    • flags - Interpolation methods 
    • borderMode - pixel extrapolation method. (Try these values; BORDER_REPLICATE, BORDER_CONSTANT, BORDER_REFLECT, BORDER_WRAP, BORDER_REFLECT_101, BORDER_TRANSPARENT and BORDER_ISOLATED)
    • borderValue - If you use BORDER_CONSTANT for borderMode, this argument define the value used for the border


Another OpenCV Example to Rotate an Image


Here is another way to rotate an image. Here I use a callback function to apply the rotation instead of using a infinite while loop. Other than the rotation, you can change the scale of the image and border extrapolation method dynamically.

Here is the OpenCV C++ code.

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;

int iAngle = 180;
int iScale = 50;
int iBorderMode = 0;
Mat imgOriginal ;
int iImageCenterY = 0;
int iImageCenterX = 0;
const char* pzRotatedImage = "Rotated Image";

void CallbackForTrackBar(int, void*)
{
Mat matRotation = getRotationMatrix2D(  Point( iImageCenterX, iImageCenterY ), (iAngle - 180), iScale / 50.0 );

// Rotate the image
Mat imgRotated;
warpAffine( imgOriginal, imgRotated, matRotation, imgOriginal.size(), INTER_LINEAR, iBorderMode, Scalar() );

imshow( pzRotatedImage, imgRotated );

}

 int main( int argc, char** argv )
 {
// Load the image
imgOriginal = imread( "MyPic.JPG", 1 );

iImageCenterY = imgOriginal.rows / 2;
iImageCenterX = imgOriginal.cols / 2;

//show the original image
const char* pzOriginalImage = "Original Image";
namedWindow( pzOriginalImage, CV_WINDOW_AUTOSIZE );
imshow( pzOriginalImage, imgOriginal );

//create the "Rotated Image" window and 3 trackbars in it
namedWindow( pzRotatedImage, CV_WINDOW_AUTOSIZE );
createTrackbar("Angle", pzRotatedImage, &iAngle, 360, CallbackForTrackBar);
createTrackbar("Scale", pzRotatedImage, &iScale, 100, CallbackForTrackBar);
createTrackbar("Border Mode", pzRotatedImage, &iBorderMode, 5, CallbackForTrackBar);

int iDummy = 0;

CallbackForTrackBar(iDummy, &iDummy);

waitKey(0);

return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
You can download this visual C++ project from here.
Rotated Image which is down-scaled and whose border values have been extrapolated
Rotated Image which is down-scaled and whose border values have been extrapolated

All the OpenCV functions have been discussed previously.


Rotate a Video

Rotating a video is also simple. The code is just like the 1st example in this lesson. Here is the OpenCV C++ code.

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
    // open the video file for reading
    VideoCapture cap("C:/Users/SHERMAL/Desktop/MyVideo.mp4"); 

    // if not success, exit program
    if ( !cap.isOpened() )  
    {
         cout << "Cannot open the video file" << endl;
         return -1;
    }

    const char* pzOriginalWindowName = "Original Video";
    namedWindow(pzOriginalWindowName, CV_WINDOW_AUTOSIZE); 

    const char* pzRotatingWindowName = "Rotated Video";
    namedWindow( pzRotatingWindowName, CV_WINDOW_AUTOSIZE );

    int iAngle = 180;
    createTrackbar("Angle", pzRotatingWindowName, &iAngle, 360);


    while (true)
    {
        Mat matOriginalFrame;

// read a new frame from video
        bool bSuccess = cap.read(matOriginalFrame); 

//if not success, break loop
        if (!bSuccess) 
{
                       cout << "Cannot read the frame from video file" << endl;
                       break;
        }

        imshow(pzOriginalWindowName, matOriginalFrame);

//get the affine transformation matrix
Mat matRotation = getRotationMatrix2D( Point(matOriginalFrame.cols / 2, matOriginalFrame.rows / 2), (iAngle - 180), 1 );

// Rotate the image
Mat matRotatedFrame;
warpAffine( matOriginalFrame, matRotatedFrame, matRotation, matOriginalFrame.size() );

imshow( pzRotatingWindowName, matRotatedFrame );

//wait for 'esc' key press for 30 ms. If 'esc' key is pressed, break loop
        if (waitKey(30) == 27) 
{
                cout << "esc key is pressed by user" << endl; 
                break
}
    }

    return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
You can download this visual C++ project from here.

All the OpenCV functions, found in the above example have been discussed earlier.



Next Tutorial : Object Detection & Tracking using Color

Previous Tutorial : How to Detect Mouse Clicks and Moves