QT绘制区域(ROI)框(矩形框和椭圆框)
先上效果图
由于项目要涉及芯片检测的功能,需要选择特定区域,所以制作了个区域选择框,
核心代码1:DrawQWidget.h
#ifndef DRAWQWIDGET_H
#define DRAWQWIDGET_H#include <QWidget>
#include <QKeyEvent>
#include <qpoint.h>
#include <qpen.h>/***/
typedef enum draw_shap_e{DRAW_RECT, //画矩形DRAW_ELLIPSE, //画椭圆DRAW_NO //不画
}DRAW_SHAP_E;
/* 用来表示鼠标在矩形区域的位置信息**/
typedef enum rect_mouse_position_e{RECT_UPPER=0, //上边缘RECT_LOWER=1, //下边缘RECT_LEFT, //左边缘RECT_RIGHT, //右边缘RECT_LEFTUPPER, //左上角RECT_LEFTLOWER, //左下角RECT_RIGHTLOWER, //右下角RECT_RIGHTUPPER, //右上角RECT_INSIDE, //区域内部RECT_OUTSIDE //区域外部
}RECT_MOUSE_POSITION_E;/* 用来表示鼠标在椭圆区域的位置信息**/
typedef enum ellipse_mouse_position_e{ELLIPSE_UPPER=0, //上顶角ELLIPSE_LOWER=1, //下顶角ELLIPSE_LEFT, //左顶角ELLIPSE_RIGHT, //右顶角ELLIPSE_INSIDE, //区域内部ELLIPSE_OUTSIDE //区域外部
}ELLIPSE_MOUSE_POSITION_E;class DrawQWidget : public QWidget
{Q_OBJECT
public:explicit DrawQWidget(QWidget *parent = 0);~DrawQWidget();void set_draw_shap(DRAW_SHAP_E d);void set_picture_image(QString file_name);protected:void timerEvent(QTimerEvent*);void paintEvent(QPaintEvent*) override;void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);private:bool is_mouse_pressed;//是否按下鼠标DRAW_SHAP_E draw_shap;QPoint new_mouse_pos;QPoint old_mouse_pos;int m_difference_x;int m_difference_y;QPainter *painter; //用来绘制图像QPen frame_pen; //用来绘制区域边框QPen red_point_pen; //用来绘制红色点const int BoundaryRange = 6;//用来表示边界的宽度范围,用于拖拽/* 矩形区域相关变量和函数* 注意:QPoint的0点是左上角,横向向右为X的正方向,竖向向下为Y的正方向*/int rect_left; //表示矩形右上角的X坐标int rect_top; //表示矩形右上角的Y坐标int rect_width; //表示矩形的宽(即水平长度)int rect_height; //表示矩形的高(即垂直长度)int rect_top_left_x, rect_top_left_y; //左上int rect_top_right_x, rect_top_right_y; //右上int rect_low_left_x, rect_low_left_y; //左下int rect_low_right_x, rect_low_right_y; //右下QPolygon rect_polygon; //装载8个红点的坐标RECT_MOUSE_POSITION_E rect_mouse_pos;void rect_init_region();void rect_update_region();void rect_change_region();RECT_MOUSE_POSITION_E rect_get_mouse_pos(int pos_x, int pos_y);/* 椭圆区域相关变量和函数* 注意:drawEllipse(20,20,210,160);* 第1,2个参数表示圆/椭圆距屏幕左上角的像素数,第3,4个参数表示圆/椭圆的宽度和高度。* 更加确切地表述,这个圆或椭圆是在矩形中,这个矩形的左上角的顶点在坐标轴中的位置为(20,20),* 这个圆或椭圆的中心为这个矩形的中心*/int ellipse_left; //表示椭圆右上角的X坐标int ellipse_top; //表示椭圆右上角的Y坐标int ellipse_width; //表示椭圆的宽(即水平长度)int ellipse_height; //表示椭圆的高(即垂直长度)int ellipse_middle_x;int ellipse_middle_y;QPolygon ellipse_polygon; //装载4个红点的坐标ELLIPSE_MOUSE_POSITION_E ellipse_mouse_pos;void ellipse_init_region();void ellipse_update_region();void ellipse_change_region();ELLIPSE_MOUSE_POSITION_E ellipse_get_mouse_pos(int pos_x, int pos_y);/* other**/int timer_id;QImage picture_image;int picture_image_w;int picture_image_h;
public slots:
};
#endif // DRAWQWIDGET_H
核心代码2:DrawQWidget.cpp
#include "DrawQWidget.h"
#include <qdebug.h>
#include <qpainter.h>
DrawQWidget::DrawQWidget(QWidget *parent) : QWidget(parent)
{setAttribute(Qt::WA_StyledBackground);setStyleSheet("background-color: rgb(0, 0, 0);");grabKeyboard();setMouseTracking(true);m_difference_x = 0;m_difference_y = 0;draw_shap = DRAW_NO;painter = new QPainter(this);frame_pen = QPen(QColor(0,174,255),2);red_point_pen = QPen(QColor(255,0,0),4);is_mouse_pressed = false;timer_id = startTimer(20);rect_init_region();ellipse_init_region();/// 开启鼠标实时追踪setMouseTracking(true);}DrawQWidget::~DrawQWidget()
{killTimer(timer_id);
}/* Event function**/
void DrawQWidget::timerEvent(QTimerEvent *)
{this->update();
}
void DrawQWidget::paintEvent(QPaintEvent *)
{painter->begin(this);painter->drawImage(QRectF(0,0,width(),height()), picture_image);switch (draw_shap) {case (DRAW_RECT) :{painter->setPen(frame_pen);//绘制边框线painter->drawRect(QRect(rect_left, rect_top, rect_width, rect_height));painter->setPen(red_point_pen);//绘制八个点painter->drawPoints(rect_polygon);}break;case (DRAW_ELLIPSE) :{painter->setPen(frame_pen);//绘制边框线painter->drawEllipse(QRect(ellipse_left, ellipse_top, ellipse_width, ellipse_height));painter->setPen(red_point_pen);//绘制四个点painter->drawPoints(ellipse_polygon);}break;case (DRAW_NO) :break;}painter->end();
}void DrawQWidget::mousePressEvent(QMouseEvent *event)
{
// if (!is_start_draw) return;is_mouse_pressed = true;
}void DrawQWidget::mouseMoveEvent(QMouseEvent *event)
{
// if (!is_start_draw) return;new_mouse_pos = event->pos();if (is_mouse_pressed) {m_difference_x = new_mouse_pos.x() - old_mouse_pos.x();m_difference_y = new_mouse_pos.y() - old_mouse_pos.y();switch (draw_shap) {case (DRAW_RECT) :rect_change_region();break;case (DRAW_ELLIPSE) :ellipse_change_region();break;case (DRAW_NO) :break;}}else{switch (draw_shap) {case (DRAW_RECT) :rect_mouse_pos = rect_get_mouse_pos(new_mouse_pos.x(), new_mouse_pos.y());break;case (DRAW_ELLIPSE) :ellipse_mouse_pos = ellipse_get_mouse_pos(new_mouse_pos.x(), new_mouse_pos.y());break;case (DRAW_NO) :break;}}old_mouse_pos = new_mouse_pos;
}void DrawQWidget::mouseReleaseEvent(QMouseEvent *event)
{
// if (!is_start_draw) return;is_mouse_pressed = false;
}/* Rect function**/
void DrawQWidget::rect_init_region()
{rect_left = 100;rect_top = 200;rect_width = 101;rect_height = 101;rect_mouse_pos = RECT_OUTSIDE;rect_update_region();
}
void DrawQWidget::rect_update_region()
{rect_top_left_x = rect_left; rect_top_left_y = rect_top;rect_top_right_x = rect_left+rect_width; rect_top_right_y = rect_top;rect_low_left_x = rect_left; rect_low_left_y = rect_top+rect_height;rect_low_right_x = rect_left+rect_width; rect_low_right_y = rect_top+rect_height;int Middle_X = rect_left + (rect_width>>1);int Middle_Y = rect_top + (rect_height>>1);rect_polygon.clear();rect_polygon<<QPoint(Middle_X, rect_top) //上中<<QPoint(rect_top_right_x, Middle_Y) //右中<<QPoint(Middle_X, rect_low_left_y) //下中<<QPoint(rect_left, Middle_Y) //左中<<QPoint(rect_left, rect_top) //左上角<<QPoint(rect_top_right_x, rect_top) //右上角<<QPoint(rect_top_right_x, rect_low_left_y) //右下角<<QPoint(rect_left, rect_low_left_y); //左下角}void DrawQWidget::rect_change_region()
{switch (rect_mouse_pos) {case (RECT_UPPER): rect_top += m_difference_y; rect_height -= m_difference_y;break;//上边界case (RECT_LOWER): rect_height += m_difference_y;break; //下边界case (RECT_LEFT) : rect_left += m_difference_x; rect_width -= m_difference_x;break;//左边界case (RECT_RIGHT): rect_width += m_difference_x;break; //右边界case (RECT_LEFTUPPER) : {//左上角rect_top += m_difference_y; rect_height -= m_difference_y;rect_left += m_difference_x; rect_width -= m_difference_x;}break;case (RECT_LEFTLOWER) : {//左下角rect_height += m_difference_y;rect_left += m_difference_x; rect_width -= m_difference_x;}break;case (RECT_RIGHTLOWER) : {//右下角rect_height += m_difference_y;rect_width += m_difference_x;}break;case (RECT_RIGHTUPPER) : {//右上角rect_top += m_difference_y; rect_height -= m_difference_y;rect_width += m_difference_x;}break;case (RECT_INSIDE) : {//内部rect_top += m_difference_y;rect_left += m_difference_x;}break;case (RECT_OUTSIDE) : return;//外部}rect_update_region();
}RECT_MOUSE_POSITION_E DrawQWidget::rect_get_mouse_pos(int pos_x, int pos_y)
{if (pos_x < rect_top_left_x || pos_x > rect_top_right_x || pos_y < rect_top_left_y || pos_y > rect_low_left_y) {this->setCursor(QCursor(Qt::ArrowCursor));return RECT_OUTSIDE;}else if (pos_y <= rect_top_left_y+BoundaryRange){ //1:左上角 2:右上角 3:上边缘if (pos_x <= rect_top_left_x+BoundaryRange) {this->setCursor(QCursor(Qt::SizeFDiagCursor));return RECT_LEFTUPPER;}else if (pos_x >= rect_top_right_x-BoundaryRange){this->setCursor(QCursor(Qt::SizeBDiagCursor));return RECT_RIGHTUPPER;}else {this->setCursor(QCursor(Qt::SizeVerCursor)); return RECT_UPPER;}}else if (pos_y >= rect_low_left_y-BoundaryRange){ //1:左下角 2:右下角 3:下边缘if (pos_x <= rect_low_left_x+BoundaryRange) {this->setCursor(QCursor(Qt::SizeBDiagCursor));return RECT_LEFTLOWER;}else if (pos_x >= rect_low_right_x-BoundaryRange){this->setCursor(QCursor(Qt::SizeFDiagCursor));return RECT_RIGHTLOWER;}else {this->setCursor(QCursor(Qt::SizeVerCursor)); return RECT_LOWER;}}else if (pos_x <= rect_top_left_x+BoundaryRange) { //左边缘this->setCursor(QCursor(Qt::SizeHorCursor)); return RECT_LEFT;}else if (pos_x >= rect_top_right_x-BoundaryRange) { //右边缘this->setCursor(QCursor(Qt::SizeHorCursor)); return RECT_RIGHT;}else {this->setCursor(QCursor(Qt::SizeAllCursor));return RECT_INSIDE;}
}
/* Ellipse function**/
void DrawQWidget::ellipse_init_region()
{ellipse_left = 100;ellipse_top = 200;ellipse_width = 101;ellipse_height = 101;ellipse_mouse_pos = ELLIPSE_OUTSIDE;ellipse_update_region();
}void DrawQWidget::ellipse_update_region()
{ellipse_middle_x = ellipse_left + (ellipse_width>>1);ellipse_middle_y = ellipse_top + (ellipse_height>>1);ellipse_polygon.clear();ellipse_polygon<<QPoint(ellipse_middle_x, ellipse_top) //上顶角<<QPoint(ellipse_left+ellipse_width, ellipse_middle_y) //右顶角<<QPoint(ellipse_middle_x, ellipse_top+ellipse_height) //下顶角<<QPoint(ellipse_left, ellipse_middle_y); //左顶角
}void DrawQWidget::ellipse_change_region()
{switch (ellipse_mouse_pos) {case (ELLIPSE_UPPER) : ellipse_top += m_difference_y; ellipse_height -= m_difference_y;break;case (ELLIPSE_LOWER) : ellipse_height += m_difference_y;break;case (ELLIPSE_LEFT) : ellipse_left += m_difference_x; ellipse_width -= m_difference_x;break;case (ELLIPSE_RIGHT) : ellipse_width += m_difference_x;break;case (ELLIPSE_INSIDE) : ellipse_top += m_difference_y;ellipse_left += m_difference_x;break;case (ELLIPSE_OUTSIDE): return;}ellipse_update_region();
}ELLIPSE_MOUSE_POSITION_E DrawQWidget::ellipse_get_mouse_pos(int pos_x, int pos_y)
{if (pos_x < ellipse_left || pos_x > (ellipse_left+ellipse_width) || pos_y < ellipse_top || pos_y > (ellipse_top+ellipse_height)) {this->setCursor(QCursor(Qt::ArrowCursor));return ELLIPSE_OUTSIDE;}else if (pos_y <= ellipse_top+BoundaryRange){ //上顶角if (pos_x >= (ellipse_middle_x-3) && pos_x <= (ellipse_middle_x+3)){this->setCursor(QCursor(Qt::SizeVerCursor)); return ELLIPSE_UPPER;}else{this->setCursor(QCursor(Qt::SizeAllCursor)); return ELLIPSE_INSIDE;}}else if (pos_y >= ellipse_top+ellipse_height-BoundaryRange){ //下顶角if (pos_x >= (ellipse_middle_x-3) && pos_x <= (ellipse_middle_x+3)) {this->setCursor(QCursor(Qt::SizeVerCursor)); return ELLIPSE_LOWER;}else{this->setCursor(QCursor(Qt::SizeAllCursor)); return ELLIPSE_INSIDE;}}else if (pos_x <= ellipse_left+BoundaryRange) { //左顶角if (pos_y >= (ellipse_middle_y-3) && pos_y <= (ellipse_middle_y+3)) {this->setCursor(QCursor(Qt::SizeHorCursor)); return ELLIPSE_LEFT;}else{this->setCursor(QCursor(Qt::SizeAllCursor)); return ELLIPSE_INSIDE;}}else if (pos_x >= ellipse_left+ellipse_width-BoundaryRange) { //右顶角if (pos_y >= (ellipse_middle_y-3) && pos_y <= (ellipse_middle_y+3)) {this->setCursor(QCursor(Qt::SizeHorCursor)); return ELLIPSE_RIGHT;}else{this->setCursor(QCursor(Qt::SizeAllCursor)); return ELLIPSE_INSIDE;}}else {this->setCursor(QCursor(Qt::SizeAllCursor));return ELLIPSE_INSIDE;}
}/* other function**/
void DrawQWidget::set_draw_shap(DRAW_SHAP_E d)
{draw_shap = d;
}void DrawQWidget::set_picture_image(QString file_name)
{QImage image_tmp;image_tmp.load(file_name);if (!image_tmp.isNull()){picture_image = image_tmp;picture_image_w = image_tmp.width();picture_image_h = image_tmp.height();}
}
在QWidget上绘制区域框,可以放大缩小移动,可以是矩形,也可以是椭圆,注释非常完整。
完整项目源码:https://download.csdn.net/download/qq_40732350/12032761
没有积分的朋友可以到淘宝代理下载,只要一块钱(不限积分)
QT绘制区域(ROI)框(矩形框和椭圆框)相关推荐
- python半径为3圆形区域边界曲线_OpenCV 学习笔记03 边界框、最小矩形区域和最小闭圆的轮廓...
本节代码使用的opencv-python 4.0.1,numpy 1.15.4 + mkl 使用图片为 Mjolnir_Round_Car_Magnet_300x300.jpg 代码如下: impor ...
- QT-绘制ROI、矩形框、椭圆框,机器视觉
#ifndef DRAWQWIDGET_H #define DRAWQWIDGET_H#include <QWidget> #include <QKeyEvent> #incl ...
- 【OpenCV 】计算物体的凸包/创建包围轮廓的矩形和圆形边界框/createTrackbar添加滑动条/
目录 topic 1:模板匹配 topic 2:图像中寻找轮廓 topic 3:计算物体的凸包 topic 4:轮廓创建可倾斜的边界框和椭圆¶ topic 5:轮廓矩¶ topic 6:为程序界面添加 ...
- OpenCV之imgproc 模块. 图像处理(5)在图像中寻找轮廓 计算物体的凸包 创建包围轮廓的矩形和圆形边界框 为轮廓创建可倾斜的边界框和椭圆 轮廓矩 多边形测试
在图像中寻找轮廓 目标 在这个教程中你将学到如何: 使用OpenCV函数 findContours 使用OpenCV函数 drawContours 原理 例程 教程的代码在下面给出. 你也可以从 这里 ...
- R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(分组箱体框颜色自定义配置)实战
R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(分组箱体框颜色自定义配置)实战 目录 R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(分组箱体框 ...
- R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(分组箱体框颜色调色板配置)实战
R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(分组箱体框颜色调色板配置)实战 目录 R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(分组箱体框 ...
- R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(分组箱体框颜色配置)实战
R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(分组箱体框颜色配置)实战 目录 R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(分组箱体框颜色配 ...
- Qt绘制直线、矩形、圆
Qt绘制直线.矩形.圆 新建一个Qt Widgets Application工程 添加头文件 #include <QPainter> 添加paintEvent函数,代码如下: void M ...
- C# opencvSharp实现鼠标移动选择感兴趣区域(ROI)
C# opencvSharp实现鼠标移动选择感兴趣区域(ROI)主要通过鼠标响应事件来实现. 1.鼠标按下响应 MouseDown() 获取鼠标按下的开始坐标. private void pictur ...
最新文章
- ML基石_10_LogisticRegression
- App上架应用市场,如何攻破安全过检难题
- Net设计模式实例之桥接模式( Bridge Pattern)(2)
- SQL Server select语句执行顺序
- Intellij idea 14 创建简单的Web项目
- Linux权限管理 - 特殊权限之文件特殊权限
- HDU - 6602 Longest Subarray(线段树+思维)
- 福建学业水平测试计算机考点大纲,福建高中信息技术学业水平考试说明大纲
- python代码去马赛克_十行python代码教你如何去除万恶的,如s一样的马赛克
- 小程序入门学习13--云函数与数据库02
- ads出现村田电容电感无法仿真的问题解决(`BJT1' is an instance of an undefined model `BJTM1')...
- [转]innodb的锁时间
- WIN10系统下命令提示符(cmd)的基本操作
- CentOS安全运维检查命令
- css3实现建筑物的旋转,CSS3实现旋转光环效果的实现步骤
- 【BFS】lydsy3161 孤舟蓑笠翁
- QQ浏览器X5内核问题汇总
- PHP税前税后,请问下大家 怎么根据税后工资1万元推算出税前工资是多少
- python实现支付宝
- RF 电路设计中的常见问题及解决方案
热门文章
- 对python的认识作文500字_关于启示的作文500字
- 计算机开启时提示键盘错误,进入BIOS自检找不到键盘提示Keyboard error怎么办
- 百度ERNIE-Gram: Pre-Training with Explicitly N-Gram Masked Language Modeling
- Sheldon Numbers 暴力枚举
- Facebook SDK for iOS 2.4 iOS 6 上运行崩溃
- “量子XX”,是怎么被玩坏的?
- 认识Axure RP
- 大学一路走来总结(技术)
- 【GDOI 2016】第四题 疯狂动物城
- scrapy中使用讯代理动态转发