将opencv的imread()函数读取的图片用QLabel显示

news/2025/6/12 19:08:25

switchPicture.py

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import numpy as np
import cv2
import sysclass MyWidget(QWidget):def __init__(self, parent = None):super().__init__(parent)self.setWindowTitle(self.tr('显示图片'))self.resize(500,400)self.label = QLabel(self)self.label.setFrameShape(QFrame.Box)self.label.setAlignment(Qt.AlignCenter)img = cv2.imread('girl_1.jpg')#cv2.imshow('111',img)#cv2.waitKey(0)width = img.shape[1]height = img.shape[0]print('cv2, width: '+str(width)+' height: '+str(height))cv2.cvtColor(img, cv2.COLOR_BGR2RGB,img)qt_img = QImage(img.data,width,height,QImage.Format_RGB888)#print(type(qt_img))#self.label.setPixmap(QPixmap.fromImage(qt_img))
self.label.setGeometry(0, 0, 400, 300)n_width = qt_img.width()n_height = qt_img.height()print('Qt, width: '+str(n_width)+' height: '+str(n_height))if n_width / 400 >= n_height / 300:ratio = n_width / 400else:ratio = n_height / 300new_width = n_width / rationew_height = n_height / rationew_img = qt_img.scaled(new_width, new_height, Qt.KeepAspectRatio)self.label.setPixmap(QPixmap.fromImage(new_img))if __name__ == '__main__':app = QApplication(sys.argv)widget = MyWidget()widget.show()#print(widget.children())sys.exit(app.exec_())

 img是<class 'numpy.ndarray'>类型的,img.shape是一个包含三个元素的元祖,img.data是<class 'memoryview'>类型的。

numpy中是这样解释ndarray.data的:

data

Python buffer object pointing to the start of the array's data.

所以我们可以将ndarray.data理解为一个指向存储array数组数据的内存的指针。

 

再来看QImage的构造函数:

 1  |  QImage()
 2  |  QImage(QSize, QImage.Format)
 3  |  QImage(int, int, QImage.Format)
 4  |  QImage(bytes, int, int, QImage.Format)
 5  |  QImage(sip.voidptr, int, int, QImage.Format)
 6  |  QImage(bytes, int, int, int, QImage.Format)
 7  |  QImage(sip.voidptr, int, int, int, QImage.Format)
 8  |  QImage(List[str])
 9  |  QImage(str, format: str = None)
10  |  QImage(QImage)
11  |  QImage(Any)

我们在上面的程序中用到的是第5个构造函数,下面解释一下第5个构造函数的各个参数:

@sip.voidptr: 把它理解为一个地址,这个地址指向的内存,存储的是图片的所有像素点的值

@int:代表图像的宽度

@int:代表图像的高度

@QImage.Format:图像是BGR格式还是RGB格式,等等

 

在上面的程序中,我们用cv2.imread()读取的图片,将结果存在img中(img是一个np.ndarray数组),然后我们再将img.data传递给QImage的构造函数。

在这,我不禁有一个疑惑,将img.data传递给QImage,QImage是如何解析它并生成图片的呢?

以下是我的理解:

img.data指向的内存连续存储着的许多整形数字,这些数字每三个或几个为一组表示一个像素点,在内存中没有所谓的图片的行和列之分,那么QImage是如何区分出图片有多少行,有多少列呢?

QImage的构造函数中有两个int型变量,他们分别是图片的宽度和高度,QImage就是通过这两个数字来识别图片有多少行和多少列的。在最后的参数QImage.Format,它的作用就是让QImage知道

应该让几个数字一组表示一个像素点。

 

 

有时,我们使用第5个构造函数会出现图像扭曲的问题,这是我们应该用第7个构造函数QImage(sip.voidptr, int, int, int, QImage.Format),第三个int型参数表示的是每行有多少个字节

将上面程序中对应项改为下面的程序就可以了,我这里又增加了一个channel变量,用于计算每行有多少字节。

channel = img.shape[2]
qt_img = QImage(img1.data,width,height,width*channel,QImage.Format_RGB888)

出现扭曲的原因是QImage构造函数不知道图片一行有多少个像素点了。

