当前位置: 首页 > article >正文

Stable Diffusion+Pyqt5: 实现图像生成与管理界面(带保存 + 历史记录 + 删除功能)——我的实验记录(结尾附系统效果图)

目录

🧠 前言

🧾 我的需求

🔧 实现过程(按功能一步步来)

🚶‍♂️ Step 1:基本图像生成界面

🗃️ Step 2:保存图片并显示历史记录

📏 Step 3:优化长提示词显示和添加删除功能

🧹 Step 4:解决新生成图片删除失败

⚠️ 遇到的问题总结

✅ 最终效果展示

🧩 总结 & 收获


🧠 前言

本科课设做过一个人脸面部表情识别系统,当时是用Pyqt5库实现的图形可视化界面,最近我尝试结合 PyQt5 和 Stable Diffusion 模型开发一个图像生成工具,目标是实现一个带有图形界面的系统,能够输入提示词生成图像、自动保存并按序命名查看历史记录并支持删除功能。在开发过程中,我逐步实现了功能,也遇到了一些问题,最终在优化下达到了预期效果。本文将记录我的需求、实现过程、遇到的问题以及最终成果。
这一篇是在先前部署Stable Diffusion V1.5的基础上,加入了图形界面显示优化,部署可看从零搭建这篇,搭建完即可链接本篇:
深度学习项目记录·Stable Diffusion从零搭建、复现笔记-CSDN博客
从全灰到清晰图像:我的 Stable Diffusion 多尺度优化学习记录-CSDN博客
这里初始图像生成迭代步数我设置为30步,img2img优化迭代步数设置为50步



可能不好理解为什么实际运行生成图片过程中是15步?其实大概知道是微调受strength参数影响,50*0.3=15,这里我查了仔细解释,如下:
在 img2img(图像到图像)模式中,实际执行的迭代步数通常会受到 strength 参数的影响,而不是直接等于 num_inference_steps。
 

第一,strength 参数的作用

  • strength(这里是0.3)控制从初始图像 init_image 到生成新图像的“变化程度”。
  • 它的取值范围是0到1:
    • strength=0:完全保留初始图像,不做任何改变。
    • strength=1:完全忽略初始图像,等同于从头生成(text-to-image)。
    • strength=0.3:表示保留70%的初始图像特征,只对30%的内容进行调整。
       

第二,为什么是15步而不是50步?

  • 在 img2img 模式中,初始图像 init_image 已经提供了大部分结构,模型不需要从完全随机的噪声开始生成。因此,strength=0.3 表示只需要对图像进行轻微调整,实际迭代步数被缩减为 50 * 0.3 = 15。
  • 这是一个优化机制,避免浪费计算资源。
     

 第三,总结

  • 第一行(30/30):对应 pipe(prompt, ..., num_inference_steps=30),完整的30步生成。
  • 第二行(15/15):对应 img2img_pipe(..., num_inference_steps=50, strength=0.3),实际步数被 strength=0.3 缩减为15步。
  • 原因:img2img 模式的 strength 参数调整了实际迭代步数,以适配从已有图像开始的优化过程。

正文开始:

🧾 我的需求

  1. 生成逻辑

    • 输入提示词 → 点击生成 → 得到一张图像并保存,文件名按序递增(如 image_001.png, image_002.png)

    • 生成完成后暂停,等待下一次手动点击“开始生成”。

  2. 交互界面

    • 提供“清空提示词”按钮,方便输入新提示词。

    • 历史记录列表显示生成的图像,格式为:

      image_001.png  
      描述: A beautiful sunset
      
  3. 历史管理

    • 长提示词能完整显示,不被截断。

    • 每张图片支持删除功能,点击图片名称后可删除对应文件。


🔧 实现过程(按功能一步步来)


🚶‍♂️ Step 1:基本图像生成界面

目标:实现一个简单的 PyQt5 界面,能够输入提示词并生成图像,仅显示在界面上,不保存。

主要通过导入PyQt5库实现:

实现要点

  • 使用 StableDiffusionPipeline 和 StableDiffusionImg2ImgPipeline 生成图像。

  • 创建 PyQt5 界面,包含 QLineEdit(输入提示词)、QPushButton(开始生成)、QLabel(显示图像)

  • 将生成过程放入 QThread,通过信号机制 pyqtSignal将生成的图像传回主线程显示。(生成图像是个耗时操作,用 QThread 异步处理)

    用到的 Python 原理和技术

  • 多线程(QThread):避免生成图像时阻塞主界面,使用 pyqtSignal 传递结果。
  • GUI 布局(QVBoxLayout, QHBoxLayout):组织界面元素。
  • 图像处理(PIL 到 QPixmap):将生成的 PIL 图像转换为 PyQt5 可显示的格式。
