Rotate Opencv Matrix by 90, 180, 270 degrees

<>

This question already has an answer here:

Answers


Use warpAffine.:

Try:

Point2f src_center(source.cols/2.0F, source.rows/2.0F);
Mat rot_mat = getRotationMatrix2D(src_center, angle, 1.0);
Mat dst;
warpAffine(source, dst, rot_mat, source.size());

dst is the final image


The above answers are too complex and hog your CPU. Your question was not arbitrary rotation, but 'Rotate Opencv Matrix by 90, 180, 270 degrees'.

UPDATE 30 JUN 2017:

This functionality is supported by OpenCV, but not documented: https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core.hpp#L1041

void rotate(InputArray src, OutputArray dst, int rotateCode);

with

enum RotateFlags {
    ROTATE_90_CLOCKWISE = 0, //Rotate 90 degrees clockwise
    ROTATE_180 = 1, //Rotate 180 degrees clockwise
    ROTATE_90_COUNTERCLOCKWISE = 2, //Rotate 270 degrees clockwise
};

Original Answer & Arbitrary degree rotation:

You can also do this by using flip and transpose operation, ie for 90CW:

transpose(matSRC, matROT);  
flip(matROT, matROT,1); //transpose+flip(1)=CW

etc. Figure out the other commands yourself (thinking=learning) by introducing yourself with the transpose and flip operation form the Docs.

void rot90(cv::Mat &matImage, int rotflag){
  //1=CW, 2=CCW, 3=180
  if (rotflag == 1){
    transpose(matImage, matImage);  
    flip(matImage, matImage,1); //transpose+flip(1)=CW
  } else if (rotflag == 2) {
    transpose(matImage, matImage);  
    flip(matImage, matImage,0); //transpose+flip(0)=CCW     
  } else if (rotflag ==3){
    flip(matImage, matImage,-1);    //flip(-1)=180          
  } else if (rotflag != 0){ //if not 0,1,2,3:
    cout  << "Unknown rotation flag(" << rotflag << ")" << endl;
  }
}

So you call it like this, and note the matrix is passed by reference.

cv::Mat matImage;
//Load in sensible data
rot90(matImage,3); //Rotate it

//Note if you want to keep an original unrotated version of 
// your matrix as well, just do this
cv::Mat matImage;
//Load in sensible data
cv::Mat matRotated = matImage.clone();
rot90(matImage,3); //Rotate it

Rotate by arbitrary degrees While I'm at it, here is how to rotate by an arbitrary degree, which i expect to be 50x more expensive. Note that rotation in this manner will include black padding, and edges will be rotated to oustide of the image's original size.

void rotate(cv::Mat& src, double angle, cv::Mat& dst){
    cv::Point2f ptCp(src.cols*0.5, src.rows*0.5);
    cv::Mat M = cv::getRotationMatrix2D(ptCp, angle, 1.0);
    cv::warpAffine(src, dst, M, src.size(), cv::INTER_CUBIC); //Nearest is too rough, 
}

Calling this for a rotation of 10.5 degrees then is obviously:

cv::Mat matImage, matRotated;
//Load in data
rotate(matImage, 10.5, matRotated);

I find it remarkable that these kind of extremely basic functions are not part of OpenCV, while OpenCV does have native things like face detection (that's not really maintained with questionable performance). Remarkable.

Cheers


@Abhishek Thakur's answer only works well for rotating the image by 180 degrees. It does not handle the rotation by 90 degrees because

  • the center of rotation supplied to getRotationMatrix2D is incorrect, and
  • output matrix size passed to warpAffline is incorrect.

Here's the code that rotates an image by 90 degrees:

Mat src = imread("image.jpg");
Mat dst;

double angle = 90;  // or 270
Size src_sz = src.size();
Size dst_sz(src_sz.height, src_sz.width); 

int len = std::max(src.cols, src.rows); 
Point2f center(len/2., len/2.);
Mat rot_mat = cv::getRotationMatrix2D(center, angle, 1.0);
warpAffine(src, dst, rot_mat, dst_sz);

Edit: Another approach to rotate images by 90,180 or 270 degrees involves doing matrix transpose and then flip. This method is probably faster.


The above code works just fine, but introduces numerical error in the image due to the matrix computations being done in floating point and the warpAffine interpolation.

For a 90deg increment rotation I prefer to use the following (in python/opencv python)

Since OpenCV images in Python are 2d Numpy Arrays.

90 deg. theImage = numpy.rot90( theImage, 1 ) 270 deg. theImage = numpy.rot90( theImage, 3 )

Note: I only tested this on gray scale images of shape ( X, Y ). If you have a color (or other multi-separation) image you might need to reshape it first to make sure that the rotation works along the correct axis.


Need Your Help

Whether to use "SET NAMES"

php python mysql internationalization

In reading "High performance MySQL" from O'Reilly I've stumbled upon the following

Can Python's optparse display the default value of an option?

python optparse

Is there a way to make Python's optparse print the default value of an option or flag when showing the help with --help?