QT-绘制ROI、矩形框、椭圆框,机器视觉

QT-绘制ROI、矩形框、椭圆框,机器视觉_第1张图片

 

#ifndef DRAWQWIDGET_H
#define DRAWQWIDGET_H
 
#include 
#include 
#include 
#include 
 
/*
 *
 */
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
#include "DrawQWidget.h"
#include 
#include 
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< 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< (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上绘制区域框,可以放大缩小移动,可以是矩形,也可以是椭圆,注释非常完整。

完整项目源码:CJOYdraw_qwidget.zip

没有积分的朋友可以到淘宝代理下载,只要一块钱(不限积分)

你可能感兴趣的:(QT)