class ImageGenerationThread(QThread):finished = pyqtSignal(object)def run(self):image = self.pipe(self.prompt).images[0]self.finished.emit(image)def generate_image(self):self.thread = ImageGenerationThread(prompt, save_path)self.thread.finished.connect(self.show_image)self.thread.start()def show_image(self, image):image.save("temp.png")pixmap = QPixmap("temp.png")self.image_label.setPixmap(pixmap)

🗃️ Step 2:保存图片并显示历史记录

目标:在生成图像后自动保存,并用列表显示图片名称和提示词,支持点击查看。

实现要点

  • 添加保存路径和文件名生成逻辑(image_001.png 等)。
  • 使用 QListWidget 显示历史记录,每张图片占两行:文件名和描述。
  • 实现点击列表项显示对应图像的功能。
     

    用到的 Python 原理和技术

  • 文件操作(os.path, os.makedirs):创建目录并保存图像。
  • 列表控件(QListWidget):存储和显示图片名及描述,使用 addItem 添加条目。
  • 字典(dict):用 self.history_data 存储文件名和提示词的映射,便于查看时获取描述。
  • 事件处理(itemClicked):绑定点击事件,加载并显示选中的图像。
def generate_image(self):filename = f"image_{self.count:03d}.png"save_path = os.path.join(self.save_dir, filename)self.thread = ImageGenerationThread(prompt, save_path)self.thread.finished.connect(self.on_generation_finished)def on_generation_finished(self, image, save_path, prompt):pixmap = QPixmap(save_path)self.image_label.setPixmap(pixmap)filename = os.path.basename(save_path)self.history_list.addItem(filename)self.history_list.addItem(f"描述: {prompt}")self.history_data[filename] = promptself.count += 1

📏 Step 3:优化长提示词显示和添加删除功能

目标:解决长提示词截断问题,并为每张图片添加删除按钮。

实现要点

  • 设置 QListWidget 宽度、开启自动换行;

  • 新增“删除图像”按钮,绑定删除逻辑;

  • 删除时移除对应列表项,弹确认框防误删。
     

    用到的 Python 原理和技术

  • 控件属性调整(setMaximumWidth, setWordWrap):增加宽度并启用自动换行。
  • 文件删除(os.remove):删除磁盘上的图片文件。
  • 列表操作(takeItem):从 QListWidget 中移除条目。
  • 对话框(QMessageBox):提供删除确认提示。
self.history_list.setMaximumWidth(400)
self.history_list.setWordWrap(True)def delete_selected_image(self):filename = self.history_list.selectedItems()[0].text()image_path = os.path.join(self.save_dir, filename)os.remove(image_path)row = self.history_list.row(selected_item)self.history_list.takeItem(row + 1)  # 描述self.history_list.takeItem(row)      # 文件名

🧹 Step 4:解决新生成图片删除失败

现象:已有图片可以删,但刚生成的删不了,会报错 [WinError 2]

原因:生成线程或图像显示时还占着这个文件的资源,没释放。

解决办法

  • 生成完成后手动释放图像对象;

  • 删除前清空当前显示的图像;

  • 加一波 gc.collect() 触发垃圾回收。
     

    用到的 Python 原理和技术

  • 垃圾回收(gc.collect):强制释放内存中的图像对象。
  • 资源管理(del, clear):显式删除图像对象并清除 QLabel 显示。
  • 异常处理(try-except):捕获删除时的错误并显示。
def on_generation_finished(self, image, save_path, prompt):# 显示图像 & 加入历史列表 ...del imagegc.collect()self.image_label.clear()def delete_selected_image(self):if self.image_label.pixmap():self.image_label.clear()os.remove(image_path)

⚠️ 遇到的问题总结

问题描述解决方法
❌ 无法保存图像最初没写保存逻辑手动加保存路径 + 文件名管理
❌ 提示词显示不完整长提示词在历史列表中只显示一行增加宽度 + 开启 setWordWrap(True)
❌ 新图片删不掉报错 [WinError 2] 文件被占用显式释放图像资源 + 清空 QLabel + 垃圾回收

