Qt 结合 OpenCV 的 Mat 对象绘制矩形区域,拖到矩形区域可用于 ROI 区域的截取

《QT从基础到进阶·十五》用鼠标绘制矩形(QGraphicsView、QPainter、QGraphicsRectItem) 在GraphicsView类中创建矩形绘制对象,并初始化该对象用于绘制矩形。在GraphicsView类的鼠标事件中设置绘制矩形时鼠标按下,移动,释放操作。矩形长宽的拖动会在DrawROI类中实现,界面的缩放把DrawROI类中的功能放入GraphicsView中的滚轮事件中。以下是鼠标绘制矩形最全的一种用法,完整源码将会放在最后面。 阅读详情

TB_DrawRectangle 表示绘制矩形类,在 QLabel 上实现绘制功能;GRectangle 表示矩形参数类; Mat 为 OpenCV 的图像类。

在这里插入图片描述

// ui->framePicture 表示显示区域;
// qScrollArea 实现图像的放大缩小显示
QScrollArea* qScrollArea=new QScrollArea(ui->framePicture);
QHBoxLayout* layout=new QHBoxLayout(ui->framePicture);
layout->addWidget(qScrollArea);
//qLabelView 表示图像的显示容器
QLabel* qLabelView=new QLabel(qScrollArea);
qLabelView->setScaledContents(true);
qLabelView->setBackgroundRole(QPalette::Background);
qLabelView->setFrameStyle(QFrame::StyledPanel);
qLabelView->setFrameShadow(QFrame::Sunken);
qLabelView->setGeometry(0, 0, qScrollArea->width(), qScrollArea->height());
qScrollArea->setWidget(qLabelView);
//制矩形的参数类
GRectangle rect; 
//Opencv 的图像类
Mat image; 
//qDrawView 表示矩形绘制的对象
TB_DrawRectangle* qDrawView=new TB_DrawRectangle(qLabelView, &rect, &image);
qDrawView->setParent(qLabelView);
qDrawView->setWindowFlags(Qt::WindowStaysOnTopHint);
qDrawView->setAttribute(Qt::WA_TranslucentBackground,true);
qDrawView->setStyleSheet("background-color:transparent");

GRectangle 类对象

GRectangle 类对象表示矩形的参数,里面包含了 P0、P1、P2 三个点的坐标参数,拖到 P0 可实现整个矩形的移动;拖到 P1、P2 可实现矩形的长宽大小变化。

#define MOUSE_LENGTH_LEN 10
#define MOUSE_RADIU_LEN  5

// GRectangle 类对象
class GRectangle
{
public:
    GRectangle();
    ~GRectangle(){}
private:
    Point2f p0;
    Point2f p1;
    Point2f p2;
    void UpdataPoint2fApi();
public:
    void SetPosLimit(Size imageSize);
    void DragPointApi(QPointF point, Size imageSize, Size labelSize);
    void DrawApi(QPainter* painter, QColor color, Size imageSize, Size labelSize);
public:
    Point2f p1_;
    Point2f p2_;
};

// GRectangle 类对象初始化
GRectangle::GRectangle()
{
    p1_=Point2f(100, 100);
    p2_=Point2f(300, 300);
    p1=p1_;
    p2=p2_;
}

//更新点状态
void GRectangle::UpdataPoint2fApi()
{
    p0=Point2f((p1.x + p2.x)/2, (p1.y + p2.y)/2);
}

//设置限制
void GRectangle::SetPosLimit(Size imageSize)
{
    int w=imageSize.width;
    int h=imageSize.height;
    if(w==0 || h==0)
        return;
    p1.x = p1.x<0 ? 0 : (p1.x>=w ? w-1 : p1.x);
    p2.x = p2.x<0 ? 0 : (p2.x>=w ? w-1 : p2.x);
    p1.y = p1.y<0 ? 0 : (p1.y>=h ? h-1 : p1.y);
    p2.y = p2.y<0 ? 0 : (p2.y>=h ? h-1 : p2.y);
    if(p1.x==p2.x && p1.y==p2.y && (p1.x==0 || p1.x==w-1) && (p1.y==0 || p1.y==h-1))
    {
        p1=Point2f(w/2-10, h/2);
        p2=Point2f(w/2+10, h/2);
    }
}

