views:

851

answers:

3

What is the best way (in c/c++) to rotate an IplImage by 90 degrees? I would assume that there must be something better than transforming it using a matrix, but I can't seem to find anything other than that in the API and online.

+2  A: 

Update for transposition:

You should use cvTranspose() or cv::transpose() because (as you rightly pointed out) it's more efficient. Again, I recommend upgrading to OpenCV2.0 since most of the cvXXX functions just convert IplImage* structures to Mat objects (no deep copies). If you stored the image in a Mat object, Mat.t() would return the transpose.

Any rotation:

You should use cvWarpAffine by defining the rotation matrix in the general framework of the transformation matrix. I would highly recommend upgrading to OpenCV2.0 which has several features as well as a Mat class which encapsulates matrices and images. With 2.0 you can use warpAffine to the above.

Jacob
Thanks! Are you sure that's not less efficient than simply transposing the pixel array? The thing is, I wasn't sure if OpenCV even internally represents the image as an array of pixels, i.e. something like a 32-bit int*, and if it did, how to get a pointer to that array.
Ben Herila
I'm sorry, I didn't read your question properly, I've updated my answer.
Jacob
+1  A: 

cvFlip (img, img, XorYaxe) - is the best way (in c/c++) to rotate an IplImage by 90 degrees.

Your Friend
A: 

Well I was looking for some details and didn't find any example. So I post here a transposeImage function which, I hope, will help others who are looking for a direct way to rotate 90° without loosing 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

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 had some explanation I would be interested.

Artem
The reason for your math is probably due to integer division. What you want to do is: float center_val = (float)image->width / 2.0f.
Ben Herila