PyQt5实现将Matplotlib图像嵌入到Scoll Area中显示滚动条效果
作者:胜天半月子 发布时间:2021-12-21 05:40:39
标签:PyQt5,Matplotlib,图像嵌入,滚动条
前言
如题目所述,又是花费了两天的时间实现了该功能,本来今天下午有些心灰意冷,打算放弃嵌入到Scoll Area中的想法,但最后还是心里一紧,仔细梳理了一下逻辑,最终实现了功能
效果展示
注意:当你想实现一个子功能的时候,可以从新创建两个文件:
×××.ui文件(如上图效果展示是和我项目里的位置一样的)×××.py文件(用来实现功能)
截图
如上图所示,
红色框
里的文件是实现效果展示的所有源文件。但是文件夹testcode
是为了实现将Matplotlib图像嵌入到Scoll Area中所做的所有工作,稍后我会将参考资源
放入文章末尾
一、解决步骤
1.1 qt designer
设计ui文件,控件的位置需要和自己项目中控件的位置相同,以便功能实现后方便项目调用
保存为
testpiv.ui
文件
1.2 pycharm编写程序
直加看代码不懂得话,建议查看1.3中的参考文章,我实现该功能也是来源于这些
代码
import cv2
import os
import sys
import math
from PyQt5 import QtCore
from PyQt5.QtWidgets import *
from PyQt5.uic import loadUi
import matplotlib
from matplotlib import pyplot as plt
matplotlib.use("Qt5Agg") # 声明使用QT5
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
matplotlib.use("Qt5Agg") # 声明使用QT5
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
#创建一个matplotlib图形绘制类
class MyFigure(FigureCanvas):
def __init__(self,width, height, dpi):
# 创建一个Figure,该Figure为matplotlib下的Figure,不是matplotlib.pyplot下面的Figure
self.fig = plt.figure(figsize=(width, height), dpi=dpi)
# 在父类中激活Figure窗口,此句必不可少,否则不能显示图形
super(MyFigure,self).__init__(self.fig)
# 调用Figure下面的add_subplot方法,类似于matplotlib.pyplot下面的subplot(1,1,1)方法
class scollarea_showpic(QMainWindow):
def __init__(self, queryPath=None, samplePath=None,limit_value = None):
super().__init__()
self.queryPath = queryPath # 图库路径
self.samplePath = samplePath # 样本图片
self.limit_value = limit_value
self.ui()
plt.rcParams['font.sans-serif'] = ['KaiTi'] # 只有这样中文字体才可以显示
def ui(self):
loadUi('./testpiv.ui', self)
self.SIFT(self.queryPath,self.samplePath,self.limit_value)
def getMatchNum(self,matches,ratio):
'''返回特征点匹配数量和匹配掩码'''
matchesMask=[[0,0] for i in range(len(matches))]
matchNum=0
for i,(m,n) in enumerate(matches):
if m.distance < ratio * n.distance: #将距离比率小于ratio的匹配点删选出来
matchesMask[i]=[1,0]
matchNum+=1
return (matchNum,matchesMask)
def SIFT(self,dirpath,picpath,limit_value):
# path='F:/python/gradu_design/gra_des/'
queryPath=dirpath #图库路径
samplePath=picpath #样本图片
comparisonImageList=[] #记录比较结果
#创建SIFT特征提取器
sift = cv2.xfeatures2d.SIFT_create()
#创建FLANN匹配对象
"""
FLANN是类似最近邻的快速匹配库
它会根据数据本身选择最合适的算法来处理数据
比其他搜索算法快10倍
"""
FLANN_INDEX_KDTREE=0
indexParams=dict(algorithm=FLANN_INDEX_KDTREE,trees=5)
searchParams=dict(checks=50)
flann=cv2.FlannBasedMatcher(indexParams,searchParams)
sampleImage=cv2.imread(samplePath,0)
kp1, des1 = sift.detectAndCompute(sampleImage, None) #提取样本图片的特征
for parent,dirnames,filenames in os.walk(queryPath):
print('parent :',parent,' ','dirnames :',dirnames)
for p in filenames:
p=queryPath+p
# print('pic file name :',p)
queryImage=cv2.imread(p,0)
kp2, des2 = sift.detectAndCompute(queryImage, None) #提取比对图片的特征
matches=flann.knnMatch(des1,des2,k=2) #匹配特征点,为了删选匹配点,指定k为2,这样对样本图的每个特征点,返回两个匹配
(matchNum,matchesMask) = self.getMatchNum(matches,0.9) #通过比率条件,计算出匹配程度
matchRatio=matchNum*100/len(matches)
drawParams=dict(matchColor=(0,255,0),
singlePointColor=(255,0,0),
matchesMask=matchesMask,
flags=0)
comparisonImage=cv2.drawMatchesKnn(sampleImage,kp1,queryImage,kp2,matches,None,**drawParams)
comparisonImageList.append((comparisonImage,matchRatio)) #记录下结果
comparisonImageList.sort(key=lambda x:x[1],reverse=True) #按照匹配度排序 降序
new_comparisonImageList = comparisonImageList[:limit_value]
count=len(new_comparisonImageList)
column = 1 # 列
row = math.ceil(count/column) # 行 math.ceil: 函数返回大于或等于一个给定数字的最小整数
print('列:',column, ' ','行:',row)
#绘图显示
F = MyFigure(width=10, height=10, dpi=100) # 500 * 400
for index,(image,ratio) in enumerate(new_comparisonImageList):
F.axes = F.fig.add_subplot(row,column,index+1)
F.axes.set_title('Similiarity %.2f%%' % ratio)
plt.imshow(image)
# 调整subplot之间的间隙大小
plt.subplots_adjust(hspace=0.2)
self.figure = F.fig
# FigureCanvas:画布
self.canvas = FigureCanvas(self.figure) # fig 有 canvas
self.canvas.resize(self.picwidget.width(), 3000) # 画布大小
self.scrollArea = QScrollArea(self.picwidget) # picwidget上有scroll
self.scrollArea.setFixedSize(self.picwidget.width(), self.picwidget.height())
self.scrollArea.setWidget(self.canvas) # widget上有scroll scroll有canvas
self.nav = NavigationToolbar(self.canvas, self.picwidget) # 创建工具栏
self.setMinimumSize(self.width(), self.height())
self.setMaximumSize(self.width(), self.height())
self.setWindowTitle('Test')
if __name__ == "__main__":
app = QApplication(sys.argv)
queryPath='F:/python/gradu_design/gra_des/imges/' #图库路径
samplePath='F:/python/gradu_design/gra_des/imges/resized_logo1_1.jpg' #样本图片
main = scollarea_showpic(queryPath,samplePath,3)
main.show()
sys.exit(app.exec_())
下载地址
源码下载:test_scollarea.py
来源:https://blog.csdn.net/HG0724/article/details/116801099


