使用QT鼠标事件mousePressEvent+opencv在ui上获取任意形状roi感兴趣区域c/c++


做毕设的时候老师要求选取任意的roi区域,决定用qt的鼠标事件存点同时用paintevent画出两点连线。并用opencv来在掩膜mask上画出边界再提取roi;**

实现效果如下:

主界面:点击open 选取照片(这个照片是吴龙备注一下hhhh)
使用QT鼠标事件mousePressEvent+opencv在ui上获取任意形状roi感兴趣区域c/c++
然后点击qt_mouse开始选点
使用QT鼠标事件mousePressEvent+opencv在ui上获取任意形状roi感兴趣区域c/c++
再点击右键选出roi:使用QT鼠标事件mousePressEvent+opencv在ui上获取任意形状roi感兴趣区域c/c++
使用QT鼠标事件mousePressEvent+opencv在ui上获取任意形状roi感兴趣区域c/c++
ok!!!

代码可能有点啰嗦贴下面了,有些和这个无关的我就删掉了

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QFileDialog>
#include<opencv2/opencv.hpp>
#include<opencv/highgui.h>
#include<vector>
#include<QtGui>
#include<QList>

using namespace cv;
using namespace std;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void roi_extract(Mat image);

private slots:
    void on_pushButton_open_clicked();
    void on_pushButton_qt_mouse_clicked();

protected:
    void mousePressEvent(QMouseEvent* event);

    void paintEvent(QPaintEvent *);



private:
    Ui::MainWindow *ui;

    QString file_name;
    Mat  capture_1,capture_2;
    QImage qimage_1;

    Mat mask_1;
    bool first_point = false, drawing = false ,draw_end = false;
    QList<int> xlist_1;
    QList<int> ylist_1;

};

#endif // MAINWINDOW_H

.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}
MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::mousePressEvent(QMouseEvent *event)
{

    if(event->button() == Qt::LeftButton)   //左键存坐标,右键结束
    {
        if(event->x() >= ui->label_photo->x() && event->x()<=ui->label_photo->x() + ui->label_photo->width() &&
                event->y() >= ui->label_photo->y() && event->y()<=ui->label_photo->y() + ui->label_photo->height() &&
                drawing == true)
        {
            qDebug()<< event->x() <<"  |  "<<event->y();
            ui->label_warning->setText("输入未超出边界");
            xlist_1.append(event->x());
            ylist_1.append(event->y());
            update();
        }else
        {
            ui->label_warning->setText("输入超出边界");
            qDebug()<<"输入超出边界";
        }
    }else if(event->button() == Qt::RightButton)
    {
        draw_end = true;
        drawing =false;
        update();
//        xlist_1.clear();
//        ylist_1.clear();  //不知道要不要清  暂时不清  以后可能设置个button来清
        roi_extract(capture_1);
    }
}

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPen pen;
    painter.drawPixmap(ui->label_photo->x(),ui->label_photo->y(),ui->label_photo->width(),ui->label_photo->height(),
                       QPixmap::fromImage(qimage_1));
//    painter.setViewport(ui->label_photo->x(),ui->label_photo->y(),ui->label_photo->width(),ui->label_photo->height());
    painter.setViewport(0,0,this->width(),this->height());
    pen.setStyle(Qt::SolidLine);
    pen.setWidthF(1);
    pen.setColor(Qt::red);
    painter.setPen(pen);

    if(drawing || draw_end)
    {
        for(int i = 0; i<ylist_1.count();i++)
        {
            if(i == 0)
                painter.drawPoint(QPointF(xlist_1[i], ylist_1[i]));
            else
                painter.drawLine(QPointF(xlist_1[i-1], ylist_1[i-1]), QPointF(xlist_1[i], ylist_1[i]));
        }
    }
    if(draw_end)
    {
        painter.drawLine(QPointF(xlist_1[0], ylist_1[0]),QPointF(xlist_1[ylist_1.count()-1], ylist_1[ylist_1.count()-1]));
//        xlist_1.clear();
//        ylist_1.clear();
    }
}

void MainWindow::roi_extract(Mat image)
{
    Mat roi_iamge;
    mask_1 = Mat::zeros(image.size(),CV_8UC1);
    vector<vector<Point>> contour;
    vector<Point> pts;
    for(int i = 0;i<ylist_1.count();i++)
    {
        pts.push_back(Point(xlist_1[i],ylist_1[i]));
    }
    contour.push_back(pts);
    drawContours(mask_1,contour,0,Scalar::all(255),-1);
    image.copyTo(roi_iamge,mask_1);
    imshow("mask_1",mask_1);
    imshow("roi_image",roi_iamge);
}

void MainWindow::on_pushButton_open_clicked()
{
    file_name = QFileDialog::getOpenFileName(this,tr("open  file"),".",tr("Video Files(*.bmp *.jpg *.pbm *.pgm *.png *.ppm *.xbm *.xpm)"));
    capture_1 = imread(file_name.toUtf8().data());
    cv::resize(capture_1,capture_1,cv::Size(ui->label_photo->width(),ui->label_photo->height()));
    sharpness = ImageSharpness_calculating(capture_1);
    this->ui->label->setText(QString::number(sharpness));


    //图片显示到label上
    cvtColor(capture_1,capture_2,CV_BGR2RGB);
    qimage_1 = QImage((const uchar*)capture_2.data,capture_2.cols,capture_2.rows,capture_2.step,QImage::Format_RGB888);
//    this->ui->label_photo->setPixmap(QPixmap::fromImage(qimage_1));
    update();
}

void MainWindow::on_pushButton_qt_mouse_clicked()
{
    this->drawing = true;
    draw_end = false;
}

参考:
[1]:https://blog.csdn.net/abc20002929/article/details/41016639
[2]: https://blog.csdn.net/qq_26787115/article/details/79988277
[3]:https://blog.csdn.net/sy95122/article/details/78687735
[4]: https://www.cnblogs.com/hwm520hlf1314/p/3477945.html