//点距离
float cvPointDistance(Point2f p1, Point2f p2)
{
    return sqrt(pow(p2.x-p1.x, 2) + pow(p2.y-p1.y, 2));
}

// 拖动点位置, sX表示图像宽度/控件宽度, sY表示图像高度/控件高度
void GRectangle::DragPointApi(QPointF point, Size imageSize, Size labelSize)
{
    float sX=(float)imageSize.width/labelSize.width;
    float sY=(float)imageSize.height/labelSize.height;
    float sZ=(sX + sY)/2;
    Point2f p(point.x()*sX, point.y()*sY);
    vector<Point2f> sorts;
    sorts.push_back(p0);
    sorts.push_back(p1);
    sorts.push_back(p2);
    float length=10e9;
    int   index=-1;
    for(size_t i=0;i<sorts.size();i++)
    {
        float l=cvPointDistance(p, sorts[i]);
        if(l<=length)
        {
            length=l;
            index=(int)i;
        }
    }
    if(length<=(MOUSE_LENGTH_LEN*sZ))
    {
        switch(index)
        {
        //P0
        case 0:
        {
            int x=p.x-p0.x;
            int y=p.y-p0.y;
            p1=Point2f(p1.x + x, p1.y + y);
            p2=Point2f(p2.x + x, p2.y + y);
            break;
        }
        //P1
        case 1:
        {
            if(!(p.x<p2.x && p.y<p2.y))
                return;
            p1=Point2f(p.x, p.y);
            break;
        }
        //P2
        case 2:
        {
            if(!(p.x>p1.x && p.y>p1.y))
                return;
            p2=Point2f(p.x, p.y);
            break;
        }
        default:
            break;
        }
    }
    //限制位置尺寸大小
    this->SetPosLimit(imageSize);
}

//绘图
void GRectangle::DrawApi(QPainter* painter, QColor color, Size imageSize, Size labelSize)
{
    if(!(labelSize.width>0 && imageSize.width>0))
        return;
    float sX=(float)imageSize.width/labelSize.width;
    float sY=(float)imageSize.height/labelSize.height;
    //更新位置点
    this->UpdataPoint2fApi();
    //实际点装换为灰度点
    QPointF P0(p0.x/sX, p0.y/sY);
    QPointF P1(p1.x/sX, p1.y/sY);
    QPointF P2(p2.x/sX, p2.y/sY);
    //初始化绘图工具
    painter->setRenderHint(QPainter::Antialiasing, true);
    painter->setPen(color);
    QRectF rect1(P0.x()-MOUSE_RADIU_LEN, P0.y()-MOUSE_RADIU_LEN, 2*MOUSE_RADIU_LEN, 2*MOUSE_RADIU_LEN);
    painter->drawEllipse(rect1);
    QRectF rect2(P1.x()-MOUSE_RADIU_LEN, P1.y()-MOUSE_RADIU_LEN, 2*MOUSE_RADIU_LEN, 2*MOUSE_RADIU_LEN);
    painter->drawEllipse(rect2);
    QRectF rect3(P2.x()-MOUSE_RADIU_LEN, P2.y()-MOUSE_RADIU_LEN, 2*MOUSE_RADIU_LEN, 2*MOUSE_RADIU_LEN);
    painter->drawEllipse(rect3);
    QPoint l2=QPoint(P2.x(), P1.y());
    QPoint l4=QPoint(P1.x(), P2.y());
    painter->drawLine(P1, l2);
    painter->drawLine(l2, P2);
    painter->drawLine(P2, l4);
    painter->drawLine(l4, P1);
}

TB_DrawRectangle 类实现拖到、绘制等功能

