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+生成模型)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75353.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75353.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75353.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

量子計算未來的潛力和挑戰

據麥肯錫預測,到 2035 年或 2040 年,量子計算市場規模可能增長至約 800 億美元。目前,許多量子比特技術正競相成為首臺通用、無差錯量子計算機的基礎,但仍面臨諸多挑戰。 我們將探討量子計算的未來前景、潛力,以及它對…

ArcGIS 給大面內小面字段賦值

文章目錄 引言:地理數據處理中的自動化賦值為何重要?實現思路模型實現關鍵點效果實現步驟1、準備數據2、執行3、完成4、效果引言:地理數據處理中的自動化賦值為何重要? 在地理信息系統(GIS)的日常工作中,空間數據的屬性字段賦值是高頻且關鍵的操作,例如在土地利用規劃…

如何打通虛擬化-容器環境并保障流量安全?SmartX VCCI 方案升級!

為了提升資源利用率、交付效率和業務靈活性,不少企業用戶都在推進從傳統架構向云原生架構的演進,并采用虛擬機與容器共存的混合模式支持多種業務系統。由于兩個環境在業務交互層面形成高度耦合,企業需要具備簡單、高效方案,實現虛…

stable diffusion 量化加速點

文章目錄 一、導出為dynamic shape1)函數講解(函數導出、輸出檢查)2)代碼展示二、導出為static shape1)函數講解(略)2)代碼展示三、序列化為FP32測速1)測速2)代碼四、序列化為FP16測速1)測速2)代碼同上五、發現并解決解決CLIP FP16溢出,并測速1)如何找到溢出的算子…

7-openwrt-one通過web頁面配置訪客網絡、無線中繼等功能

前幾個章節一直在介紹編譯、分區之類的,都還沒正常開始使用這個路由器的wifi。默認wifi是沒有啟動的,前面還是通過手動修改uci配置啟動的,這個章節介紹下官方web頁面的使用。特別是訪客網絡、無線中繼 1、開啟wifi,配置wifi基本信息 我們使用有線連接路由器,通過192.168.…

AcWing 6099. 座位

原題目鏈接 問題描述 有 n 頭奶牛(n ≥ 5),編號為 1 ~ n,按照某種順序圍著一張圓桌坐成一圈。 奶牛之間存在如下的朋友關系: 如果兩頭奶牛相鄰,則它們是朋友;如果兩頭奶牛之間只隔著一頭奶…

44、Spring Boot 詳細講義(一)

Spring Boot 詳細講義 目錄 Spring Boot 簡介Spring Boot 快速入門Spring Boot 核心功能Spring Boot 技術棧與集成Spring Boot 高級主題Spring Boot 項目實戰Spring Boot 最佳實踐總結 一、Spring Boot 簡介 1. Spring Boot 概念和核心特點 1.1、什么是 Spring Boot&#…

配置mac mini M4 的一些軟件

最近更換了 mac mini M4 ,想要重新下載配置軟件 ,記錄一下。 Homebrew是什么? homebrew是一款Mac OS平臺下的軟件包管理工具,擁有安裝、卸載、更新、查看、搜索等功能。通過簡單的指令可以實現包管理,而不用關心各種…

網絡空間安全(54)CSRF

一、定義與原理 CSRF(Cross-Site Request Forgery),全稱為跨站請求偽造,也被稱為One Click Attack或Session Riding,縮寫為CSRF或XSRF。它是一種網絡安全漏洞,攻擊者通過偽造用戶的請求,利用用戶…

分布式文件存儲系統FastDFS

文章目錄 1 分布式文件存儲1_分布式文件存儲的由來2_常見的分布式存儲框架 2 FastDFS介紹3 FastDFS安裝1_拉取鏡像文件2_構建Tracker服務3_構建Storage服務4_測試圖片上傳 4 客戶端操作1_Fastdfs-java-client2_文件上傳3_文件下載4_獲取文件信息5_問題 5 SpringBoot整合 1 分布…

安裝了VM Tools,仍無法復制拖動-解決方案

今天在安裝ubuntu時遇到了困擾許久的問題,安裝了VM Tools,仍無法拖動主機文件到虛擬機,主要有兩種原因并對應解決辦法。 1.相關虛擬機設置選項卡中-客戶機隔離-兩個功能沒有勾選 解決方案:勾選重啟虛擬機即可 2.(這個…

Jmeter分布式測試啟動

代理客戶端配置 打開jmeter.properties文件,取消注釋并設置端口(如server_port1099), 并添加server.rmi.ssl.disabletrue禁用SSL加密。 (Linux系統)修改jmeter-server文件中的RMI_HOST_DEF為代理機實際IP。…

火語言RPA--Oracle-導入數據表格

【組件功能】:導入特定的表格數據到包含同樣字段的數據表 將表格對象數據通過數據庫操作對象導入到指定數據庫。 配置預覽 配置說明 源表格 表格來源有“來自表格對象”和“來自表達式”2種,表達式支持DataTable類型變量。 對象 對應來自表格對象&…

Java的Selenium的特殊元素操作與定位之驗證碼

1.使用OCR技術識別驗證 步驟: 截取整個網頁的截圖。 定位驗證碼圖片元素。 根據驗證碼圖片的位置和大小,從截圖中裁剪出驗證碼圖片。 使用OCR工具(如Tesseract)識別驗證碼圖片中的文本。 2.手動處理驗證碼 步驟:…

OpenStack Yoga版安裝筆記(十七)安全組筆記

一、安全組與iptables的關系 OpenStack的安全組(Security Group)默認是通過Linux的iptables實現的。以下是其主要實現原理和機制: 安全組與iptables的關系 OpenStack的安全組規則通過iptables的規則鏈實現。每條安全組規則會被轉換為相應的i…

starrocks split函數和trino split函數差異性

在trino419和starrocks3.2.8中分別執行下面這兩條sql,出來的結果是不一樣的 select split(,,,)[1] as t1 select coalesce(split(,,&#

Spring Data JPA中的List底層:深入解析ArrayList的奧秘!!!

&#x1f31f; Spring Data JPA中的List底層&#xff1a;深入解析ArrayList的奧秘 &#x1f4a1; 你是否好奇過&#xff0c;為什么Spring Data JPA的查詢方法返回的List<T>總是默認為ArrayList&#xff1f;本文將通過技術原理解析、驗證實驗和性能優化指南&#xff0c;為…

騰訊云智測試開發面經

1、投遞時間線 2.20投遞簡歷,3.11第一輪面試,3.30第二輪面試,4.4第三輪面試,4.10第四輪面試,4.11offer意向書 2、第一輪面試 第一輪面試技術面,面試官是導師,面試時長40多分鐘 1)自我介紹 2)數組和列表的區別 3)了解哪些數據庫 4)進程和線程的區別 5)了解哪…

【深度學習】【目標檢測】【Ultralytics-YOLO系列】YOLOV3源碼整體結構解析

【深度學習】【目標檢測】【Ultralytics-YOLO系列】YOLOV3源碼整體結構解析 文章目錄 【深度學習】【目標檢測】【Ultralytics-YOLO系列】YOLOV3源碼整體結構解析前言代碼結構整體data文件結構模型訓練超參數配置文件解析數據集配置文件解析 models文件結構utils文件結構runs文…

Python常用排序算法

1. 冒泡排序 冒泡排序是一種簡單的排序算法&#xff0c;它重復地遍歷要排序的列表&#xff0c;比較相鄰的元素&#xff0c;如果他們的順序錯誤就交換他們。 def bubble_sort(arr):# 遍歷所有數組元素for i in range(len(arr)):# 最后i個元素是已經排序好的for j in range(0, …