最终效果展示

  1. 生成 + 保存

    • 输入提示词,点击“开始生成”,生成一张图像并保存(如 image_001.png),完成后暂停。
    • 清空提示词后输入新提示词,点击生成,保存为 image_002.png,文件名依次递增。
  2. 历史记录显示

    • 历史列表中,文件名和提示词分两行显示,长提示词自动换行,例如:

      image_001.png  
      描述: A beautiful sunset over the mountains with a long description that wraps
      image_002.png  
      描述: A cute kitten playing with a ball
      
  3. 删除功能完善

    • 选中历史中的图片文件名,点“删除”按钮,会弹窗确认;

    • 删除后界面实时刷新,文件从磁盘也会消失;删除后:

    • 新生成的图片也能正常删了!删除001.png

      下方显示已删除图像+图像名
      生成测试:This guy is wearing a short-sleeve T-shirt with pure color patterns. The T-shirt is with cotton fabric and its neckline is v-shape. The pants this guy wears is of long length. The pants are with cotton fabric and solid color patterns
      这位男士穿着一件纯色图案的短袖 T 恤。T恤为棉质面料,领口呈 V 形。这位男士穿着一条长裤。裤子为纯棉面料,纯色图案。
      效果一般,测试2:A little girl is sitting in front of a large painted rainbow .

      测试3:White dog playing with a red ball on the shore near the water .



      关闭系统界面,图像已保存到本地


🧩 总结 & 收获

这个小项目让我逐步实践了以下内容:

  • PyQt5 界面搭建;

  • 多线程 + 信号机制避免卡顿;

  • 图像处理、自动保存、文件管理;

  • 资源释放与垃圾回收(真香);

  • 控件交互与用户体验优化。

最关键的是,从一开始的功能设想到实际落地、再到解决 bug 完善体验,完整走了一遍闭环,非常适合练手或当项目展示。


如果你也想做个图像生成小工具类似系统,可以直接参考我这套逻辑(Pyqt5+生成模型)。

相关文章:

Stable Diffusion+Pyqt5: 实现图像生成与管理界面(带保存 + 历史记录 + 删除功能)——我的实验记录(结尾附系统效果图)

目录 🧠 前言 🧾 我的需求 🔧 实现过程(按功能一步步来) 🚶‍♂️ Step 1:基本图像生成界面 🗃️ Step 2:保存图片并显示历史记录 📏 Step 3&#xff1a…...

使用WasmEdge将InternLM集成到Obsidian,打造本地智能笔记助手

本文来自社区投稿,作者Miley Fu,WasmEdge Runtime 创始成员。 本文将介绍如何通过 WasmEdge 将书生浦语(InternLM)大模型部署在本地,并与 Obsidian 笔记软件集成,从而在笔记软件中直接利用大模型实现文本总…...

深入理解Softmax函数及其在PyTorch中的实现