class TB_DrawRectangle : public QWidget
{
    Q_OBJECT
public:
    explicit TB_DrawRectangle(QWidget *parent, GRectangle *rect, Mat *image);
    void mouseMoveEvent(QMouseEvent *e);
    void mouseReleaseEvent(QMouseEvent *e);
    void paintEvent(QPaintEvent *event);
    ~TB_DrawRectangle(){}
public:
    GRectangle* graphic;  
    Mat* imageSize;
    QColor color;
};

//初始化
TB_DrawRectangle::TB_DrawRectangle(QWidget *parent, GRectangle *rect, Mat *image) :
    QWidget(parent), graphic(rect), imageSize(image), color(Qt::red)
{}

//鼠标移动事件
void TB_DrawRectangle::mouseMoveEvent(QMouseEvent *e)
{
    if(!(e->buttons() & Qt::LeftButton))
        return;
    int x=e->x();
    int y=e->y();
    if(x<0 || y<0 || x>this->width() || y>this->height())
        return;
    if(!(graphic && imageSize))
        return;
    graphic->DragPointApi(QPointF(x, y), Size(imageSize->cols, imageSize->rows), Size(this->width(), this->height()));
}

//鼠标释放事件
void TB_DrawRectangle::mouseReleaseEvent(QMouseEvent *e)
{
    e->accept();
}

//鼠标绘制事件
void TB_DrawRectangle::paintEvent(QPaintEvent* event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    if(!(graphic && imageSize))
        return;
    graphic->DrawApi(&painter, color, Size(imageSize->cols, imageSize->rows), Size(this->width(), this->height()));
    this->update();
}
【OpenCV 笔记】鼠标消息绘制矩形+截取ROI小窗口 学习资源来自优快云大佬浅墨的著作《OpenCV3编程入门》 首先附上书籍中利用鼠标消息绘制矩形的C++代码: /*动态绘制矩形*/ #include "stdafx.h" #include &lt;opencv2\opencv.hpp&gt; using namespace cv; #define WINDOW_NAME "鼠标绘制矩形" void on_MouseHandle(int e... 阅读详情

相关推荐

基于opencv的感兴趣区域ROI的操作

本文章主要对感兴趣区域ROI的操作(对于ROI区域图像叠加)说明 在图像处理的领域,我们常常需要去设置自己感兴趣的区域(ROI,region of interest),来专注或者简化工作过程。也就是从图像中选择的一个图像区域,这个区域是图像分析所关注的重点。我们圈定这个区域,以便进行下一步的处理.而且,使用ROI指定想读入的目标,可以减少处理时间,增加精度,给图像处理带来不小的便利。

JiaFanChen的博客 7843

Qt绘图:选中区域

0.前言 选区操作是比较常见的需求,如截图、图表等。一般矩形选区居多,有的是四个边都可编辑,有的是横向可编辑。单个选区的操作逻辑也是比较简单的,之后会在此基础上增加更复杂的需求。 本文代码源码链接及实现效果如下: github 链接(SimpleSelection类):https://github.com/gongjianbo/EasyQPainter 1.实现细节 矩形区域可以用 QRect 来保存,先对这个类有个基本的认识: QRect有四个成员变量,分别对应左上角和右下角点坐标 x.

龚建波 4162

OpenCV模板匹配框架:多ROI支持与并行加速的工业视觉实践

模板匹配是计算机视觉中的一项基础技术,其核心原理是通过在目标图像中滑动搜索模板图像,计算相似度以定位目标。这项技术的价值在于能够实现快速、准确的物体识别与定位,广泛应用于工业自动化、机器人引导和质量检测等场景。在实际工程中,标准模板匹配函数往往难以应对复杂多变的工业环境,例如零件旋转、尺度变化以及背景干扰等问题。为此,开发者需要构建更高级的框架,通过引入多样化的ROI(感兴趣区域)定义、图像金字塔多尺度搜索以及并行计算加速等策略来提升匹配的鲁棒性和效率。本文探讨的框架正是基于OpenCV,通过集成旋转矩形、

380

Qt+OpenCV联合开发(十六)--图像几何形状绘制

