PyQT:第一个Demo,画出鼠标单击位置出图像的列像素折线图

31 篇文章 0 订阅
18 篇文章 0 订阅

场景:有一系列图像,需要查看图像每列的像素值的大小,可以把图像读出来然后指定列,再查看,但比较麻烦,每看一列都要修改一下。后面又用回调函数滑动条,这样不用每次都修改列了,但假如换张图像的话还是要修改图像路径。所以就想做个界面,可以选择打开图像,并且鼠标单击一下图像中某点,就会画出这个点所在列(当然也可以是行)的一整列像素值的折线图。

最终的效果如下,还可以基本满足。

 代码如下:

from PyQt5.QtWidgets import QApplication, QMessageBox, QFileDialog, QGridLayout
from PyQt5.QtGui import QPainter, QPixmap
from PyQt5 import uic,QtWidgets
from PyQt5.QtCore import Qt, QPoint
from plot2 import Ui_MainWindow  # 这里的plot2是通过plot2.ui转成的plot2.py文件
import sys
import matplotlib
matplotlib.use("Qt5Agg")  # 声明使用QT5
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import numpy as np
import cv2

plt.rcParams['font.sans-serif']=['SimHei']  # 显示中文标签
plt.rcParams['axes.unicode_minus']=False

#创建一个matplotlib图形绘制类
class MyFigure(FigureCanvas):
    def __init__(self,width=5, height=4, dpi=600):
        #第一步:创建一个创建Figure
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        #第二步:在父类中激活Figure窗口
        super(MyFigure,self).__init__(self.fig) #此句必不可少,否则不能显示图形
        #第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
        self.axes = self.fig.add_subplot(111)

class MyWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MyWindow, self).__init__()
        self.setupUi(self)
        self.button_1.clicked.connect(self.open)
        # 第五步:定义MyFigure类的一个实例
        self.F = MyFigure(width=3, height=2, dpi=600)

    def plotcol(self, col, row):
        print(col)
        col = col - self.label_1.x()
        row = row - self.label_1.y()
        print(col)
        if(col >= 0 and col <= self.label_1.width() and row >= 0 and row <= self.label_1.height()):

            img_1 = cv2.imread(self.imgName, 0)
            img_1 = cv2.resize(img_1, (self.label_2.width(), self.label_2.height()), interpolation=cv2.INTER_AREA)
            cols_ = img_1[:, col]
            x = np.arange(0, self.label_2.height(), 1)

            self.F.axes.plot(x, cols_)

            self.F.fig.suptitle("列像素折线图")
            self.F.fig.savefig('tmp.jpg')
        self.label_2.setPixmap(QPixmap('tmp.jpg').scaled(self.label_2.width(), self.label_2.height()))
        self.F.axes.clear()

    def open(self):
        self.imgName, imgType = QFileDialog.getOpenFileName(self.label_1, "打开图片", "", "*.tiff;;*.jpg;;*.png;;All Files(*)")
        self.jpg = QPixmap(self.imgName).scaled(self.label_1.width(), self.label_1.height())
        # self.label.setPixmap(jpg)
        if (self.jpg.isNull() != True):
            self.label_1.setPixmap(self.jpg)

    def mousePressEvent (self, event):
        if event.button() == Qt.LeftButton:
            print(event.pos())
            self.plotcol(event.pos().x(), event.pos().y())

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    mywindow = MyWindow()
    mywindow.show()
    sys.exit(app.exec_())

 自己话好ui后,用工具自动转成py文件,只要ui中包含这三个组件,并且名字对应,就行。

 这里还遇到一些状况,就是开始的时候选择的窗体是Dialog和widget这两个都试过,但最后运行的界面总和预览的不一致,但是如果不加布局的话,是一致的。搞了很久都不行,最后换成了Main Window窗体,可以。

 还遇到一些其它问题:

(1)最开始的时候尝试使用的是加载动态ui,就是不转换为py文件,但是后面需要用到鼠标事件,没办法重写鼠标事件函数了

 将其转换为py后,就比较方便重写

 (2)另外一个问题就是怎么将plot画的图在label组件里显示,一定有方法,只是我还不知道,最后采用的方法比较笨,就是先把plot画的图保存为图片,然后label加载图片。后面再研究一下不这么笨的方法。

(3)还要对鼠标单击位置的坐标转换一下,转换为对应的图像中的坐标,并约束坐标只有在图像内部时画图。

 

 

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值