下面是正常显示和扭曲的图片:

正常:

 

扭曲:

转载于:https://www.cnblogs.com/ACPIE-liusiqi/p/10610293.html


https://dhexx.cn/news/show-4341671.html

相关文章

Python学习之路--递归

递归 定义&#xff1a;在函数中调用自己 #RecursionError: maximum recursion depth exceeded while calling a Python object 递归错误&#xff0c;超过递归最大深度 最大递归深度997&#xff0c;或998&#xff0c;是python从内存角度出发做的限制 修改最大深度 import syssys…

量化交易 题解

这是一道贪心题目&#xff0c;有一个神奇的贪心策略&#xff1a;维护一个小根堆&#xff0c;最小的股票价格。 若当前第 i 天的股票价格大于堆顶&#xff0c;那么就将差价累加到答案里&#xff0c;并且弹出堆顶&#xff0c;插入两次第 i 天的股票价格。若小于堆顶&#xff0c;那…

excel 转换日期

早上一朋友问我excel中如何将类似这样“19850421”的文本日期转换为“1985-04-21”。我的第一反应就是直接设置单元格格式为日期&#xff0c;于是打开excel试了试结果显示“##############”悲剧了&#xff0c;于是想到函数&#xff0c;就在excel中给她组合了一条函数“CONCATE…

无向图的割点与割边

定义&#xff1a; 给定无向图G&#xff08;V&#xff0c;E&#xff09;&#xff1a; 若对于x∈V&#xff0c;从图中删去节点x以及所有与节点x相关联的边后&#xff0c;G分裂成两个或两个以上不相连的子图&#xff0c;则称x为G的割点。 若对于e∈E&#xff0c;从图中删去边e后&a…

〖美好生活〗一则用来长知识的科普小短文

惊蛰、春分过后&#xff0c;万物复苏&#xff0c;大地回春&#xff0c;即将迎来我们中国人较为重视的一个传统节日——清明节。关于清明节要去祭扫祖先这一传统&#xff0c;相信所有人都知道&#xff0c;但是关于这个节日的来历可能就鲜有人关心了。以下来自于小编搜罗来的野史…

database中不存在的数据的概率怎么求(smoothing)?

看了李宏毅老师的https://www.bilibili.com/video/av9770302/?p4课程&#xff0c;了解了一下 Matrix Factorization 具体可以参考下边的连接 https://blog.csdn.net/u014595019/article/details/80586438 脑洞大开&#xff0c;未知的图像分类能不能用同样的思路处理。 这里有一…

【转】关于Jmeter3.0,你必须要知道的5点变化

2016.5.18日&#xff0c;Apache 发布了jmeter 3.0版本&#xff0c;本人第一时间上去查看并下载使用了&#xff0c;然后群里或同事都会问有什么样变化呢&#xff1f;正好在网上看到一遍关于3.0的文章&#xff0c;但是是英文的。这里翻译一下&#xff0c;照顾英文不好的同学。 Jm…

ctop监控容器

简介ctop是一个实时的容器性能监控工具,效果和htop差不多.安装直接是二进制文件安装的 wget https://github.com/bcicen/ctop/releases/download/v0.7.2/ctop-0.7.2-linux-amd64 修改可执行权限 chmod x ctop-0.7.2-linux-amd64 移动到/usr/local/bin下 mv ctop-0.7.2-linux-am…

java后端技术栈路线图

很多人做Java开发2&#xff0c;3年后&#xff0c;都会感觉自己遇到瓶颈。什么都会又什么都不会&#xff0c;如何改变困境&#xff0c;为什么很多人写了7,8年还是一个码农&#xff0c;工作中太多被动是因为不懂底层原理。公司的工作节奏又比较快&#xff0c;难有机会学习架构原理…

leetcode 1078 Occurrences After Bigram

lc1078 Occurrences After Bigram trim().split()将原字符串转换成words数组 依次匹配first和second&#xff0c;若两者都能匹配上&#xff0c;则下一个单词为third&#xff0c;将其加入List<String> res 返回 res.toArray(new String[0]) 1 class Solution {2 publi…