当前位置: 首页 > article >正文

c++提取矩形区域图像的梯度并拟合直线

在这里插入图片描述
c++提取旋转矩形区域的边缘最强梯度点,并拟合直线

#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>

using namespace cv;
using namespace std;

int main() {
    // 加载图像
    Mat img = imread("image.jpg", IMREAD_GRAYSCALE);
    if (img.empty()) {
        cout << "Could not open or find the image!" << endl;
        return -1;
    }

    // 定义旋转矩形 (中心点, 大小, 旋转角度)
    Point2f center(img.cols / 2.0f, img.rows / 2.0f);
    Size2f size(200, 100); // 矩形大小
    float angle = 45;      // 旋转角度
    RotatedRect rotatedRect(center, size, angle);

    // 提取旋转矩形区域
    Mat rotatedRegion;
    Mat rotationMatrix = getRotationMatrix2D(center, angle, 1.0);
    warpAffine(img, rotatedRegion, rotationMatrix, img.size(), INTER_LINEAR, BORDER_CONSTANT, Scalar(0));
    Rect boundingRect = rotatedRect.boundingRect();
    Mat croppedRegion = rotatedRegion(boundingRect);

    // 计算梯度
    Mat gradX, gradY, gradMag, gradDir;
    Sobel(croppedRegion, gradX, CV_32F, 1, 0); // X方向梯度
    Sobel(croppedRegion, gradY, CV_32F, 0, 1); // Y方向梯度
    magnitude(gradX, gradY, gradMag);          // 梯度幅值
    phase(gradX, gradY, gradDir, true);        // 梯度方向

    // 找到最强梯度点
    double minVal, maxVal;
    Point minLoc, maxLoc;
    minMaxLoc(gradMag, &minVal, &maxVal, &minLoc, &maxLoc);

    // 提取梯度最强的点
    vector<Point2f> strongGradientPoints;
    float threshold = 0.8 * maxVal; // 设置阈值
    for (int y = 0; y < gradMag.rows; y++) {
        for (int x = 0; x < gradMag.cols; x++) {
            if (gradMag.at<float>(y, x) > threshold) {
                strongGradientPoints.push_back(Point2f(x + boundingRect.x, y + boundingRect.y));
            }
        }
    }

    // 拟合直线
    Vec4f lineParams;
    fitLine(strongGradientPoints, lineParams, DIST_L2, 0, 0.01, 0.01);

    // 计算直线的两个端点
    Point2f linePoint(lineParams[2], lineParams[3]);
    Point2f lineDirection(lineParams[0], lineParams[1]);
    Point2f pt1 = linePoint - lineDirection * 1000; // 延长线
    Point2f pt2 = linePoint + lineDirection * 1000;

    // 在原图上绘制旋转矩形和拟合的直线
    Mat imgDisplay;
    cvtColor(img, imgDisplay, COLOR_GRAY2BGR);
    Point2f vertices[4];
    rotatedRect.points(vertices);
    for (int i = 0; i < 4; i++) {
        line(imgDisplay, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0), 2);
    }
    line(imgDisplay, pt1, pt2, Scalar(0, 0, 255), 2);

    // 显示结果
    imshow("Rotated Region", croppedRegion);
    imshow("Gradient Magnitude", gradMag);
    imshow("Result", imgDisplay);
    waitKey(0);

    return 0;
}

效果演示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://www.kler.cn/a/531387.html

相关文章:

  • Leetcode—1427. 字符串的左右移【简单】Plus
  • AMD模块
  • js笔记(黑马程序员)
  • 基于最近邻数据进行分类
  • 海外问卷调查渠道查,如何影响企业的运营
  • 从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(OLED设备层封装)
  • fflush的概念和使用案例
  • 汽车自动驾驶AI
  • FPGA 时钟拓扑结构建议
  • X Window System 架构概述
  • CommonJS
  • python 中的堆
  • LeetCode-182. 查找重复的电子邮箱
  • 基础篇04-图像的灰度值变换
  • 一份完整系统化提升信息输出密度与逻辑严谨性的训练素材
  • Github 2025-02-03 开源项目周报 Top14
  • 【开发和生产环境配置】
  • 零碎的知识点(十二):“期望” 是什么?
  • 构建一个运维助手Agent:提升运维效率的实践
  • leetcode 2594. 修车的最少时间
  • FreeRTOS学习 --- 队列集
  • 深度解析近期爆火的 DeepSeek
  • Linux03——常见的操作命令
  • 计算机网络的组成,功能
  • 密码学的数学基础1-素数和RSA加密
  • PWN--格式化字符串