如何在OpenCV 3中旋转cv::Rect提取的图像区域后复制?
解决思路:提取ROI → 旋转内容 → 复制到目标Mat
我懂你的需求啦——你是想把从原图像里提取的矩形区域先旋转,再复制到目标Mat中,之前尝试用cv::RotatedRect没达到预期效果对吧?其实RotatedRect主要是用来描述旋转后的矩形区域形状,不是直接帮你旋转图像内容的。下面给你一套完整的实现方案:
步骤拆解
- 从原图像中提取目标矩形区域(ROI)
- 对提取出的ROI进行旋转处理(保留完整内容,不裁剪)
- 将旋转后的ROI复制到目标Mat的指定位置(做边界检查避免越界)
完整代码示例
#include <opencv2/opencv.hpp> using namespace cv; int main() { // 读取原图像并初始化全黑的目标Mat Mat myimg = imread("gopro.png"); if (myimg.empty()) { printf("图像读取失败,请检查路径!"); return -1; } Mat draw = Mat(myimg.size(), myimg.type(), Scalar::all(0)); // 1. 定义原矩形区域并提取独立ROI(用clone避免和原图像共享内存) Rect r2 = Rect(417, 144, 153, 85); Mat roi = myimg(r2).clone(); // 2. 设置旋转参数:以ROI中心为旋转点,可自定义旋转角度 double rotate_angle = 90; // 示例为90度,你可以改成45、180等任意角度 Point2f roi_center(roi.cols / 2.0f, roi.rows / 2.0f); // 生成旋转矩阵 Mat rotation_mat = getRotationMatrix2D(roi_center, rotate_angle, 1.0); // 计算旋转后ROI的边界矩形,避免内容被裁剪 Rect rotated_bbox = RotatedRect(roi_center, roi.size(), rotate_angle).boundingRect(); // 调整旋转矩阵,让旋转后的图像在新Mat中居中 rotation_mat.at<double>(0, 2) += rotated_bbox.width / 2.0 - roi_center.x; rotation_mat.at<double>(1, 2) += rotated_bbox.height / 2.0 - roi_center.y; // 执行旋转操作 Mat rotated_roi; warpAffine(roi, rotated_roi, rotation_mat, rotated_bbox.size()); // 3. 将旋转后的ROI复制到目标Mat中(做边界检查防止越界) int target_x = r2.x; int target_y = r2.y; // 确保旋转后的ROI不会超出目标Mat的范围 if (target_x + rotated_roi.cols > draw.cols) target_x = draw.cols - rotated_roi.cols; if (target_y + rotated_roi.rows > draw.rows) target_y = draw.rows - rotated_roi.rows; target_x = max(target_x, 0); target_y = max(target_y, 0); Rect target_rect(target_x, target_y, rotated_roi.cols, rotated_roi.rows); rotated_roi.copyTo(draw(target_rect)); // 展示结果 imshow("Original ROI", roi); imshow("Rotated ROI", rotated_roi); imshow("Final Result", draw); waitKey(0); return 0; }
关键细节说明
- 为什么不用RotatedRect直接提取?
RotatedRect是用来定义一个倾斜的矩形区域,如果你直接用它从原图像提取区域,得到的是一个包含倾斜矩形的最小正矩形(空白处会填充黑边),但并没有旋转原矩形的内容——这和你想要的“先提取正矩形,再旋转内容”是两回事。 - 旋转时的边界处理
用RotatedRect::boundingRect()计算旋转后的实际尺寸,能确保旋转后的内容不会被裁剪;调整旋转矩阵的偏移量,是为了让旋转后的图像在新Mat里居中显示,不会出现偏移。 - 越界检查
旋转后的ROI尺寸可能比原矩形大,所以复制到目标Mat前要检查位置,避免超出图像范围导致程序报错。
内容的提问来源于stack exchange,提问作者Sara Ahsain
相关产品推荐
相关产品推荐

