PyQt5實現將Matplotlib圖像嵌入到Scoll Area中顯示滾動條效果
前言
如題目所述,又是花費瞭兩天的時間實現瞭該功能,本來今天下午有些心灰意冷,打算放棄嵌入到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
總結
從目前我的認知來講,你想要實現的功能,基本上換一種思路、想法,都是可能會有解決方案的,隻不過可能難度不同,你需要投入的精力不同。
結合本篇博客來說,從我產生這個想法來說,我一直在找資料,從一開始的簡單搜索同一個內容到後面轉變搜索思路,到最後梳理邏輯框架、代碼,最後實現功能,此過程耗費的時間(兩天多)不算長,但也不算短。中間的過程是煎熬的,幾次試圖想放棄,最後還是挺瞭過來,還是很開心的。
隻要不放棄,你就可以!
以上就是PyQt5實現將Matplotlib圖像嵌入到Scoll Area中顯示滾動條效果的詳細內容,更多關於PyQt5 Matplotlib圖像嵌入的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- OpenCV-Python 實現兩張圖片自動拼接成全景圖
- Opencv Python實現兩幅圖像匹配
- Pyqt+matplotlib 實現實時畫圖案例
- matplotlib更改窗口圖標的方法示例
- Python圖像處理之圖像拼接