C++ 将 Opencv 矩阵旋转 90、180、270 度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15043152/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rotate Opencv Matrix by 90, 180, 270 degrees
提问by TimZaman
I'm capturing image from webcam and I need to rotate it by right angle. I found myself theese functions:
我正在从网络摄像头捕获图像,我需要将其旋转成直角。我发现自己这些功能:
getRotationMatrix2D
- to create rotation matrix (whatever it is)transform
- transform one matrix to another by rotation matrix
getRotationMatrix2D
- 创建旋转矩阵(无论它是什么)transform
- 通过旋转矩阵将一个矩阵转换为另一个矩阵
But, I don't get anything but black area. This is my code:
但是,除了黑色区域,我什么也没有。这是我的代码:
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
}
Outputs just black screen.
只输出黑屏。
采纳答案by Abhishek Thakur
Use warpAffine.:
使用 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
dst
是最终图像
回答by TimZaman
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'.
上面的答案太复杂了,会占用你的 CPU。您的问题不是任意旋转,而是“将 Opencv 矩阵旋转 90、180、270 度”。
UPDATE 30 JUN 2017:
2017 年 6 月 30 日更新:
This functionality is supported by OpenCV, but not documented: https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core.hpp#L1041
OpenCV 支持此功能,但未记录: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:
您也可以通过使用翻转和转置操作来做到这一点,即对于 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 degreesWhile 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.
旋转任意度数虽然我正在做,这里是如何旋转任意度数,我预计它会贵 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,
}
Calling this for a rotation of 10.5 degrees then is obviously:
将其称为 10.5 度旋转显然是:
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.
我发现这些极其基本的功能不是 OpenCV 的一部分,这很了不起,而 OpenCV 确实有像人脸检测这样的原生功能(这并没有真正以可疑的性能维护)。卓越。
Cheers
干杯
回答by Alexey
@Abhishek Thakur's answer only works well for rotating the image by 180 degrees. It does not handle the rotation by 90 degrees because
@Abhishek Thakur 的答案仅适用于将图像旋转 180 度。它不处理旋转 90 度,因为
- the center of rotation supplied to
getRotationMatrix2D
is incorrect, and - output matrix size passed to
warpAffline
is incorrect.
- 提供给的旋转中心
getRotationMatrix2D
不正确,并且 - 传递给的输出矩阵大小
warpAffline
不正确。
Here's the code that rotates an image by 90 degrees:
这是将图像旋转 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);
Edit:Another approachto rotate images by 90,180 or 270 degrees involves doing matrix transpose
and then flip
. This method is probably faster.
编辑:另一种将图像旋转 90,180 或 270 度的方法涉及执行矩阵transpose
,然后flip
. 这种方法可能更快。
回答by Jeffrey Zampieron
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.
上面的代码工作得很好,但由于矩阵计算是在浮点和 warpAffine 插值中完成的,因此在图像中引入了数值误差。
For a 90deg increment rotation I prefer to use the following (in python/opencv python)
对于 90 度增量旋转,我更喜欢使用以下内容(在 python/opencv python 中)
Since OpenCV images in Python are 2d Numpy Arrays.
由于 Python 中的 OpenCV 图像是 2d Numpy 数组。
90 deg.
theImage = numpy.rot90( theImage, 1 )
270 deg.
theImage = numpy.rot90( theImage, 3 )
90 度
theImage = numpy.rot90( theImage, 1 )
270 度。
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.
注意:我仅在形状 ( X, Y ) 的灰度图像上进行了测试。如果您有彩色(或其他多分色)图像,您可能需要先对其进行整形,以确保旋转沿正确的轴进行。