《OpenCV3和Qt5计算机视觉应用开发》学习笔记第4章

本章主要学习OpenCV读取图片与QImage交互数据并显示在界面上。

1.Qt使用QPixmap显示图片

首先我们创建一个ImageViewer工程,在mainwindow.h文件中添加三个函数

protected:
    void dragEnterEvent(QDragEnterEvent *event);
    void dropEvent(QDropEvent *event);
    void resizeEvent(QResizeEvent *event);

函数实现

void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    QStringList acceptedFileTypes;
    acceptedFileTypes.append("jpg");
    acceptedFileTypes.append("png");
    acceptedFileTypes.append("bmp");
    if (event->mimeData()->hasUrls() && event->mimeData()->urls().count() == 1)
    {

        QFileInfo file(event->mimeData()->urls().at(0).toLocalFile());
        if(acceptedFileTypes.contains(file.suffix().toLower()))
        {
            event->acceptProposedAction();
        }
    }
}

void MainWindow::dropEvent(QDropEvent *event)
{
    QFileInfo file(event->mimeData()->urls().at(0).toLocalFile());

    QString filePath = file.absoluteFilePath();

    if(pixmap.load(filePath))
    {
        ui->label->setPixmap(pixmap.scaled(ui->label->size(),
                                           Qt::KeepAspectRatio,
                                           Qt::SmoothTransformation));
       
    }
    else
    {
        QMessageBox::critical(this,
                              tr("Error"),
                              tr("The image file cannot be read!"));
    }
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event);
    if(!pixmap.isNull())
    {
        ui->label->setPixmap(pixmap.scaled(ui->label->width()-5,
                                           ui->label->height()-5,
                                           Qt::KeepAspectRatio,
                                           Qt::SmoothTransformation));
    }
}

拖一张图片到界面上

这是直接使用QPixmap加载图片显示在QLabel,下面我们用OpenCV读取图片。


2.opencv读取图片转成QImage显示在QLable上。我们在主界面上再加一个QLabel。在dropEvent函数中添加以下代码

ui->label->setPixmap(pixmap.scaled(ui->label->size(),
                                           Qt::KeepAspectRatio,
                                           Qt::SmoothTransformation));
cv::Mat mat = cv::imread(filePath.toStdString());  //读文件
cvtColor(mat, mat, COLOR_BGR2RGB);
QImage image(mat.data, mat.cols, mat.rows, QImage::Format_RGB888);
QPixmap pix = QPixmap::fromImage(image);
ui->label_opencv->setPixmap(pix.scaled(ui->label_opencv->width(),
                                       ui->label_opencv->height(),
                                       Qt::KeepAspectRatio,
                                       Qt::SmoothTransformation));

运行结果:


3.opencv写入保存图片,上面是用opencv读取图片,这里我们再通过imwrite写图片保存到本地,在dropEvent添加一行代码即可

bool isWrite = cv::imwrite(saveFileName.toStdString(), mat);

完整的代码如下:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPixmap>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QDebug>
#include <QFileInfo>
#include <QMessageBox>
#include <QResizeEvent>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    void dragEnterEvent(QDragEnterEvent *event);
    void dropEvent(QDropEvent *event);
    void resizeEvent(QResizeEvent *event);

private:
    Ui::MainWindow *ui;
    QPixmap pixmap;
};

#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "opencv2/opencv.hpp"
#include <QImage>
#include <QDebug>

using namespace cv;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setAcceptDrops(true);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    QStringList acceptedFileTypes;
    acceptedFileTypes.append("jpg");
    acceptedFileTypes.append("png");
    acceptedFileTypes.append("bmp");

    if (event->mimeData()->hasUrls() && event->mimeData()->urls().count() == 1)
    {

        QFileInfo file(event->mimeData()->urls().at(0).toLocalFile());
        if(acceptedFileTypes.contains(file.suffix().toLower()))
        {
            event->acceptProposedAction();
        }
    }
}

void MainWindow::dropEvent(QDropEvent *event)
{
    QFileInfo file(event->mimeData()->urls().at(0).toLocalFile());
    QString filePath = file.absoluteFilePath();
    QString saveFileName = file.path() + "/aa." + file.suffix();

    if(pixmap.load(filePath))
    {
        ui->label->setPixmap(pixmap.scaled(ui->label->size(),
                                           Qt::KeepAspectRatio,
                                           Qt::SmoothTransformation));
        cv::Mat mat = cv::imread(filePath.toStdString());  //读文件
        cvtColor(mat, mat, COLOR_BGR2RGB);
        QImage image(mat.data, mat.cols, mat.rows, QImage::Format_RGB888);
        QPixmap pix = QPixmap::fromImage(image);
        ui->label_opencv->setPixmap(pix.scaled(ui->label_opencv->width(),
                                               ui->label_opencv->height(),
                                               Qt::KeepAspectRatio,
                                               Qt::SmoothTransformation));
        bool isWrite = cv::imwrite(saveFileName.toStdString(), mat);
        qDebug() << "dropEvent===================isWrite=====" << isWrite;
    }
    else
    {
        QMessageBox::critical(this,
                              tr("Error"),
                              tr("The image file cannot be read!"));
    }
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event);
    if(!pixmap.isNull())
    {
        ui->label->setPixmap(pixmap.scaled(ui->label->width()-5,
                                           ui->label->height()-5,
                                           Qt::KeepAspectRatio,
                                           Qt::SmoothTransformation));
    }
}

工程文件:


QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = ImageViewer
TEMPLATE = app

#win环境配置
win32:{
    CONFIG(debug, debug|release){
        DESTDIR += $$PWD/../bin/win64d
        LIBS += -L$$PWD/../lib/win64d -lopencv_world480d
    }else{
        DESTDIR += $$PWD/../bin/win64
        LIBS += -L$$PWD/../lib/win64 -lopencv_world480
    }
}

INCLUDEPATH += ../Include

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += \
        main.cpp \
        mainwindow.cpp

HEADERS += \
        mainwindow.h

FORMS += \
        mainwindow.ui

4.在Qt中创建自定义控件,并使用QPainter绘制它。

首先我们创建一个名为Painter_Test的项目,在MainWindow上添加一个QWidget部件。

然后创建一个QBlinkingWidget类,继随QWidget,编写void paintEvent(QPaintEvent *event)函数,添加一个定时器,触发槽函数,刷新界面。具体代码如下

#ifndef QBLINKINGWIDGET_H
#define QBLINKINGWIDGET_H

#include <QWidget>
#include <QPaintEvent>
#include <QPainter>
#include <QTimer>

class QBlinkingWidget : public QWidget
{
    Q_OBJECT
public:
    explicit QBlinkingWidget(QWidget *parent = nullptr);

protected:
    void paintEvent(QPaintEvent *event);

signals:

private slots:
    void onBlink();

private:
    QTimer blinkTimer;
    bool blink;

};

#endif // QBLINKINGWIDGET_H

#include "qblinkingwidget.h"

QBlinkingWidget::QBlinkingWidget(QWidget *parent) : QWidget(parent)
{
    blink  = false;
    connect(&blinkTimer, SIGNAL(timeout()), this, SLOT(onBlink()));
    blinkTimer.start(500);
}

void QBlinkingWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    if(blink)
        painter.fillRect(this->rect(), QBrush(Qt::red));
    else
        painter.fillRect(this->rect(), QBrush(Qt::white));
}

void QBlinkingWidget::onBlink()
{
    blink = !blink;
    this->update();
}

接着打开主界面UI文件,右键widget选择【提升为】选项,填写QBlinkingWidget类

添加成功后,类名变成QBlinkingWidget

运行:

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值