40

我正在从网络摄像头捕捉图像,我需要将其旋转直角。我发现自己有这些功能:

  1. getRotationMatrix2D- 创建旋转矩阵(不管它是什么)
  2. transform- 通过旋转矩阵将一个矩阵转换为另一个矩阵

但是,除了黑色区域,我什么都没有。这是我的代码:

   if(rotate_button.click%4>0) {
       double angle = (rotate_button.click%4)*90;  //button increments its click by 1 per click
       Mat transform_m = getRotationMatrix2D(Point(cam_frame_width/2, cam_frame_height/2), angle, 1);  //Creating rotation matrix
       Mat current_frame;
       transform(cam_frame, current_frame, transform_m);  //Transforming captured image into a new one
       cam_frame = Mat((int)current_frame.cols,(int)current_frame.rows, cam_frame_type) = Scalar(0,128,0);  //resizing captured matrix, so I can copy the resized one on it
       current_frame.copyTo(cam_frame);  //Copy resized to original
   }

输出只是黑屏。

4

4 回答 4

137

上面的答案太复杂了,占用了你的 CPU。您的问题不是任意旋转,而是“将 Opencv 矩阵旋转 90、180、270 度”。

2017 年 6 月 30 日更新:

OpenCV 支持此功能,但未记录:https ://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core.hpp#L1041

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

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
};

原始答案和任意度数旋转:

您也可以通过使用翻转和转置操作来做到这一点,即对于 90CW:

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

等等。通过使用文档中的转置和翻转操作介绍自己,自己找出其他命令(思考=学习)。

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;
  }
}

所以你这样称呼它,并注意矩阵是通过引用传递的。

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

旋转任意度数 当我在这里时,这里是如何旋转任意度数,我预计它会贵 50 倍。请注意,以这种方式旋转将包括黑色填充,并且边缘将被旋转到超出图像的原始大小。

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, 
}

将其称为旋转 10.5 度显然是:

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

我发现这些极其基本的功能不是 OpenCV 的一部分,而 OpenCV 确实具有像人脸检测这样的原生功能(这并没有真正保持有问题的性能)。卓越。

干杯

于 2014-06-02T08:37:06.680 回答
32

使用 warpAffine。:

尝试:

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是最终图像

于 2013-02-23T17:18:25.253 回答
9

@Abhishek Thakur 的回答仅适用于将图像旋转 180 度。它不能处理 90 度的旋转,因为

  • 提供给的旋转中心getRotationMatrix2D不正确,并且
  • 传递给的输出矩阵大小warpAffline不正确。

这是将图像旋转 90 度的代码:

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);

编辑: 另一种将图像旋转 90,180 或 270 度的方法是先做矩阵transpose,然后flip. 这种方法可能更快。

于 2013-05-15T14:25:27.050 回答
0

上面的代码工作得很好,但是由于矩阵计算是在浮点和 warpAffine 插值中完成的,所以在图像中引入了数值误差。

对于 90 度增量旋转,我更喜欢使用以下(在 python/opencv python 中)

由于 Python 中的 OpenCV 图像是 2d Numpy 数组。

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

注意:我只在形状 ( X, Y ) 的灰度图像上对此进行了测试。如果您有彩色(或其他多分离)图像,您可能需要先对其进行整形,以确保旋转沿正确的轴进行。

于 2013-10-10T12:28:39.960 回答