Softmax函数简介 Softmax函数在机器学习和深度学习中,被广泛用于多分类问题的输出层。它将一个实数向量转换为概率分布,使得每个元素介于0和1之间,且所有元素之和为1。 Softmax函数的定义 给定一个长度为 K K K的输入向量 z [ z 1 , z 2 …...

JGraphT 在 Spring Boot 中的应用实践

1. 引言 1.1 什么是 JGraphT JGraphT 是一个用于处理图数据结构和算法的 Java 库,提供了丰富的图类型和算法实现。 1.2 为什么使用 JGraphT 丰富的图类型:支持简单图、多重图、伪图等多种图类型。强大的算法库:提供最短路径、最小生成树、拓扑排序等多种算法。易于集成:…...

java导入excel更新设备经纬度度数或者度分秒

文章目录 一、背景介绍二、页面效果三、代码0.pom.xml1.ImportDevice.vue2.ImportDeviceError.vue3.system.js4.DeviceManageControl5.DeviceManageUserControl6.Repeater7.FileUtils8.ResponseModel9.EnumLongitudeLatitude10.词条 四、注意点本人其他相关文章链接 一、背景介…...

视频设备轨迹回放平台EasyCVR远程监控体系落地筑牢国土监管防线

一、背景概述 我国土地资源遭违法滥用的现象愈发严峻,各类土地不合理利用问题频发。不当的土地开发不仅加剧了地质危害风险,导致良田受损、森林资源的滥伐,还引发了煤矿无序开采、城市开发区违建等乱象,给国家宝贵的土地资源造成…...

tree-sitter 的 grammar.js 编写方法

tree-sitter 的 grammar.js 编写方法 一、grammar.js 的作用是什么?二、基本结构三、关键词解释四、编写小技巧1. 起点是 source_file2. 所有规则名(如 identifier, number)都是 $ > ...3. 正则表达式用于定义词法规则(终结符&…...

Git 实践笔记

这里写自定义目录标题 一、将当前改动追加到某次commit上二、git 强制修改分支位置 一、将当前改动追加到某次commit上 stash工作区中的当前改动 git stash假设需要修改的commit是 f744c32,将HEAD移动到需要改动的commit的父提交上 git rebase f744c32^ --interact…...

【特权FPGA】之数码管

case语句的用法: 计数器不断的计数,每一个num对应数码管一种数据的输出。实例通俗易懂,一目了然。 timescale 1ns / 1ps// Company: // Engineer: // // Create Date: // Design Name: // Module Name: // Project Name: //…...

Stable Diffusion 四重调参优化——项目学习记录

学习记录还原:在本次实验中,我基于 Stable Diffusion v1.5模型,通过一系列优化方法提升生成图像的质量,最终实现了图像质量的显著提升。实验从基础的 Img2Img 技术入手,逐步推进到参数微调、DreamShaper 模型和 Contro…...

遇到git提交报错:413

是因为提交文件过大导致内存溢出。 解决方法: 假设您的提交历史如下: Apply to .gitignore abcd123 当前提交 efgh456 包含node_modules的提交 ijkl789 较早的正常提交 您可以: 回退到添加node_modules之前的提交: bash App…...

关于nacos注册的服务的ip异常导致网关路由失败的问题

文章目录 关于nacos注册的服务的ip异常导致网关路由失败的问题相关处理方案为方案一:手动指定服务注册的 IP 地址方法二:设置优先使用的网络段方法三:指定网络接口方法四:忽略特定的网卡 备注 关于nacos注册的服务的ip异常导致网关路由失败的…...

大模型在初治CLL成人患者诊疗全流程风险预测与方案制定中的应用研究

目录 一、绪论 1.1 研究背景与意义 1.2 国内外研究现状 1.3 研究目的与内容 二、大模型技术与慢性淋巴细胞白血病相关知识 2.1 大模型技术原理与特点 2.2 慢性淋巴细胞白血病的病理生理与诊疗现状 三、术前风险预测与手术方案制定 3.1 术前数据收集与预处理 3.2 大模…...

【C++游戏引擎开发】第9篇:数学计算库GLM(线性代数)、CGAL(几何计算)的安装与使用指南

写在前面 两天都没手搓实现可用的凸包生成算法相关的代码,自觉无法手搓相关数学库,遂改为使用成熟数学库。 一、GLM库安装与介绍 1.1 vcpkg安装GLM 跨平台C包管理利器vcpkg完全指南 在PowerShell中执行命令: vcpkg install glm# 集成到系…...

408 计算机网络 知识点记忆(8)

前言 本文基于王道考研课程与湖科大计算机网络课程教学内容,系统梳理核心知识记忆点和框架,既为个人复习沉淀思考,亦希望能与同行者互助共进。(PS:后续将持续迭代优化细节) 往期内容 408 计算机网络 知识…...

基于Python脚本实现Flink on YARN任务批量触发Savepoint的实践指南

基于Python脚本实现Flink on YARN任务批量触发Savepoint的实践指南 一、背景与价值 在流计算生产环境中,Flink on YARN的部署方式凭借其资源管理优势被广泛采用。Savepoint作为Flink任务状态的一致性快照,承载着故障恢复、版本升级、作业暂停等重要场景…...

我可能用到的网站和软件

我可能用到的网站和软件 程序员交流的网站代码管理工具前端组件库前端框架在线工具人工智能问答工具学习的网站Windows系统电脑的常用工具 程序员交流的网站 csdn博客博客园 - 开发者的网上家园InfoQ - 软件开发及相关领域-极客邦掘金 (juejin.cn) 代码管理工具 GitHub 有时…...

FPGA状态机设计:流水灯实现、Modelsim仿真、HDLBits练习

一、状态机思想 1.概念 状态机(Finite State Machine, FSM)是计算机科学和工程领域中的一种抽象模型,用于描述系统在不同状态之间的转换逻辑。其核心思想是将复杂的行为拆解为有限的状态,并通过事件触发状态间的转移。 2.状态机…...

2024年第十五届蓝桥杯CC++大学A组--成绩统计

2024年第十五届蓝桥杯C&C大学A组--成绩统计 题目: 动态规划, 对于该题,考虑动态规划解法,先取前k个人的成绩计算其方差,并将成绩记录在数组中,记录当前均值,设小蓝已检查前i-1个人的成绩&…...

WinForm真入门(13)——ListBox控件详解

WinForm ListBox 详解与案例 一、核心概念 ‌ListBox‌ 是 Windows 窗体中用于展示可滚动列表项的控件,支持单选或多选操作,适用于需要用户从固定数据集中选择一项或多项的场景‌。 二、核心属性 属性说明‌Items‌管理列表项的集合,支持动…...

Kotlin 学习-集合

/*** kotlin 集合* List:是一个有序列表,可通过索引(下标)访问元素。元素可以在list中出现多次、元素可重复* Set:是元素唯一的集合。一般来说 set中的元素顺序并不重要、无序集合* Map:(字典)是一组键值对。键是唯一的…...

解决java使用easyexcel填充模版后,高度不一致问题

自定义工具,可以通过获取上一行行高设置后面所以行的高度 package org.springblade.modules.api.utils;import com.alibaba.excel.write.handler.RowWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.wr…...

数据结构与算法之ACM Fellow-算法4.3 最小生成树

数据结构与算法之ACM Fellow-算法4.3 最小生成树 加权图 是一种为每条边关联一个 权值 或是 成本 的图模型。这种图能够自然地表示许多应用。在一幅航空图中,边表示航线,权值则可以表示距离或是费用。在一幅电路图中,边表示导线,…...

使用POCO库进行ZIP压缩和解压

使用POCO库进行ZIP压缩和解压 POCO C Libraries提供了一个ZIP模块&#xff0c;可以方便地进行文件和数据流的压缩与解压操作。下面我将介绍如何使用POCO的ZIP模块进行这些操作。 1. 基本ZIP文件操作 压缩文件/目录到ZIP #include <Poco/Zip/Compress.h> #include <…...

自动驾驶的未来:多模态感知融合技术最新进展

作为自动驾驶领域的专业人士&#xff0c;我很高兴与大家分享关于多模态感知融合技术的前沿研究和实践经验。在迅速发展的自动驾驶领域&#xff0c;多模态感知融合已成为提升系统性能的关键技术。本文将深入探讨基于摄像头和激光雷达的多模态感知融合技术&#xff0c;重点关注最…...

亮相2025全球分布式云大会,火山引擎边缘云落地AI新场景

4 月 9 日&#xff0c;2025 全球分布式云大会暨 AI 基础设施大会在深圳成功举办&#xff0c;火山引擎边缘云产品解决方案高级总监沈建发出席并以《智启边缘&#xff0c;畅想未来&#xff1a;边缘计算新场景落地与 Al 趋势新畅想》为主题&#xff0c;分享了边缘计算在 AI 技术趋…...

XCode集成第三方framework步骤

一、添加 .framework 文件到项目 ‌拖拽或手动添加‌ 在Xcode中&#xff0c;直接将 .framework 文件拖入项目导航器的目标文件夹中, 确保 .framework 文件被复制到项目目录内&#xff08;非外部路径&#xff09;‌。或通过菜单操作&#xff1a; ‌General → Frameworks, Libra…...

无损分区管理,硬盘管理的“瑞士军刀”!

打工人们你们好&#xff01;这里是摸鱼 特供版~ 今天给大家带来一款简单易用、功能强大的无损分区软件——分区助手技术员版&#xff0c;让你的硬盘管理变得轻松又高效&#xff01; 推荐指数&#xff1a;★★★★★ 软件简介 分区助手技术员版是一款功能强大的硬盘分区工具&…...

VS Code下开发FPGA——FPGA开发体验提升__下

上一篇&#xff1a;IntelliJ IDEA下开发FPGA-CSDN博客 Type&#xff1a;Quartus 一、安装插件 在应用商店先安装Digtal IDE插件 安装后&#xff0c;把其他相关的Verilog插件禁用&#xff0c;避免可能的冲突。重启后&#xff0c;可能会弹出下面提示 这是插件默认要求的工具链&a…...

ffmpeg播放音视频流程

文章目录 &#x1f3ac; FFmpeg 解码播放流程概览&#xff08;以音视频文件为例&#xff09;1️⃣ 创建结构体2️⃣ 打开音视频文件3️⃣ 查找解码器并打开解码器4️⃣ 循环读取数据包&#xff08;Packet&#xff09;5️⃣ 解码成帧&#xff08;Frame&#xff09;6️⃣ 播放 / …...