猜你喜欢
- 由传智播客教程整理,我们这里使用的是python2.7.x版本,就是2.7之后的版本,因为python3的改动略大,我们这里不用它。现在我们
- 方法一、主要问题是docx受lxml的影响,如果lxml的版本不对的话,docx根本装不上,不管你用pip,easy_install或者是用
- enumerate函数用于遍历序列中的元素以及它们的下标。enumerate函数说明:函数原型:enumerate(sequence, [s
- 本来非常喜欢偷懒最好就是不干活那种所以最近在研究把Jenkins模块集成起来做成傻瓜界面这样就给他们用本人Python搓望大神不要喷,多多指
- 一. meta方法打包好的入口index.html头部加入<META HTTP-EQUIV="pragma" CO
- 本文实例讲述了Python常见数据结构之栈与队列用法。分享给大家供大家参考,具体如下:Python常见数据结构之-栈首先,栈是一种数据结构。
- 笔者在网上找了很多关于VSCODE配置Go语言的教程,但是由于版本等种种问题,最终都已失败告终。无奈只能在官方文档上寻求帮助,现在终于可以了
- 把今天的学习的opencv知识先记录一下!运行环境是:pycharm话不多说,献上代码再说:import cv2 # openc
- 导语:哈喽,在经历了过年相亲这一环节,成了是好事💗,不成也是多认识一个人,见见"世面",也可以“开拓”一下眼界,说不定遇
- 类的私有属性和方法Python是个开放的语言,默认情况下所有的属性和方法都是公开的 或者叫公有方法,不像C++和 Java中有明确的publ
- 最近一两年短视频业务风生水起,各个视频网站都有各自特色的短视频内容。如果有这样一个程序,可以把各大视频网站的热门用户最新发布的视频都下载下来
- 前言双端比较算法是vue2.x采用的diff算法,本篇文章只是对双端比较算法粗略的过程进行了一下分析,具体细节还是得Vue源码,Vue的源码
- 我们都知道tensorflow框架可以使用tensorboard这一高级的可视化的工具,为了使用tensorboard这一套完美的可视化工具
- global语句的作用在编写程序的时候,如果想为一个在函数外的变量重新赋值,并且这个变量会作用于许多函数中时,就需要告诉python这个变量
- 本文实例为大家分享了python实现五子棋游戏的具体代码,供大家参考,具体内容如下一、运行截图:二、代码# 用数组定义一个棋盘,棋盘大小为
- 如下所示:for line in file.readlines():line=line.strip('\n')来源:http
- 关于二分法的定义我就不说了,CSDN很多大牛和前辈都已经阐述的很清楚了,直接上代码。首先,先创建一个名称为 binary_search 的函
- 在目标检测的模型训练中, 我们通常都会有一个特征提取网络backbone, 例如YOLO使用的darknet SSD使用的VGG-16。为了
- 本文用python在TCP的基础上实现一个HTTP客户端, 该客户端能够复用TCP连接, 使用HTTP1.1协议. 一. 创建HT
- 上一篇博客写到用javascript生成多组文本,可以让数据的输入不受显示,现在我们需要把这些输入写入数据库,这里就用到json传入。 首先