使用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. 结果
通过界面加载一张图像,显示结果如下:

使用QT显示OpenCV读取的图片的更多相关文章
- 对opencv读取的图片进行像素调整(1080, 1920) 1.cv2.VideoCapture(构造图片读取) 2.cv2.nameWindow(构建视频显示的窗口) 3.cv2.setWindowProperty(设置图片窗口的像素) 4.video_capture(对图片像素进行设置)
1. cv2.VideoCapture(0) #构建视频抓捕器 参数说明:0表示需要启动的摄像头,这里也可以写视频的路径 2. cv2.nameWindow(name, cv2.WINDOW_NORM ...
- Imagelab-0-QT label显示 opencv 图像
Imagelab-0-QT label显示 opencv 图像 opencvc++qtimagelab 开始之前 这其实也是opencv 处理图像的系列, 只是想我们在进一步复杂化我们的代码之前, 每 ...
- OpenCV【2】---读取png图片显示到QT label上的问题
问题一: 操作图片test.png是一个365x365的PNG图片 通过OpenCV自带的GUI显示出来图像是没问题的,例如以下操作代码所看到的: QStringfileName=QFileD ...
- python中用opencv读取并显示图片
一.读取并显示图片: import matplotlib.pyplot as plt # plt 用于显示图片 import matplotlib.image as mpimg # mpimg 用于读 ...
- 【QT】二进制读取图像文件并显示
打开对话框选择文件 二进制方式读取文件 转换成图像显示 void MainWindow::showImage() { //打开文件对话框 QString lastPath="D:/Engli ...
- [实例]ROS使用OpenCV读取图像并发布图像消息在rviz中显示
思路: (1)使用opencv读取本地图像 (2)调用cv_bridge::CvImage().toImageMsg()将本地图像发送给rviz显示 一.使用opencv读取本地图像并发布图像消息 ( ...
- 一个显示 OpenCV Mat 图像的自定义 Qt 控件
今天学习 Qt 的时候顺手写了一个,包含一个头文件 qcvdisplay.h 和一个源文件 qcvdisplay.cpp,因为这是 qt 默认的文件命名方式,在 Qt Designer 中提升控件时会 ...
- 吴裕雄--天生自然python学习笔记:python用OpenCV 读取和显示图形
Open CV 是一个开源.跨平台的计算机视觉库,它可 以在商业和研究领域中免费使用,目前已广泛应用于人机 互动.人脸识别.动作识别.运动跟踪等领域. 要识别特定的图像,最重要的是要有识别对象的特征 ...
- Opencv读取各种格式图片,在TBitmap上面重绘
//opencv读取图片 cv::Mat image; //const char *fileName = "HeadImage-UI/Photo-001.bmp"; const c ...
随机推荐
- c++ 文件的简单操作
文件的读取操作 在程序设计中,文件常用的操作不外乎--打开.读.写.流指针操作.关闭.我日常中使用的比较多,但从来 没有细细总结今天就总结下具体的用法. 相关概念 计算机上的文件其实是数据的集合,对文 ...
- MATLAB2017 下载及安装教程
全文借鉴于软件安装管家 链接: https://pan.baidu.com/s/1-X1Hg35bDG1G1AX4MnHxnA 提取码: ri88 复制这段内容后打开百度网盘手机App,操作更方便哦 ...
- c#数字图像处理(四)线性点运算
灰度图像的点运算可分为线性点运算和非线性点运算两种.4.1线性点运算定义线性点运算就是输出灰度级与输入灰度级呈线性关系的点运算.在这种情况下,灰度变换函数的形式为: g(x, y)=pf(x,y)+L ...
- 关于Python类的多继承中的__mro__属性使用的C3算法以及继承顺序解释
刚刚学到类的多继承这个环节,当子类继承多个父类时,调用的父类中的方法具体是哪一个我们无从得知,为此,在Python中有函数__mro__来表示方法解析顺序. 当前Python3.x的类多重继承算法用的 ...
- 04--Java--使用eclipse创建开发java项目步骤
eclipse创建开发java步骤 1.三种创建java项目 1)方式一:在包资源管理器(package explorer)窗口中鼠标右击任意位置选择New --> Java Project,如 ...
- SpringCloud与微服务Ⅹ --- SpringCloud Config分布式配置中心
一.SpringCloud Config是什么 分布式系统面临的问题 --- 配置问题 微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务.由于每个 ...
- Java Email 邮件发送
自己所编码的项目出现了问题,且是 24 小时运行于服务器上的. 如果出错了,那么我们也无从而知. 这个时候,只能通过异常捕获,然后将异常信息发送至开发者的邮箱上. 但是一个邮件的发送配置冗长,代码量至 ...
- 下载 安装MYsql 服务器
摘自 https://blog.csdn.net/youxianzide/article/details/85319106 https://www.2cto.com/database/201805/7 ...
- Linux 误删catlina.out导致磁盘空间爆满,无法查询到大文件解决办法
大概是前俩天吧,发现公司的网站不定时的出现接口调不通的情况,便让手下小弟去服务器上查看一下,小弟告我磁盘空间满了,于是我让他处理一下.结果没想到他直接把 catlina.out 给干掉了.后果可想而知 ...
- session、cookie、sessionStorage、localStorage的简要理解
一.cookie和session 首先 session 和 cookie 用于浏览器客户端与服务端数据交互,通过会话的方式跟踪浏览器用户身份. 1.cookie (1).一般由服务器生成,可以设置失效 ...