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

本文介绍了如何在Qt应用中利用QPixmap和OpenCV读取、显示并保存图片,包括从拖放操作读取图片、使用OpenCV进行图像处理以及将处理后的图像显示在界面上,最后通过imwrite函数将图片保存到本地。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本章主要学习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

运行:

 

OpenCV3Qt5计算机视觉应用开发》是一本介绍如何结合OpenCV3Qt5进行计算机视觉应用开发的书籍。本书共分为八,内容丰富而全面。 第一是对计算机视觉相关技术的概述,引导读者了解计算机视觉的基础知识,以及OpenCV3Qt5的基本概念使用方法。 第二到第五依次介绍了OpenCV3Qt5的基础知识使用方法。其中,在OpenCV3节中,读者能够学习到如何使用OpenCV3进行图像处理、特征提取、目标检测等计算机视觉任务。而在Qt5节中,读者将学习到如何使用Qt5进行图形界面设计,以及如何将OpenCV3Qt5进行桥接,实现计算机视觉应用的图形化界面。 第六介绍了如何在Qt5中导入OpenCV3库,并给出了一些在Qt中使用OpenCV进行图像处理的示例代码。读者可以通过这一的学习,了解如何在Qt中调用OpenCV函数,实现各种图像处理功能。 第七是一个完整的计算机视觉应用案例,案例中介绍了一个基于OpenCV3Qt5开发的人脸识别系统。通过阅读这一的内容,读者可以了解到如何运用OpenCV3Qt5构建一个实际的计算机视觉应用系统,并了解到其中的原理细节。 第八是有关Qt5的高级使用扩展。本内容较为高级,主要介绍了如何使用Qt5进行多线程编程、网络编程数据库操作等高级技术,并给出了一些示例代码。 总之,《OpenCV3Qt5计算机视觉应用开发》是一本非常实用的书籍,适合计算机视觉爱好者开发者阅读,通过学习本书,读者能够掌握使用OpenCV3Qt5进行计算机视觉应用开发的技巧方法。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值