一、坐标系 电脑屏幕的坐标系,原点(0,0)在左上角,越往下y越大,越往右x越大,最大值在屏幕右下角 二、函数原型 1、rectangle函数 作用:用来绘制一个矩形框的,通常用在图片的标记上 c++原型: 参数一:img 图像 参数二:Rect对象的rec,Rect()函数是画出图像中的矩形。Rect(x,y,width,height),x, y为左上角坐标,width, height则为长和宽 参数三:color 线条颜色 (RGB) 或亮度(灰度图像 ) 参数四:th

hml111666的博客 2378

基于Qt与OpenCV的掌纹特征提取系统:C++实现与工程实践

计算机视觉是人工智能领域的关键技术,其核心在于通过算法让计算机“看懂”图像。特征提取是计算机视觉的基础环节,它从图像中识别并定位关键信息点,如边缘、角点或纹理特征,这些特征是后续图像识别、匹配与分析的基础。在生物识别、安防监控、工业质检等应用场景中,高效、准确的特征提取技术具有重要价值。本文聚焦于一个具体的工程实践案例——手形掌纹特征提取系统,深入探讨了如何利用**OpenCV**强大的图像处理库和**Qt**成熟的跨平台GUI框架,在C++环境下构建一个完整的、可交互的桌面应用程序。文章详细解析了从图像预

weixin_34152820的博客 557

基于Qt/C++与OpenCV构建桌面贴片机控制软件框架

机器视觉与自动化控制是工业自动化领域的核心技术。其原理在于通过图像传感器获取环境信息,并利用算法进行处理与分析,进而驱动执行机构完成精确操作。这项技术的核心价值在于能够替代人眼进行高速、高精度的检测与定位,大幅提升生产效率和一致性。在电子制造、精密装配等应用场景中,机器视觉是实现自动化生产线的关键环节。本文聚焦于利用OpenCV实现视觉定位与角度检测,并结合Qt框架构建模块化控制软件,具体探讨了如何从零搭建一个用于半导体贴片机的“拾取-视觉校正-放置”核心闭环系统,涵盖了硬件抽象、路径优化等工程实践要点。

weixin_30321709的博客 402

Qt 结合 OpenCV 的 Mat 对象绘制旋转矩形 ROI 区域

TB_DrawRotateRect 表示绘制旋转矩形类,在 QLabel 上实现绘制功能。其中,拖到 p0 点能实现旋转矩形的移动;拖到 p1、p2 能实现旋转矩形大小和位置的变化;拖到 p3、p4 能实现旋转矩形长度大小的变化。

dede28的博客 1001

6. QT环境下使用OPenCV(利用鼠标实现图像的ROI区域选择)

如果需要在一张图像上绘制多个矩形框,那么就需要时刻保存上一帧绘制过的带有矩形框的图像,需要添加一个新的全局变量rectedImage,并更改回调函数中的内容,添加一层判断,当第一次绘制后,给rectedImage进行赋值,如果rectedImage为空时就在原始图像上绘制,如果不为空,就在rectedImage图像上绘制。因为要在图像上实现鼠标框选的动作,那么必然需要记录鼠标左键按下和松开时的坐标,而且当矩形框绘制到图像上之后需要不停的刷新窗口上的图像帧(后面文章会讲到),所以需要在。

山间点烟雨 1466

Learning OpenCV Day2-Mat在Qt中的显示以及像素格式

