You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在OpenCV 3中旋转cv::Rect提取的图像区域后复制?

解决思路:提取ROI → 旋转内容 → 复制到目标Mat

我懂你的需求啦——你是想把从原图像里提取的矩形区域先旋转,再复制到目标Mat中,之前尝试用cv::RotatedRect没达到预期效果对吧?其实RotatedRect主要是用来描述旋转后的矩形区域形状,不是直接帮你旋转图像内容的。下面给你一套完整的实现方案:

步骤拆解

  1. 从原图像中提取目标矩形区域(ROI)
  2. 对提取出的ROI进行旋转处理(保留完整内容,不裁剪)
  3. 将旋转后的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:35:22