将Opencv矩阵旋转90、180、270度[重复]
Posted
技术标签:
【中文标题】将Opencv矩阵旋转90、180、270度[重复]【英文标题】:Rotate Opencv Matrix by 90, 180, 270 degrees [duplicate] 【发布时间】:2013-02-09 04:34:43 【问题描述】:我正在从网络摄像头捕捉图像,我需要将其旋转直角。我发现自己有这些功能:
getRotationMatrix2D
- 创建旋转矩阵(不管它是什么)
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
只输出黑屏。
【问题讨论】:
这个问题是关于C++的,而另一个问题依赖于Java接口。一些答案使用 C++ 接口,但这不是将此问题标记为重复的充分理由。 【参考方案1】:上面的答案太复杂了,会占用你的 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 确实具有像人脸检测这样的原生功能(这并没有真正保持有问题的性能)。了不起。
干杯
【讨论】:
感谢您的提示,它对我的用例非常有帮助! 这应该是这个特定问题的公认答案 这就是我要找的。这是唯一专注于将图像旋转 90 度的倍数而不需要warpAffine
的答案。
@TimZaman:另外,我不确定这一点,但你可能需要小心你从同一个 Mat 读写的方法。有可能 opencv 在这里做了正确的事情,但它可能不会。
@tdp2110 就地很好。谢谢你的建议!更新了答案。【参考方案2】:
使用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
是最终图像
【讨论】:
这个答案是有效的并且非常适合任意旋转,但是,问题是 90 度(模数)旋转。即我猜你的仿射变换的计算量将是转置和翻转组合的数十倍。 (见下面我的回答)。 太糟糕了!仿射将插入并使用大量浮点运算。甚至要求的不是欧几里得刚性变换。翻转会更有效。 即使使用warpAffine
旋转 360 度也会使图像模糊。您可以添加flags=cv2.INTER_NEAREST
以在一定程度上减少模糊,但这仍然是一个明显的退化。【参考方案3】:
@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);
编辑: Another approach 将图像旋转 90,180 或 270 度涉及执行矩阵 transpose
然后 flip
。这种方法可能更快。
【讨论】:
与上面给出的明显简单的解决方案相比,这个答案太复杂了。编辑指的是一个使用简单解决方案但在循环中的链接,因此也比我上面已经给出的答案慢。【参考方案4】:上面的代码工作得很好,但是由于矩阵计算是在浮点和warpAffine插值中完成的,所以在图像中引入了数值误差。
对于 90 度增量旋转,我更喜欢使用以下(在 python/opencv python 中)
由于 Python 中的 OpenCV 图像是 2d Numpy 数组。
90 度。 theImage = numpy.rot90( theImage, 1 ) 270度 theImage = numpy.rot90( theImage, 3 )
注意:我只在形状 ( X, Y ) 的灰度图像上进行了测试。 如果您有彩色(或其他多分离)图像,您可能需要先对其进行整形,以确保旋转沿正确的轴进行。
【讨论】:
这不是正确的语言。以上是关于将Opencv矩阵旋转90、180、270度[重复]的主要内容,如果未能解决你的问题,请参考以下文章
Google Vision OCR,将文字坐标从 90、180、270 个文档中旋转到 0 度
通过transpose和flip实现图像旋转90/180/270度