C++opencv图片旋转
时间: 2025-05-28 11:58:15 浏览: 17
<think>好的,用户想了解在C++中使用OpenCV进行图片旋转的方法或示例代码。我需要结合他们提供的四个引用内容,整理出两种主要的旋转方法:仿射变换和cv::rotate函数,并给出对应的代码示例。首先,引用[1]和[2]提到了使用warpAffine和getRotationMatrix2D来实现任意角度的旋转,这应该是仿射变换的方法。需要解释如何计算旋转矩阵,并应用仿射变换。用户可能需要注意旋转后的图像尺寸问题,是否需要调整输出尺寸,或者保持原图大小,但可能会有部分被裁剪。示例代码中的dsize参数设置为原图尺寸,这样可能导致图像被裁剪,或者可以计算新的尺寸来容纳整个旋转后的图像,可能需要额外说明。
然后,引用[3]和[4]提到了使用cv::rotate函数,但参数是枚举类型,只能旋转90度的倍数。这种方法适用于快速进行90、180、270度的旋转,不需要计算旋转矩阵,代码更简洁。需要指出两者的区别,比如仿射变换更灵活,而cv::rotate只能处理特定角度。接下来,需要确保代码示例正确。比如,在引用[1]中,center的坐标是否正确?应该是cols和rows的顺序,因为Point2f的参数是(x,y),而图像的x对应cols,y对应rows。所以center应该是(img.cols/2.0, img.rows/2.0),而不是rows在前。检查示例代码是否存在这个问题,需要修正,避免用户使用时出错。另外,引用[3]中的C++代码使用了cv::rotate,参数为1表示180度旋转,这与引用[4]中的flip函数不同,flip的参数0是上下翻转,1是左右翻转,-1是同时翻转,等效于180度旋转。但用户的问题是关于旋转,所以需要明确说明cv::rotate和flip的区别,避免混淆。用户可能需要了解两种方法的适用场景:任意角度旋转使用仿射变换,而90度倍数的旋转使用cv::rotate更高效。同时,注意在仿射变换中如何处理图像缩放和插值方法,比如scale参数调整图像大小,或者保持原尺寸导致裁剪。
最后,生成相关问题,例如如何调整旋转后的图像尺寸,如何处理不同旋转方法的性能差异,或者如何组合旋转与其他变换。确保问题与用户当前问题相关,帮助他们深入理解。</think>### C++ OpenCV 图像旋转方法详解
#### 一、基于仿射变换的任意角度旋转
使用$cv::warpAffine$函数实现任意角度旋转,需配合$cv::getRotationMatrix2D$生成旋转矩阵:
```cpp
#include <opencv2/opencv.hpp>
using namespace cv;
int main() {
Mat img = imread("lena.jpg");
if (img.empty()) return -1;
// 计算旋转中心(注意坐标顺序)
Point2f center(img.cols/2.0f, img.rows/2.0f);
double angle = 45; // 旋转角度
double scale = 1.0; // 缩放比例
// 生成旋转矩阵
Mat rotation_matrix = getRotationMatrix2D(center, angle, scale);
// 计算旋转后的图像边界
Rect2f bbox = RotatedRect(center, img.size(), angle).boundingRect2f();
// 调整旋转矩阵的平移分量
rotation_matrix.at<double>(0,2) += bbox.width/2.0 - center.x;
rotation_matrix.at<double>(1,2) += bbox.height/2.0 - center.y;
Mat rotated_img;
warpAffine(img, rotated_img, rotation_matrix, bbox.size());
imshow("Rotated", rotated_img);
waitKey(0);
return 0;
}
```
关键参数说明:
- `center`:旋转中心坐标,需注意$(x,y)$对应$(cols,rows)$[^1]
- `angle`:顺时针旋转角度(单位:度)
- `scale`:缩放因子,1.0表示保持原尺寸
- `bbox`:自动计算旋转后的图像尺寸,避免裁剪[^2]
#### 二、使用cv::rotate的90度倍数旋转
对于90°、180°、270°的快速旋转,可用$cv::rotate$函数:
```cpp
#include <opencv2/opencv.hpp>
using namespace cv;
int main() {
Mat img = imread("cat.jpg");
if (img.empty()) return -1;
Mat rotated;
// 旋转类型枚举参数:
// ROTATE_90_CLOCKWISE = 0, // 顺时针90°
// ROTATE_180 = 1, // 180°
// ROTATE_90_COUNTERCLOCKWISE = 2 // 逆时针90°
rotate(img, rotated, ROTATE_90_CLOCKWISE);
imshow("90° Rotation", rotated);
waitKey(0);
return 0;
}
```
该方法无需计算旋转矩阵,执行效率更高[^3]
#### 三、方法对比
| 方法 | 角度范围 | 性能 | 适用场景 |
|-----------------|---------------|--------|-------------------|
| warpAffine | 任意角度 | 较慢 | 精确角度调整 |
| rotate | 90°倍数 | 快速 | 快速方向调整 |
| flip+rotate组合 | 特殊角度组合 | 中等 | 复杂角度变换[^4] |
$$ \text{旋转矩阵计算公式:} M =
\begin{bmatrix}
\alpha & \beta & (1-\alpha) \cdot center.x - \beta \cdot center.y \\
-\beta & \alpha & \beta \cdot center.x + (1-\alpha) \cdot center.y
\end{bmatrix} $$
其中$\alpha = scale \cdot \cos\theta$, $\beta = scale \cdot \sin\theta$[^2]
阅读全文
相关推荐


















