文章目錄
- 一.前言
- 1.引言
- 2.正文
- 二.核心內容
- 1.數據集
- 2.模型訓練
- 3.界面窗口
- 1.登錄注冊界面
- 2.核心功能界面
- 3.檢測告警提示窗口
- 三..核心界面模塊介紹
- 1.頂部信息區域
- 2.數據輸入
- 3.參數配置
- 4.告警設置
- 5.操作臺
- 6.關于
- 7.指標變化
- 8.異常速覽
- 9.日志輸出
- 10.檢測結果
- 11.核心內容顯示區域
- 四.問題回答
- 1.項目結構是怎樣的,好上手么?
- 2.項目依賴
- 3.我想更改背景圖或文字
- 1.改文字
- 2.改圖片
- 五.總結
一.前言
1.引言
火災作為威脅人類生命和財產安全的主要災害之一,早期識別對減少損害至關重要。傳統的煙霧探測器作用范圍有限,而基于計算機視覺的火焰與煙霧識別系統能夠覆蓋更廣泛區域,實現及時預警。本項目的開發具有多方面重要價值:它可應用于商場、學校、地鐵站等公共場所,實現全天候監測,快速發現火情隱患,爭取人員疏散的寶貴時間;在石油化工、電力及制造等高風險行業,能夠實時監控異常火焰和煙霧,防止嚴重事故發生;結合無人機及監控設備,可用于大范圍森林火災防控,解決傳統人工巡邏效率低及覆蓋面窄的問題;系統還能集成到智能家居平臺,提升家庭火災報警能力,尤其適合無人居住的場景;此外,本項目驗證了YOLOv8算法在火焰煙霧檢測中的適用性,為相關領域研究提供了寶貴的實踐經驗和技術支持;從經濟角度來看,該視覺檢測方案相較傳統火災報警系統安裝維護成本更低,覆蓋范圍更廣,顯著降低安全保障投入;社會層面上,它通過技術手段有效降低火災發生頻率及損失,有助于營造更加安全的社會環境,保障人民生命與財產安全。
2.正文
朋友們好!本次給大家介紹我開發的“基于YOLO的火焰與煙霧檢測系統”,本系統通過自行訓練YOLO目標檢測模型,使用PyQt5制作交互界面,設置了多種告警方式以及數據可視化方案,用戶能夠設置詳細的目標檢測參數配置,系統支持多種輸入數據源,主打美觀實用!接下來我以詳細圖文的方式和大家介紹我開發的系統~
二.核心內容
1.數據集
我們的數據集包括了包含煙霧和火焰的圖像共909張,其中訓練集為673張,驗證集為236張,每張圖都進行了詳細的標注,標注的目標為煙霧(0)和火焰(1)下面截圖為訓練集圖像示例,數據集已經打包!
我們按照訓練集:測試集8:2的比例對全集進行劃分,最后產出兩個目錄
數據集當然不是手動劃分的,因為太機械了,我們可以先把標注好的圖像放到一起,把標注好的txt(YOLO格式)文件也放到一起,最后使用腳本設置好相關數量,就能實現自動劃分啦!
import os
import shutil
import random# 輸入路徑
labels_dir = r'C:\Users\13978\Downloads\fire_detection\VOC2020\labels' # 輸入YOLO標簽文件目錄
images_dir = r'C:\Users\13978\Downloads\fire_detection\VOC2020\JPEGImages' # 對應圖像文件目錄
output_dir = r'C:\Users\13978\Downloads\fire_detection\VOC2020\output_dataset2' # 輸出目錄# 分配數量
train_count = 400
val_count = 100# 創建輸出目錄結構
for split in ['train', 'val']:os.makedirs(os.path.join(output_dir, split, 'images'), exist_ok=True)os.makedirs(os.path.join(output_dir, split, 'labels'), exist_ok=True)# 獲取所有標注文件(假設圖像和標簽同名)
label_files = [f for f in os.listdir(labels_dir) if f.endswith('.txt')]
random.shuffle(label_files)# 檢查數量是否足夠
total_needed = train_count + val_count
if len(label_files) < total_needed:raise ValueError(f"標簽文件不足,共有 {len(label_files)} 個,要求至少 {total_needed} 個。")# 分配訓練和驗證
train_files = label_files[:train_count]
val_files = label_files[train_count:train_count + val_count]def copy_samples(file_list, split_name):for label_file in file_list:base_name = os.path.splitext(label_file)[0]image_file = None# 嘗試匹配圖像擴展名for ext in ['.jpg', '.png', '.jpeg']:possible_image = os.path.join(images_dir, base_name + ext)if os.path.exists(possible_image):image_file = possible_imagebreakif image_file is None:print(f"?? 圖像文件 {base_name} 不存在,跳過。")continue# 拷貝標簽和圖像shutil.copy(os.path.join(labels_dir, label_file), os.path.join(output_dir, split_name, 'labels', label_file))shutil.copy(image_file, os.path.join(output_dir, split_name, 'images', os.path.basename(image_file)))print(f"? {split_name} 集合完成,共復制 {len(file_list)} 張圖像。")# 執行復制
copy_samples(train_files, 'train')
copy_samples(val_files, 'val')
這里多說一句,如果大家拿到的是VOC格式的數據集也不要慌,我們可以使用下面的腳本將VOC數據集轉化成YOLO數據集以供模型訓練。
import os
import xml.etree.ElementTree as ET
from PIL import Image# VOC 類別列表(順序必須固定)
classes = ['fire'] # 替換成你自己的類別# 輸入路徑
voc_anno_dir = r'C:\Users\13978\Downloads\fire_detection\VOC2020\Annotations'
voc_img_dir = r'C:\Users\13978\Downloads\fire_detection\VOC2020\JPEGImages'# 輸出路徑
yolo_label_dir = r'C:\Users\13978\Downloads\fire_detection\VOC2020\labels'
os.makedirs(yolo_label_dir, exist_ok=True)def convert_box(size, box):"""將VOC邊界框坐標轉為YOLO格式"""dw = 1. / size[0]dh = 1. / size[1]x_center = (box[0] + box[1]) / 2.0y_center = (box[2] + box[3]) / 2.0w = box[1] - box[0]h = box[3] - box[2]return (x_center * dw, y_center * dh, w * dw, h * dh)def convert_annotation(xml_path, img_path, output_path):tree = ET.parse(xml_path)root = tree.getroot()img = Image.open(img_path)w, h = img.sizewith open(output_path, 'w') as out_file:for obj in root.iter('object'):cls = obj.find('name').textif cls not in classes:continuecls_id = classes.index(cls)xml_box = obj.find('bndbox')b = (float(xml_box.find('xmin').text),float(xml_box.find('xmax').text),float(xml_box.find('ymin').text),float(xml_box.find('ymax').text))bb = convert_box((w, h), b)out_file.write(f"{cls_id} {' '.join(map(str, bb))}\n")# 遍歷VOC標注文件夾
for filename in os.listdir(voc_anno_dir):if not filename.endswith('.xml'):continuexml_path = os.path.join(voc_anno_dir, filename)img_filename = filename.replace('.xml', '.jpg')img_path = os.path.join(voc_img_dir, img_filename)output_path = os.path.join(yolo_label_dir, filename.replace('.xml', '.txt'))if not os.path.exists(img_path):print(f"Warning: image {img_path} not found, skipping.")continueconvert_annotation(xml_path, img_path, output_path)print(f"Converted {filename} to {output_path}")
By:如有需要,本人可提供標注好的VOC(XML)格式火焰數據集2059張,歡迎了解!
2.模型訓練
我們使用yolov8n.pt作為基礎模型,對標注好的數據集進行深度學習模型訓練,訓練的話需要準備
data.yaml
配置文件,此文件內容可以參考我的:
path: C:\Users\13978\Downloads\fire_detection\VOC2020\output_dataset2 # 數據集的根目錄
train: train # 相對于 path 的訓練圖像路徑
val: val # 相對于 path 的驗證圖像路徑names:0: smoke1: fire
然后執行下面的命令,就可以開始訓練模型了
yolo task=detect mode=train model=../data/models/yolov8n.pt data=./data.yaml epochs=50 imgsz=640 batch=16 lr0=0.01
下表為上面命令的詳細解讀
參數 | 值 | 解釋 |
---|---|---|
yolo | - | 調用 YOLOv8 的命令行接口工具。 |
task=detect | detect | 任務類型為“目標檢測”(可選值還有:segment , classify 等)。 |
mode=train | train | 模式為訓練模式(其他模式有 predict , val , export 等)。 |
model=../data/models/yolov8n.pt | ../data/models/yolov8n.pt | 指定預訓練模型的路徑,這里是 YOLOv8n(nano)版本的權重。 |
data=./data.yaml | ./data.yaml | 數據集配置文件的路徑,定義了訓練集、驗證集的路徑及類別等信息。 |
epochs=50 | 50 | 模型將訓練 50 個 epoch。 |
imgsz=640 | 640 | 輸入圖像尺寸為 640×640 像素。 |
batch=16 | 16 | 每個 batch 包含 16 張圖像(batch size)。 |
lr0=0.01 | 0.01 | 初始學習率設置為 0.01。 |
害,由于博主電腦不支持GPU加速,所以確實花費了一些時間成本,最終訓練50輪我們花費了將近3個小時,好在功夫不負有心人,訓練任務如期結束。
下面的數圖為模型輸出目錄和文件
卷 Data 的文件夾 PATH 列表
卷序列號為 9AD9-E265
D:\PROJECTS\GITEE\YOLO_PROJECTS\YOLOV8-FIRE-SMOKE-DETECTION\TRAIN\RUNS\DETECT\TRAIN3
│ args.yaml
│ confusion_matrix.png
│ confusion_matrix_normalized.png
│ events.out.tfevents.1753497631.Admin.16932.0
│ F1_curve.png
│ labels.jpg
│ labels_correlogram.jpg
│ PR_curve.png
│ P_curve.png
│ results.csv
│ results.png
│ R_curve.png
│ train_batch0.jpg
│ train_batch1.jpg
│ train_batch1720.jpg
│ train_batch1721.jpg
│ train_batch1722.jpg
│ train_batch2.jpg
│ val_batch0_labels.jpg
│ val_batch0_pred.jpg
│ val_batch1_labels.jpg
│ val_batch1_pred.jpg
│ val_batch2_labels.jpg
│ val_batch2_pred.jpg
│
└─weightsbest.ptlast.pt
簡單介紹一下輸出文件、目錄內容
文件/文件夾名 | 類型 | 說明用途 |
---|---|---|
best.pt | 模型權重 | 驗證集表現最佳的模型,推薦用于推理部署 |
last.pt | 模型權重 | 最后一輪訓練后保存的模型 |
args.yaml | 配置文件 | 本次訓練的參數配置(batch size、epoch、數據路徑等) |
results.png | 圖像 | 訓練過程關鍵指標(Loss、mAP、Precision、Recall)趨勢圖 |
results.csv | 表格數據 | 與 results.png 對應的原始數據(每個 epoch 的指標) |
confusion_matrix.png | 圖像 | 混淆矩陣,展示預測 vs 真實類別的關系 |
confusion_matrix_normalized.png | 圖像 | 歸一化混淆矩陣,更易觀察類別預測比例 |
F1_curve.png | 圖像 | F1 分數曲線,衡量精度與召回的平衡 |
P_curve.png | 圖像 | Precision(準確率)隨閾值變化曲線 |
R_curve.png | 圖像 | Recall(召回率)隨閾值變化曲線 |
PR_curve.png | 圖像 | PR 曲線(Precision vs Recall) |
labels.jpg | 圖像 | 各類別標注的分布頻率圖 |
labels_correlogram.jpg | 圖像 | 類別之間的共現關系圖(哪些類別常一起出現) |
train_batch0.jpg 等 | 圖像 | 訓練集部分圖像及其標注框(訓練樣本可視化) |
val_batch*_labels.jpg | 圖像 | 驗證集圖像+真實標簽框 |
val_batch*_pred.jpg | 圖像 | 驗證集圖像+模型預測框(用于與真實值對比) |
events.out.tfevents.* | 日志文件 | TensorBoard 日志文件,支持訓練過程可視化 |
weights/ 文件夾 | 文件夾 | 存放訓練過程中生成的模型權重文件(包含 best.pt , last.pt ) |
下圖為results.png
我們最關心的當然是weights/best.pt
模型文件,這是我們火焰與煙霧檢測系統
的核心。
3.界面窗口
在本章節僅簡單介紹一下界面:
我們的核心界面包括:
1.登錄注冊界面
2.核心功能界面
3.檢測告警提示窗口
提示:為了使用不同需求的用戶,我們這里為大家設置了方便的設置開關,具體來說是代碼里面的system_conf.py
我們設置了一個SHOW_LOGIN_FLAG
用來控制“是否啟用登錄系統”,當此標志位為True
時,啟用登錄系統,反之不啟用。
1.登錄注冊界面
我們為用戶設計了美觀簡約的登錄注冊界面,用戶可以選擇注冊或者登錄,拿到代碼的小伙伴可以自行調整系統相關文字以及圖標和背景圖片,系統附帶了登錄注冊使用的數據庫,默認用戶名和密碼為
用戶名:admin
密碼:admin
2.核心功能界面
只有用戶名和密碼匹配并且成功登錄的用戶才能使用我們系統的核心功能,我們的和弦功能界面采用PyQt5開發,包含多個功能模塊和顯示區域,這些子模塊我會在下一個章節詳細介紹。
3.檢測告警提示窗口
我們設置了多種告警提示方案,下圖為“系統彈窗提示”方案,當發現畫面中有煙霧或者火情時,系統會自動在桌面右下角彈出警告提示窗,發出聲音進行告警提示。
三..核心界面模塊介紹
本章節是我們系統的核心章節,我會使用圖文的方式介紹每個核心界面的子模塊,讓大家了解我設計的目的和具體代碼實現方案,大家能夠了解到我具體的設計初衷以及想法。
1.頂部信息區域
頂部信息區域由三部分組成,分別為:標題區域、日期與系統指標區域、用戶信息區域。
首先,系統名稱以大號字體居中展示,并采用半透明背景樣式,以突出系統標識和整體視覺效果。其下方左側顯示當前時間和日期,實現實時更新。
在底部,系統會每秒刷新一次當前 CPU 和內存使用率,數據精確到小數點后一位,方便用戶實時掌握系統運行狀態。
右側為用戶信息區域,顯示當前登錄用戶的姓名。旁邊的小三角圖標為功能入口,點擊后可選擇 “退出登錄” 或 “退出系統” 兩項操作:
退出登錄:系統將跳轉回登錄界面,用戶需重新輸入正確的用戶名和密碼以重新登錄;
退出系統:系統會彈出確認提示,詢問用戶“是否確定退出”。點擊 YES 后,系統將完全關閉。
2.數據輸入
該區域為系統的整體數據輸入控制面板,支持四種數據輸入方式,具體包括:
圖片
視頻
RTMP/RTSP 視頻流
本機攝像頭
多樣化的輸入方式極大地擴展了系統的數據接入能力與應用場景。
在下方區域,用戶可以選擇博主提供的預訓練模型 best.pt 作為目標檢測模型,也可加載自行訓練的模型文件。系統在模型選擇方面提供了較高的靈活性,只要模型符合系統支持的格式與規范,即可順利接入使用。
3.參數配置
在參數配置子模塊中,用戶可以靈活調整輸入參數,包括重疊度(IOU)和置信度(Confidence),這些參數的變動將直接影響最終的目標檢測結果。
我們提供了兩種參數調節方式:SpinBox 和 Slider。這兩個組件基于 Vue 的雙向綁定機制,實現了數據的同步更新——當用戶調整其中一個組件時,另一個組件的數值也會自動聯動變化。
這種便捷的參數調節方式大大降低了用戶配置系統輸入參數的操作難度,提升了使用效率和體驗。
4.告警設置
在告警設置模塊中,用戶需手動選擇所需的告警方式。系統內置了五種告警方式,具體如下:
語音播報:通過語音播放具體的告警內容;
聲音告警:播放預設的告警音效;
系統彈窗提醒:在屏幕右下角彈出告警提示窗口;
短信提醒:調用第三方服務發送短信(需進行相關配置);
郵件提醒:通過第三方服務發送郵件通知(需進行相關配置)。
這些可多選的組件為復選框(QCheckBox),用戶可以根據需求選擇多個。
5.操作臺
用戶可在操作臺上直接對系統進行操作,包括:
停止任務
導出數據(支持 TXT、CSV、Excel 格式)
保存畫面(將當前畫面保存為本地文件)
清空畫面(清除當前顯示內容)
為提升功能辨識度,我們貼心地為不同功能設置了顏色區分的交互按鈕,幫助用戶更高效地完成操作。
6.關于
此處展示了若干信息入口,包括:
關于作者:點擊后將提示用戶是否前往作者博客;
技術支持:可直接通過 QQ 與作者聯系,進行在線咨詢;
關于軟件:展示當前軟件的基本信息和簡介;
關于 Qt:調用系統原生的 Qt 信息彈窗。
通過這些入口,用戶可以方便地了解軟件背景,并快速獲取開發者的技術支持。
7.指標變化
我們為系統設置了高顏值的折線圖可視化界面,用于實時展示 CPU 與內存占用情況 的變化趨勢。圖表采用 ECharts 實現,背景為透明樣式,整體風格簡潔美觀,提升了系統界面的視覺體驗。
CPU 利用率 以發光黃色折線展示;
內存使用率 以發光紫色折線展示;
數據每秒更新一次,通過多線程方式刷新,確保圖表實時性同時不會阻塞主線程,避免界面卡頓。
當鼠標懸停于折線圖上時,將自動顯示對應時間點的詳細指標值,方便用戶精確查看系統資源變化。
8.異常速覽
此模塊為博主的一個巧思,旨在于快速讓用戶看到匯總起來的每個目標圖像數據,用戶可以使用點擊圖像的方式按需保存每一塊截取出來的圖像,我們為每個圖像進行了編號,這里的編號和檢測結果表格里的編號是對應的,如果有多個會自動添加滾動條進行展示。
9.日志輸出
顧名思義,該模塊用于展示實時檢測結果日志,包括檢測出的目標數量及相關告警信息。
每條新日志在展示前,都會自動添加精確到時分秒的時間戳,便于用戶后續回溯與分析。新生成的日志將按時間順序追加至日志末尾,并支持自動滾動顯示,確保用戶始終能夠查看到最新的檢測信息。
10.檢測結果
在此區域,我們以二維表格的形式展示當前圖像檢測的結果,所有檢測到的目標均以列表方式呈現,便于統一查看。
圖像數據采用 Base64 編碼 方式進行切割與嵌入,用戶可以直觀地查看每個目標的圖像片段,并與當前畫面進行快速比對,便于問題定位與分析。
表格基于簡約的 HTML <table>
結構構建,設計輕量,顯著降低了系統資源開銷。
當檢測結果較多時,表格右側會自動顯示滾動條,用戶可通過拖動滾動條查看更多內容,保證良好的交互體驗與數據可讀性。
11.核心內容顯示區域
本區域用于展示每次目標檢測的結果,采用 堆棧組件(QStackedWidget) 實現多頁面切換。具體包括:
第一頁:用于顯示圖像檢測結果;
第二頁:用于顯示視頻、視頻流或攝像頭檢測結果。
通過這種設計,系統能夠靈活支持 靜態圖像 與 動態視頻流 兩種類型的內容展示。
該區域是整個軟件中占據界面面積最大的部分,同時也是用戶最為關注的核心功能區域。
四.問題回答
在這個章節我將對大家關注的問題進行回答
1.項目結構是怎樣的,好上手么?
請放心,項目好上手!
我們的項目定義為yolov8-fire-smoke-detection
,我們使用包、類和函數對主要功能進行區分,核心代碼位于src
目錄下,項目根目錄的main.py
為程序入口,每個目錄的功能和作用大家見名知意,我們的代碼采用標準格式的編碼,比如類名就是大駝峰,函數名就是小寫加下劃線,下圖為項目結構
2.項目依賴
我們的項目核心為PyQt5+YOLOv8,下面是我們項目的依賴
PyQt5==5.15.11
PyQt5_sip==12.15.0
QtAwesome==1.3.1
torch==2.4.1
torchvision==0.19.1
Pillow==9.3.0
PyQtWebEngine==5.15.5
opencv-python==4.10.0.82
ultralytics==8.3.98
pyttsx3==2.71
大家拿到代碼之后直接執行下面的命令,即可一鍵安裝依賴!
pip install -r requirements.txt
請你放心,我們的項目一定能運行!
3.我想更改背景圖或文字
這個需求還是很常見的
1.改文字
改文字很簡單,比如要更改項目名字,就去代碼中全局搜索
指定的字符串,下圖為PyCharm全局搜索的方式
Edit-Find-Replace in Files
然后搜索要替換的字符串
然后重新啟動項目
驗證一下,生效
2.改圖片
這里以更改背景圖片為例,給大家演示如何更改主界面背景圖
首先要現有一張背景圖,然后放到imgs/
目錄下替換同名文件
然后執行script/create_qrc.py
腳本,重新生成qrc二進制資源文件,最后驗證一下
ok沒問題!
五.總結
這次和大家詳細分享了我使用PyQt5+YOLOV8開發的火焰與煙霧檢測系統,本系統實用性強、可拓展性強、能夠滿足不同用戶的差異化需求。
需要源碼可以點擊下方二維碼加我好友帶數據集,非無償請理解!