- PyQt5和Qt designer的详细安装教程:https://blog.csdn.net/qq_43811536/article/details/135185233?spm=1001.2014.3001.5501
- Qt designer界面和所有组件功能的详细介绍:https://blog.csdn.net/qq_43811536/article/details/135186862?spm=1001.2014.3001.5501
- Qt designer设计UI实例:双视图立体匹配与重建的可视化UI:https://blog.csdn.net/qq_43811536/article/details/135198820?spm=1001.2014.3001.5501
目录
- 1. 实例:双视图立体匹配与重建的可视化UI
- 2. 一个简单的UI展示
- 3. 基于PyQt5自定义UI功能
- 3.1 查询UI中组件的变量名
- 3.2 使用PyQt5对小组件自定义功能
1. 实例:双视图立体匹配与重建的可视化UI
- 输入:一对左右眼视图的图像。
- 任务:对输入的一对带相机参数的左右眼图像数据,实现SAD、NCC 两种局部的立体匹配方法进行重建。
- 输出:
- 基本的交互界面供用户选择立体匹配算法以及输入的图片。
- 将每种立体匹配方法所用的时间以及图片大小信息显示出来。
- 可视化重建的结果,如点云,深度图,视差图等,可以使用Meshlab 软件
或者Open3D 进行可视化
2. 一个简单的UI展示
针对上述实例要求,设计了一个简单的符合要求的UI如下图所示。界面包含图片选择(Picture)、匹配算法选择(Matching algorithm)、成本函数选择(Matching cost)、运行按钮(Run)、图片显示窗口(Picture visualization)、结果显示窗口(Results display)和输出信息窗口(Output information)。
3. 基于PyQt5自定义UI功能
3.1 查询UI中组件的变量名
首先,Qt designer设计的UI中的每一个组件对象都有一个变量名,即下图红框中的“对象”,例如Picture窗口中的图片选项栏对应的变量名就是comboBox
,右边的QComboBox
是我们在Qt designer界面和所有组件功能的详细介绍中介绍过的一个小组件的父类。默认的组件变量名如下图中所示,当然也可以自定义变量名方便后续编程。
3.2 使用PyQt5对小组件自定义功能
- 导入所需的所有包:
# 这里仅展示PyQt5相关包
from PyQt5.QtWidgets import *
from PyQt5 import uic, QtGui, QtWidgets, QtCore
- 定义UI的类:
class MyWindow(QWidget):def __init__(self):self.init_ui(self) # 初始化设计的界面def init_ui(self, self1):"""获取UI中需要自定义的组件的变量名"""
init_ui()
函数,注意变量名与Qt designer中对象一一对应:
def init_ui(self):self.ui = uic.loadUi("./Stereo_matching.ui", self1) # 加载 .ui 文件self.scenario_name = self.ui.comboBox.currentText() # 双视图self.matching_algorithm = self.ui.comboBox_5.currentText() # 匹配算法self.matching_cost = self.ui.comboBox_6.currentText() # 匹配costself.graphicsView = self.ui.graphicsView # 左右视图self.graphicsView_2 = self.ui.graphicsView_2 # 结果self.text = self.ui.textBrowser # 显示结果# 绘制当前选择的双视图self.ui.comboBox.currentIndexChanged.connect(self.draw_current_scenario)# 给RUN按钮绑定事件run_button = self.ui.pushButtonrun_button.clicked.connect(self.run)
- 根据运行逻辑,当我们选择一对双视图之后首先应该实时绘制出来,方便用户根据实际图片决定是否需要更换双视图的选择。所以我们需要定义一个信号与槽(Signals and Slots)函数,在小组件
comboBox
和graphicsView
之间建立交互,即上一段代码中的self.ui.comboBox.currentIndexChanged.connect(self.draw_current_scenario)
,这行代码的含义是一旦comboBox
中当前的索引改变(即当前选项改变),则执行self.draw_current_scenario()
函数。这里,我们将self.draw_current_scenario()
函数定义如下(注意形参为self的函数是UI类内函数,其他均为类外全局函数):
def draw_current_scenario(self):self.text.append("Drawing pictures...")# 获取当前的双视图self.scenario_name = self.ui.comboBox.currentText()# 读取左右视图left_image, right_image, groundtruth_image, mask_image = import_image(self.scenario_name)# 绘制左右视图、groundtruth、maskplot_image(self.scenario_name, left_image, right_image, groundtruth_image, mask_image)self.text.append("The picture's size: " + str(left_image.shape))self.text.append("Click RUN to start.\n")self.picture_visualization()def picture_visualization(self):pixmap = QtGui.QPixmap(f"./results/{self.scenario_name}_input.png")# 创建 QGraphicsScenescene = QtWidgets.QGraphicsScene(self)scene.addPixmap(pixmap)# 创建 QRectF 对象rect = QtCore.QRectF(pixmap.rect())scene.setSceneRect(rect)# 设置 QGraphicsViewself.graphicsView.setScene(scene)# 调整视图以适应场景的内容self.graphicsView.fitInView(scene.sceneRect(), QtCore.Qt.KeepAspectRatio)def import_image(scenario_name):"""读取左右视图"""
def plot_image(scenario_name, left_image, right_image, groundtruth_image, mask_image):"""绘制左右视图、groundtruth、mask等"""
- 在选择一对双视图之后,用户需要选择匹配算法和cost算法,最后点击RUN按钮运行。由于选择匹配算法和cost算法时界面不需要有其他功能体现,所以不需要做额外定义,主要RUN之前更新一下当前的双视图、匹配算法、匹配cost即可。点击RUN按钮运行同样需要定义一个信号与槽函数
run_button.clicked.connect(self.run)
:
def run(self):# 获取当前的双视图、匹配算法、匹配costself.scenario_name = self.ui.comboBox.currentText()self.matching_algorithm = self.ui.comboBox_5.currentText()self.matching_cost = self.ui.comboBox_6.currentText()# 调用main.py中的run_stereo_matching函数t1 = time.time()result_pic, acc = run_stereo_matching(self.scenario_name, self.matching_algorithm, self.matching_cost,)if result_pic is not None:# 显示结果self.result_display()t2 = time.time()self.text.append(f"Runtime: {t2 - t1:.3f}s")self.text.append(f"The result's size: {str(result_pic.shape)}")if acc is not None:self.text.append(f"Acc: {acc:.5f}\n")else:self.text.append("Warning! NCC is not applicable to this picture!\n")def run_stereo_matching(scenario_name, matching_algorithm_name, matching_cost_name):"""运行双视图立体匹配"""
- 最后,运行结果需要呈现在Display窗口,同时运行日志要在Output information窗口中输出。其中运行日志可以通过
self.text.append()
进行实时输出,运行结果绘制类似picture_visualization(self)
函数,定义如下:
def result_display(self):pixmap = QtGui.QPixmap(f"./results/{self.scenario_name}_{self.matching_algorithm}_{self.matching_cost}.png")# 创建 QGraphicsScenescene = QtWidgets.QGraphicsScene(self)scene.addPixmap(pixmap)# 创建 QRectF 对象rect = QtCore.QRectF(pixmap.rect())scene.setSceneRect(rect)# 设置 QGraphicsViewself.graphicsView_2.setScene(scene)# 调整视图以适应场景的内容self.graphicsView_2.fitInView(scene.sceneRect(), QtCore.Qt.KeepAspectRatio)
- 最最后,运行UI:
if __name__ == "__main__":app = QApplication(sys.argv)w = MyWindow()# display the windoww.ui.show()sys.exit(app.exec_())