使用QT显示OpenCV读取的图片

简介: 使用QT显示OpenCV读取的图片

使用QT显示OpenCV读取的图片

目录

1. 概述

OpenCV自带了一部分常用的GUI功能,但是更多的图像处理功能需要其他GUI框架来辅助实现,这里通过QT来显示OpenCV读取的图片。

2. 实现

在QtCreator中新建一个基于QMainWindow的应用:

其中QImageShowWidget就是用于显示图像的控件,它是继承于QWidget实现的,可以将其嵌入QMainWindow的centralwidget中:

QImageShowWidget是自定义的显示组件,可以首先在QtCreator的设计师界面拖入一个QWidget,再通过“窗口部件提升”功能提升为QImageShowWidget。

2.1. 代码

qimageshowwidget.h代码如下:

#ifndef QIMAGESHOWWIDGET_H
#define QIMAGESHOWWIDGET_H
#include <QWidget>
class QImageShowWidget : public QWidget
{
    Q_OBJECT
public:
    explicit QImageShowWidget(QWidget *parent = nullptr);
    ~QImageShowWidget();
    bool LoadImage(const char* imagePath);
signals:
public slots:
protected:
    void paintEvent(QPaintEvent *);     //绘制
    void Release();
private:
    uchar* winBuf;      //窗口填充buf
    int winWidth;      //窗口像素宽
    int winHeight;      //窗口像素高
    int winBandNum;      //波段数
};
#endif // QIMAGESHOWWIDGET_H

qimageshowwidget.cpp代码如下:

#include "qimageshowwidget.h"
#include <opencv2\opencv.hpp>
#include <QPainter>
#include <QDebug>
#include <iostream>
using namespace cv;
using namespace std;
QImageShowWidget::QImageShowWidget(QWidget *parent) : QWidget(parent)
{
    //填充背景色
    setAutoFillBackground(true);
    setBackgroundRole(QPalette::Base);
    winBuf = nullptr;
    winWidth = rect().width();
    winHeight = rect().height();
    winBandNum = 3;
}
QImageShowWidget::~QImageShowWidget()
{
    if(winBuf)
    {
        delete[] winBuf;
        winBuf = nullptr;
    }
}
bool QImageShowWidget::LoadImage(const char* imagePath)
{
    //从文件中读取成灰度图像
    Mat img = imread(imagePath);
    if (img.empty())
    {
        fprintf(stderr, "Can not load image %s\n", imagePath);
        return false;
    }
    Release();
    winWidth = rect().width();
    winHeight = rect().height();
    size_t winBufNum = (size_t) winWidth * winHeight * winBandNum;
    winBuf = new uchar[winBufNum];
    memset(winBuf, 255, winBufNum*sizeof(uchar));
    for (int ri = 0; ri < img.rows; ++ri)
    {
        for (int ci = 0; ci < img.cols; ++ci)
        {
            for(int bi = 0; bi < winBandNum; bi++)
            {
                size_t m = (size_t) winWidth * winBandNum * ri + winBandNum * ci + bi;
                size_t n = (size_t) img.cols * winBandNum * ri + winBandNum * ci + bi;
                winBuf[m] = img.data[n];
            }
        }
    }
    update();
    return true;
}
//重新实现paintEvent
void QImageShowWidget::paintEvent(QPaintEvent *)
{
    if(!winBuf)
    {
        return;
    }
    QImage::Format imgFomat = QImage::Format_RGB888;
    QPainter painter(this);
    QImage qImg(winBuf, winWidth, winHeight, winWidth*winBandNum, imgFomat);
    painter.drawPixmap(0, 0, QPixmap::fromImage(qImg));
}
void QImageShowWidget::Release()
{
    if(winBuf)
    {
        delete[] winBuf;
        winBuf = nullptr;
    }
}

2.2. 解析

所有基于QWidget的类都可以重新实现界面重绘事件paintEvent(),它会在界面需要的时候(例如调用update())自动重绘。在这个事件函数中可以通过图形绘制接口QPainter绘制:

QImage::Format imgFomat = QImage::Format_RGB888;
QPainter painter(this);
QImage qImg(winBuf, winWidth, winHeight, winWidth*winBandNum, imgFomat);
painter.drawPixmap(0, 0, QPixmap::fromImage(qImg));

可以看到QPainter绘制的其实是QImage对象,也就是重点是构造QImage这个对象。这个对象是由申请的内存winBuf来构建的。显示的图像是由宽、高以及波段组成的,需要将三维空间压缩为一维空间——简单来讲,内存的组成为RGBRGBRGB...,并且起点位置为左上角,由左至右,由上至下。

OpenCV读取的图像为Mat对象:

//从文件中读取成灰度图像
Mat img = imread(imagePath);
if (img.empty())
{
    fprintf(stderr, "Can not load image %s\n", imagePath);
    return false;
}

Mat对象可以通过data()方法直接访问读取的图像内存。而这块内存也是RGBRGBRGB...的结构组成,并且起点位置也是左上角,由左至右,由上至下。将其逐像素传入到申请的内存winBuf:

winWidth = rect().width();
winHeight = rect().height();
size_t winBufNum = (size_t) winWidth * winHeight * winBandNum;
winBuf = new uchar[winBufNum];
memset(winBuf, 255, winBufNum*sizeof(uchar));
for (int ri = 0; ri < img.rows; ++ri)
{
    for (int ci = 0; ci < img.cols; ++ci)
    {
        for(int bi = 0; bi < winBandNum; bi++)
        {
            size_t m = (size_t) winWidth * winBandNum * ri + winBandNum * ci + bi;
            size_t n = (size_t) img.cols * winBandNum * ri + winBandNum * ci + bi;
            winBuf[m] = img.data[n];
        }
    }
}

3. 结果

通过界面加载一张图像,显示结果如下:

分类: OpenCV , QT

标签: 图像显示 , QT , OpenCV


相关文章
|
4月前
|
计算机视觉
Opencv学习笔记(十二):图片腐蚀和膨胀操作
这篇文章介绍了图像腐蚀和膨胀的原理、作用以及使用OpenCV实现这些操作的代码示例,并深入解析了开运算和闭运算的概念及其在图像形态学处理中的应用。
243 1
Opencv学习笔记(十二):图片腐蚀和膨胀操作
|
5月前
|
算法 计算机视觉
基于qt的opencv实时图像处理框架FastCvLearn实战
本文介绍了一个基于Qt的OpenCV实时图像处理框架FastCvLearn,通过手撕代码的方式详细讲解了如何实现实时人脸马赛克等功能,并提供了结果展示和基础知识回顾。
207 7
|
4月前
|
计算机视觉 Python
Opencv学习笔记(二):如何将整个文件下的彩色图片全部转换为灰度图
使用OpenCV库将一个文件夹内的所有彩色图片批量转换为灰度图,并提供了相应的Python代码示例。
55 0
Opencv学习笔记(二):如何将整个文件下的彩色图片全部转换为灰度图
|
4月前
|
计算机视觉 Python
Opencv学习笔记(一):如何将得到的图片保存在指定目录以及如何将文件夹里所有图片以数组形式输出
这篇博客介绍了如何使用OpenCV库在Python中将图片保存到指定目录,以及如何将文件夹中的所有图片读取并以数组形式输出。
313 0
Opencv学习笔记(一):如何将得到的图片保存在指定目录以及如何将文件夹里所有图片以数组形式输出
|
5月前
|
文字识别 计算机视觉 开发者
基于QT的OCR和opencv融合框架FastOCRLearn实战
本文介绍了在Qt环境下结合OpenCV库构建OCR识别系统的实战方法,通过FastOCRLearn项目,读者可以学习Tesseract OCR的编译配置和在Windows平台下的实践步骤,文章提供了技术资源链接,帮助开发者理解并实现OCR技术。
252 9
基于QT的OCR和opencv融合框架FastOCRLearn实战
|
4月前
|
计算机视觉
Opencv错误笔记(一):通过cv2保存图片采用中文命名出现乱码
在使用OpenCV的cv2模块保存带有中文命名的图片时,直接使用cv2.imwrite()会导致乱码问题,可以通过改用cv2.imencode()方法来解决。
236 0
Opencv错误笔记(一):通过cv2保存图片采用中文命名出现乱码
|
6月前
|
计算机视觉 Windows Python
windows下使用python + opencv读取含有中文路径的图片 和 把图片数据保存到含有中文的路径下
在Windows系统中,直接使用`cv2.imread()`和`cv2.imwrite()`处理含中文路径的图像文件时会遇到问题。读取时会返回空数据,保存时则无法正确保存至目标目录。为解决这些问题,可以使用`cv2.imdecode()`结合`np.fromfile()`来读取图像,并使用`cv2.imencode()`结合`tofile()`方法来保存图像至含中文的路径。这种方法有效避免了路径编码问题,确保图像处理流程顺畅进行。
547 1
|
4月前
|
Serverless 计算机视觉
语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆
这篇文章介绍了如何使用OpenCV库通过mask图像绘制分割对象的外接椭圆。首先,需要加载mask图像,然后使用`cv2.findContours()`寻找轮廓,接着用`cv2.fitEllipse()`拟合外接椭圆,最后用`cv2.ellipse()`绘制椭圆。文章提供了详细的代码示例,展示了从读取图像到显示结果的完整过程。
91 0
语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆
|
5月前
|
计算机视觉
基于QT的opencv插件框架qtCvFrameLearn实战
这篇文章详细介绍了如何基于Qt框架开发一个名为qtCvFrameLearn的OpenCV插件,包括项目配置、插件加载、Qt与OpenCV图像转换,以及通过各个插件学习OpenCV函数的使用,如仿射变换、卡通效果、腐蚀、旋转和锐化等。
83 10
|
5月前
|
机器学习/深度学习 Java 计算机视觉
opencv4.5.5+qt5.15.2+vtk9.1+mingw81_64编译记录
本文记录了使用mingw81_64编译OpenCV 4.5.5、Qt 5.15.2、VTK 9.1的详细过程,包括编译结果截图、编译步骤、遇到的问题及其解决方案,以及相关参考链接。文中还提到了如何编译boost源码为静态库,并提供了测试代码示例。
159 0
opencv4.5.5+qt5.15.2+vtk9.1+mingw81_64编译记录

热门文章

最新文章