1.自定义一个QOpenGLWidget类 2.重写void paintEvent(QPaintEvent *event)方法 void Window::paintEvent(QPaintEvent *event) { QOpenGLWidget::paintEvent(event); QPainter painter; cv::Mat mat = cv::imrea...

T_T1528的博客 463

基于Qt与OpenCV的工业视觉检测系统:架构、实现与优化

计算机视觉作为人工智能的关键分支,其核心原理是让机器通过图像处理与分析来“感知”和理解世界。在工业自动化领域,这项技术的价值尤为凸显,它能替代人眼进行高精度、高重复性的在线质量检测,从而提升生产效率和产品一致性。OpenCV作为开源的计算机视觉库,提供了从图像采集、预处理到特征提取、模式识别等一系列基础算法,是实现工业视觉应用的强大工具。结合Qt这一成熟的跨平台C++ GUI框架,开发者可以构建出稳定、高效且用户友好的工业检测软件。本文聚焦于如何将Qt的界面开发能力与OpenCV的视觉算法库深度融合,详细阐

weixin_34055787的博客 346

VS2022+Qt5.15.2+OpenCV4.5.5图像处理开发工作流

图像处理是计算机视觉的入门基石,其核心在于算法实现与工程落地的结合。OpenCV提供成熟算法内核,Qt构建跨平台GUI交互界面,而VS2022则保障C++工程的稳定编译、高效调试与MSVC ABI一致性。三者协同的关键不在单点技术,而在版本兼容性、内存管理(如QImage与cv::Mat零拷贝转换)、信号槽与算法线程解耦等工程细节。该组合规避了Qt6 ABI断裂、OpenCV5 CMake重构及Python环境不可控等问题,特别适合课程设计、嵌入式原型验证与Windows可执行交付场景,真正解决‘算法跑通但

weixin_34185320的博客 341

(OpenCV — 7)ROI 区域图像叠加&图像混合

1 感兴趣区域: ROI 在图像处理领域,我们常常需要设置感兴趣区域 ( ROI. region of interest) ,来专注或者简化工作过程 。 也就是从图像中选择的一个图像区域,这个区域是图像分析所关注的重点 。 我们圈定这个区域,以便进行进一步处理 。 而且,使用 ROI指定想读入的目标,可以减少处理时间,增加精度,给图像处理来带不小的便利 。 定义 ROI 区域有两种方法 : ...

QtHalcon 943

Qt5实现的图片ROI区域的框选、移动、缩放

基于VS+Qt5实现的用于图片ROI区域框选,并可以对区域进行移动缩放删除保存操作。主要通过重写QLabel,代码仅供参考。 介绍链接:https://blog.youkuaiyun.com/qq_36131739/article/details/104855098

OpenCV联合C++/Qt 学习笔记(七)----图像中绘制基础图形、ROI区域截取及图像深拷贝与浅拷贝

本文介绍了OpenCV中常用的图像绘制和操作功能。基础图形绘制包括直线、圆形、椭圆、矩形、多边形和文字,各函数参数详细说明了坐标、颜色、线宽等属性。ROI区域截取可通过Range或Rect实现。图像拷贝分为深拷贝(copyTo创建独立副本)和浅拷贝(直接赋值共享内存)。示例代码演示了图形绘制、ROI操作及拷贝效果对比,展示了修改原图对浅拷贝图像的影响。这些功能为图像处理提供了基本的绘制和区域操作工具。

H001205的博客 62

QT实现ROI程序

QT实现的ROI,相信你看了很多图像库ROI的界面的功能,但总要用它的控件或类等,本程序完全脱离其他函数库。

基于 Python 的 LIF 模型:探索神经元同步与小世界网络

首先,我们定义了一个LIFNeuronself.soma.L = self.soma.diam = 12.6157 # 固定神经元形状self.cm = cm # 电容self.V_rest = V_rest # 静息电位self.V = V_rest # 初始化膜电位在初始化过程中,每个神经元被赋予初始的静息电位,并且其膜电位会在后续的模拟过程中动态变化。

qq_36224726的博客 1427

opencv 叠加文字_OpenCV学习(二)叠加图片,叠加文字

图片叠加是图像处理的基本操作。这个笔记是用来练习图像感兴趣区域ROI的。ROI(Region of Interest) 是指图像中的一个矩形区域,表明后续的程序需要单独处理这一个小区域。如果对图像设置了ROI,那么,Opencv的大多数函数只在该ROI区域内运算(只处理该ROI区域,效果有点儿类似于对其他部分锁定不得编辑),如果没设ROI的话,就会处理整幅图像。需要注意的时候,设置的ROI一定在图...

weixin_39787397的博客 861

中国高精度年度平均气温栅格数据集(1901-2024)

本文基于中国月度平均气温栅格数据集,计算生成1901-2024年1km分辨率的年度平均气温数据集,并按中国省市行政区划进行裁剪。该数据集融合CRU全球数据和WorldClim高分辨率数据,经496个站点验证,具有高时空精度和长时间序列特点,覆盖全国(含港澳台)逾百年气温记录,为气候变化研究、生态水文分析及农业生产评估等提供重要数据支撑。数据格式为Tif,单位为0.1℃,可获取全国、各省及各市三个尺度的气温栅格数据。

PPdata_Academy的博客 1244

长沙红胖子Qt·西安(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...

长沙红胖子 Qt・西安,本人拥有省级科研团队从业背景,研发团队产出所有项目、产品方案和研发无分包、无外包、无AI代笔,长期深耕双一流体系高精尖技术配套研发。博客主动剥离复杂底层工况机理,专注沉淀高端、特种行业领域Qt工程化落地实战经验。所有内容均为个人梳理总结的通用性工程方法论,只输出可公开的普适技术思路。

长沙红胖子 Qt・西安|省级科研团队从业背景,深耕双一流体系高精尖技术配套研发|剥离高精尖机理,沉淀高端特种行业领域 Qt 工程化落地经验|博文仅分享通用技术总结,输出公开普适工程思路。 164万+

stm32 + freertos + c++混合编程方法

其他一些资料上面,c++配置成--cpp11或者-cpp 都是把工程配置成c++。三、添加cpp文件,我们调用cpp文件里面的接口函数,不需要修改main.c后缀名。2、配置工程编译时候是--c99,是因为工程里面FreeRTOS是c语言,c++模式会报错。我们这里是默认c,编写的c++文件,单独选择--cpp编译,这在后面配置!c++是面向对象编程,对于一些项目来说,c++编程更加合适!stm32cubemax配置,这里就不写了,配置资料比较多。这里就是让cpp文件在c++下编译。最后,编程成功,点亮!

yuhu0012的博客 2629

基于CANopenNode协议栈在正点原子探索者开发板上进行移植

配置好之后进行采用keil IDE进行代码生成即可,还需要进行CANopenNode的代码集成,并参照demo进行代码移植。发送完成后心跳包以1s的周期重新开始发送。正点原子的开发板引出的是CAN1接口。这里的心跳时间间隔设置为100ms。则将心跳包周期设置为0。

wangfandashe的博客 4701

HOG+SVM行人检测实战:OpenCV与Qt完整实现

HOG(方向梯度直方图)是计算机视觉中经典的特征描述方法,通过统计图像局部区域的梯度方向分布来表征物体特征。结合SVM(支持向量机)分类器,HOG+SVM成为传统目标检测领域的标杆算法,在计算资源受限的场景仍具实用价值。本文以行人检测为切入点,详细讲解如何使用OpenCV3.4实现完整的HOG特征提取流程,包括关键参数winSize(64,128)、blockSize(16,16)的工程意义,以及如何通过数据增强提升SVM模型鲁棒性。针对实际部署需求,特别分享Qt可视化界面开发技巧与多线程优化方案,帮助开发

weixin_30855099的博客 327

帆软报表导出各种格式之后台导出

我们前面介绍了帆软报表在界面上的导出是通过类似的URL:http://localhost:8075/webroot/decision/view/report?op=export&sessionID=10653244-3e46-408c-bc54-f89a214a9bc7&format=image&extype=PNG 来完成的,就是带OP=export以及format参数来完成的。如果不从界面传参数,比如我们自己实现了一个HTTP接口,也可以通过传参数format来完成各种格式的导

帆软爱好者的专栏 4270
上一篇: c++ 双头链表结构,包括节点插入、删除、移动、查找等操作
下一篇: Qt 结合 Mat 对象绘制圆形区域,拖到圆形区域可用于 ROI 截取
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刚出道的菜鸟@丢丢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值