『森林火灾检测』基于PaddleX实现森林火灾检测
效果預覽
B站鏈接
AIStudio鏈接
項目背景
??2019年3月30日17時 ,涼山州木里縣境內發生森林火災,30名撲火人員犧牲。
??2020年3月30日15時35分,涼山州西昌市經久鄉和安哈鎮交界的皮家山山脊處發生森林火災,參與火災撲救的19人犧牲、3人受傷。這起森林火災造成各類土地過火總面積3047.7805公頃,綜合計算受害森林面積791.6公頃,直接經濟損失9731.12萬元。
??2020年4月14日17時35分,西藏自治區林芝市巴宜區尼西村附近發生森林火災,3000余人歷時4晝夜持續撲救,明火于4月18日17時全部撲滅。此次撲救,共撲打火線13公里,清理煙點4200余處、站桿倒木3900余根,開設防火隔離帶3.5公里,實施了兩次人工增雨。
??2021年3月13日12時許,寧夏固原市原州區張易鎮馬場村二林溝荒山起火,撲火過程中造成2人死亡,6人受傷。火場共有3處著火點,在3個不同山頭,過火面積500余畝。
??2021年3月14日13時許,云南省昆明市盤龍區茨壩街道與龍泉街道交界處三丘田附近發生森林火災。火情發生后,昆明市森林消防支隊249名指戰員迅速趕往現場處置,地方撲救力量(地方專業撲火隊員256人、半專業撲火隊員160人、干部群眾155人)緊密配合撲救。
??1950年以來,中國年均發生森林火災13067起,受害林地面積653019公頃,因災傷亡580人。其中1988年以前,全國年均發生森林火災15932起,受害林地面積947238公頃,因災傷亡788人(其中受傷678人,死亡110人)。1988年以后,全國年均發生森林火災7623起,受害林地面積94002公頃,因災傷亡196人(其中受傷142人,死亡54人),分別下降52.2%、90.1%和75.3%。
??森林火災由于在野外,人煙稀少,故而難以在初始階段就發現并及時撲滅,更大程度上只有當火情演變為較大規模后,才能夠被發現并撲救,而這時,撲救難度及損失程度已呈指數級上升。而如何在野外這樣的惡劣環境下及時捕捉火情并通報是人工智能時代下防火滅火的新命題。
??本項目基于PaddleX,選取PPYOLO進行項目開發,并實現了windows端的部署,后期將結合PaddleSlim裁剪模型大小以及PaddleLite部署于樹莓派上。
實地操作
1. 數據處理
2. 模型訓練
3. 模型導出
數據處理
#解壓數據集并將其移動至dataset中 !tar -xf /home/aistudio/data/data90352/fire_detection.tar !mv VOC2020 dataset數據處理
??在本數據集中,由于文件名及文件內容不符合PaddleX所提供的數據集讀取API,故需要對其進行處理。觀察數據集可知,有兩個問題:一為標注文件的文件名中存在空格,這極大地影響了PaddleX數據集讀取;二為標注文件中的內容需要進行對應性修改。
# 修改.xml文件名,去掉文件名中的空格 # -*- coding: utf-8 -*- import os #設定文件路徑 jpg_path='dataset/JPEGImages/' anno_path = 'dataset/Annotations/' i=1 #對目錄下的文件進行遍歷 for file in os.listdir(jpg_path): #判斷是否是文件if os.path.isfile(os.path.join(jpg_path,file))==True: #設置新文件名main = file.split('.')[0]if " " in main:new_main = main.replace(' ','')new_main_jpg = new_main + '.jpg'new_main_anno = new_main + '.xml'print(os.path.join(jpg_path,new_main_jpg))print(os.path.join(anno_path,new_main_anno))# new_name=file.replace(file,"rgb_%d.jpg"%i) # #重命名os.rename(os.path.join(jpg_path,main+'.jpg'),os.path.join(jpg_path,new_main_jpg))os.rename(os.path.join(anno_path,main+'.xml'),os.path.join(anno_path,new_main_anno))i+=1 #結束 print ("End") # 這里修改.xml文件中的<path>元素 !mkdir dataset/Annotations1 import xml.dom.minidom import ospath = r'dataset/Annotations' # xml文件存放路徑 sv_path = r'dataset/Annotations1' # 修改后的xml文件存放路徑 files = os.listdir(path) cnt = 1for xmlFile in files:dom = xml.dom.minidom.parse(os.path.join(path, xmlFile)) # 打開xml文件,送到dom解析root = dom.documentElement # 得到文檔元素對象item = root.getElementsByTagName('path') # 獲取path這一node名字及相關屬性值for i in item:i.firstChild.data = '/home/aistudio/dataset/JPEGImages/' + str(cnt).zfill(6) + '.jpg' # xml文件對應的圖片路徑with open(os.path.join(sv_path, xmlFile), 'w') as fh:dom.writexml(fh)cnt += 1 # 這里修改.xml文件中的<failname>元素 !mkdir dataset/Annotations2 import xml.dom.minidom import ospath = r'dataset/Annotations1' # xml文件存放路徑 sv_path = r'dataset/Annotations2' # 修改后的xml文件存放路徑 files = os.listdir(path)for xmlFile in files:dom = xml.dom.minidom.parse(os.path.join(path, xmlFile)) # 打開xml文件,送到dom解析root = dom.documentElement # 得到文檔元素對象names = root.getElementsByTagName('filename')a, b = os.path.splitext(xmlFile) # 分離出文件名afor n in names:n.firstChild.data = a + '.jpg'with open(os.path.join(sv_path, xmlFile), 'w') as fh:dom.writexml(fh)下面刪除在數據集處理過程中所生成的冗余文件,并將其更改為適合PaddleX的數據集格式。
!rm -rf dataset/Annotations !rm -rf dataset/Annotations1 !mv dataset/Annotations2 dataset/Annotations??PaddleX非常貼心地為開發者準備了數據集劃分工具,免去了開發者多寫幾行代碼的需求。這里我們設置訓練集、驗證集、測試集劃分比例為7:2:1。
!paddlex --split_dataset --format VOC --dataset_dir /home/aistudio/dataset/ --val_value 0.2 --test_value 0.1模型訓練
??在使用PaddleX進行模型訓練的過程中,我們使用目前PaddleX適配精度最高的PPYolo模型進行訓練。其模型較大,預測速度比YOLOv3-DarkNet53更快,適用于服務端。大家也可以更改其他模型嘗試一下。這里我訓練了大概200個epoch(別問,問就是沒算力了也懶得續點了……)當然看趨勢還能漲!(有算力的童鞋可以試著調參或者繼續往下面去試試)
import os os.environ['CUDA_VISIBLE_DEVICES'] = '0'from paddlex.det import transforms import paddlex as pdx# 定義訓練和驗證時的transforms # API說明 https://paddlex.readthedocs.io/zh_CN/develop/apis/transforms/det_transforms.html train_transforms = transforms.Compose([transforms.MixupImage(mixup_epoch=250), transforms.RandomDistort(),transforms.RandomExpand(), transforms.RandomCrop(), transforms.Resize(target_size=608, interp='RANDOM'), transforms.RandomHorizontalFlip(),transforms.Normalize() ])eval_transforms = transforms.Compose([transforms.Resize(target_size=608, interp='CUBIC'), transforms.Normalize() ])# 定義訓練和驗證所用的數據集 # API說明:https://paddlex.readthedocs.io/zh_CN/develop/apis/datasets.html#paddlex-datasets-vocdetection train_dataset = pdx.datasets.VOCDetection(data_dir='/home/aistudio/dataset',file_list='/home/aistudio/dataset/train_list.txt',label_list='/home/aistudio/dataset/labels.txt',transforms=train_transforms,parallel_method='thread',shuffle=True) eval_dataset = pdx.datasets.VOCDetection(data_dir='/home/aistudio/dataset',file_list='/home/aistudio/dataset/val_list.txt',label_list='/home/aistudio/dataset/labels.txt',parallel_method='thread',transforms=eval_transforms)# 初始化模型,并進行訓練 # 可使用VisualDL查看訓練指標,參考https://paddlex.readthedocs.io/zh_CN/develop/train/visualdl.html num_classes = len(train_dataset.labels)# API說明: https://paddlex.readthedocs.io/zh_CN/develop/apis/models/detection.html#paddlex-det-ppyolo model = pdx.det.PPYOLO(num_classes=num_classes)# API說明: https://paddlex.readthedocs.io/zh_CN/develop/apis/models/detection.html#train # 各參數介紹與調整說明:https://paddlex.readthedocs.io/zh_CN/develop/appendix/parameters.html model.train(num_epochs=540,train_dataset=train_dataset,train_batch_size=8,eval_dataset=eval_dataset,learning_rate=0.000125,save_interval_epochs=1,lr_decay_epochs=[270,320, 480],save_dir='output/ppyolo',resume_checkpoint='/home/aistudio/output/ppyolo/epoch_197',use_vdl=True)模型導出
??這里我們將訓練過程中保存的模型導出為inference格式模型,其原因在于:PaddlePaddle框架保存的權重文件分為兩種:支持前向推理和反向梯度的訓練模型 和 只支持前向推理的推理模型。二者的區別是推理模型針對推理速度和顯存做了優化,裁剪了一些只在訓練過程中才需要的tensor,降低顯存占用,并進行了一些類似層融合,kernel選擇的速度優化。而導出的inference格式模型包括__model__、__params__和model.yml三個文件,分別表示模型的網絡結構、模型權重和模型的配置文件(包括數據預處理參數等)。
!paddlex --export_inference --model_dir=output/ppyolo/best_model --save_dir=./inference_model模型部署
模型導出后我們可以采用Python端以視頻流的形式部署。
import cv2 import paddlex as pdx from playsound import playsound# 修改模型所在位置 predictor = pdx.deploy.Predictor('D:\\project\\python\\fire\\inference_model') cap = cv2.VideoCapture('D:\\project\\python\\fire\\mda-kcwgejj7mfckc19e.mp4')while cap.isOpened():ret, frame = cap.read()if ret:result = predictor.predict(frame)score = result[0]['score']if score >= 0.3:print("*"*100)# 修改音頻所在位置# playsound('D:\\project\\python\\cigarette\\cigarette.mp3')# print(result)vis_img = pdx.det.visualize(frame, result, threshold=0.3, save_dir=None)cv2.imshow('cigarette', vis_img)if cv2.waitKey(1) & 0xFF == ord('q'):breakelse:break cap.release()請點擊此處查看本環境基本用法.
Please click here for more detailed instructions.
總結
以上是生活随笔為你收集整理的『森林火灾检测』基于PaddleX实现森林火灾检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 『PPYOLO tiny尝鲜』基于Pad
- 下一篇: 『PaddlePaddle X Wech