基于QT实现显示OpenCV读取的图片

目录
  • 1. 概述
  • 2. 实现
    • 2.1 代码
    • 2.2 解析
  • 3. 结果

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. 结果

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

到此这篇关于基于QT实现显示OpenCV读取的图片的文章就介绍到这了,更多相关QT显示OpenCV读取图片内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • QT中在QLabel显示图片并且利用鼠标点击画线问题

    目录 在QLabel显示图片并且利用鼠标点击画线 以下为我的代码,供参考 在QLabel显示图片并且利用鼠标点击画线 最近在做在Label上显示图片并且通过鼠标点击画线,在网上查了很多零零散散的东西,收获也多 很多初学者更希望直接贴代码,这样可以模仿来写,我下面直接贴出我的项目中自己写的maLabel类 (如果只是实现利用鼠标绘制, 重写void paintEvent(QPaintEvent *event);void mousePressEvent(QMouseEvent *e); void m

  • OpenCV+Qt实现图像处理操作

    本文实例为大家分享了OpenCV+Qt实现图像处理操作的具体代码,供大家参考,具体内容如下 一.目标 Qt界面实现 雪花屏 高斯模糊 中值滤波 毛玻璃 灰度化 XY方向模糊 双边模糊 腐蚀 [图像处理操作] 要求左边原图,右边效果图 结果展示如下:[图像处理实现有点多,就不一个一个地展示了,各别展示如下] 雪花屏 毛玻璃 灰度化处理 二.使用Qt界面 使用到Qt中的UI设计界面 设计好界面之后最好先保存 对每一个按钮设计槽函数 三.图像处理操作完整代码 难点在于:Qt是QImage而OpenCV

  • OpenCV+Qt实现图像处理操作工具的示例代码

    目录 一.目标 二.使用Qt界面 三.图像处理操作完整代码 一.目标 Qt界面实现 雪花屏 高斯模糊 中值滤波 毛玻璃 灰度化 XY方向模糊 双边模糊 腐蚀 [图像处理操作] 要求左边原图,右边效果图 结果展示如下:[图像处理实现有点多,就不一个一个地展示了,各别展示如下] 雪花屏 毛玻璃 灰度化处理 二.使用Qt界面 使用到Qt中的UI设计界面 设计好界面之后最好先保存 对每一个按钮设计槽函数 三.图像处理操作完整代码 难点在于:Qt是QImage而OpenCV是Mat,需要Mat转QImag

  • QT+OpenCV实现录屏功能

    本文使用QT+opencv来实现对指定窗体画面录制,并保存为avi文件. (1)获取窗体界面 QScreen类有一个grabWindow函数,可以用来获取窗体的画面,这个函数使用很简单,就是传入窗体句柄和要截取的坐标.但是这个函数有一个缺陷,它是通过截取桌面画面的方式,而不是通过 窗体获取界面,所以当你的窗体被其他窗体遮挡时,就无法截取完整的窗体界面,如果你是要录制整个桌面画面,那用这个函数就可以了,下面的方法调用GDI函数来实现,即使窗体被遮挡时仍然能够获取到完整界面,但是窗体最小化时也一样无

  • OpenCV读取与写入图片的实现

    1.读取图片 cv2.imread(filename, flags) -filename: 文件名称 -flags: 0 读入灰度图片,1 读入彩色图片 cv2.imshow(winname, mat) -winname: 窗口名字 -mat: 要展示的图片矩阵 cv2.waitKey(0):暂停程序,这样才能显示图片 import cv2 img = cv2.imread("img.jpg", 1) cv2.imshow('img', img) cv2.waitKey(0) 2.图片

  • VS+Qt+Halcon 显示图片,实现鼠标缩放、移动图片

    目录 摘要 关键代码解释 1️.Qt函数与Halcon算子获取的文件路径字符串的区别 摘要 本篇博文记录一下,用VS+Qt+Halcon实现对图片的读取以及鼠标缩放,移动(鼠标事件调用了halcon自带的算子)的过程.以及遇到的坑.....

  • C++使用opencv读取图片的操作代码(图像处理)

    目录 代码理解 全部代码 读取结果 参考 代码理解 using namespace cv; 解释:加入此代码,后面就不需要在函数前加入cv:: 如从cv::imread(),可以直接写成imread() int main(int argc, char** argv) { return 0: } 解释: // argc是命令行,总的参数个数; argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数命令行后面跟的用户输入的参数 // char *argv[] 用来取得你所输入的参数 /

  • 基于Qt实现SVG图片浏览器

    目录 介绍 一.项目介绍 二.项目基本配置 三.UI界面设计 四.主程序实现 4.1 .pro文件 4.2 添加SvgWindow类 4.3 添加SvgWidget类 4.4 svgwidget.h头文件 4.5 svgwidget.cpp源文件 4.6 svgwindow.h头文件 4.7 svgwindow.cpp源文件 4.8 mainwindow.h头文件 4.9 mainwindow.cpp源文件 五.效果演示 介绍 SVG的英文全称是Scalable Vector Graphics,

  • python使用opencv读取图片的实例

    安装好环境后,开始了第一个Hello word 例子,如何读取图片,保存图品 import cv2 import numpy as np import matplotlib.pyplot as plt #读取图片代码 img = cv2.imread('test.jpg',cv2.IMREAD_GRAYSCALE) #IMREAD_COLOR = 1 #IMREAD_UNCHANGED = -1 #展示图片 cv2.imshow('image',img) cv2.waitKey(0) cv2.d

  • python opencv 读取图片 返回图片某像素点的b,g,r值的实现方法

    如下所示: #coding=utf-8 #读取图片 返回图片某像素点的b,g,r值 import cv2 import numpy as np img=cv2.imread('./o.jpg') px=img[10,10] print px blue=img[10,10,0] print blue green=img[10,10,1] print blue red=img[10,10,2] print blue 以上这篇python opencv 读取图片 返回图片某像素点的b,g,r值的实现方

  • Python OpenCV读取显示视频的方法示例

    目标 学习读取视频,显示视频和保存视频. 学习从相机捕捉并显示它. 你将学习以下功能:cv.VideoCapture(),cv.VideoWriter() 从相机中读取视频 通常情况下,我们必须用摄像机捕捉实时画面.提供了一个非常简单的界面.让我们从摄像头捕捉一段视频(我使用的是我笔记本电脑内置的网络摄像头) ,将其转换成灰度视频并显示出来.只是一个简单的任务开始. 要捕获视频,你需要创建一个 VideoCapture 对象.它的参数可以是设备索引或视频文件的名称.设备索引就是指定哪个摄像头的数

  • 基于Qt OpenCV的图像灰度化像素操作详解

    效果图 实现代码 #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include<opencv2/opencv.hpp> using namespace cv; QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *

  • 基于Qt OpenCV实现图像数据采集软件

    效果图 示例代码 #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include<QTimer> #include<QDebug> #include<QDateTime> #include<opencv2/opencv.hpp> using namespace cv; using namespace std; QT_BEGIN_NAMESPACE namespace Ui { class

  • 基于深度学习和OpenCV实现目标检测

    目录 使用深度学习和 OpenCV 进行目标检测 MobileNets:高效(深度)神经网络 使用 OpenCV 进行基于深度学习的对象检测 使用 OpenCV 检测视频 使用深度学习和 OpenCV 进行目标检测 基于深度学习的对象检测时,您可能会遇到三种主要的对象检测方法: Faster R-CNNs (Ren et al., 2015) You Only Look Once (YOLO) (Redmon et al., 2015) Single Shot Detectors (SSD)(L

随机推荐