MaskDetection / dl_finalproject.py
YuXiLi's picture
Upload 626 files
6964af9 verified
raw
history blame
No virus
4.62 kB
# -*- coding: utf-8 -*-
"""DL_finalProject.ipynb
Automatically generated by Colab.
Original file is located at
https://colab.research.google.com/drive/10aj1WXX-L9ZzCbSXCLN1D3X6Pwbf1OCr
"""
# Commented out IPython magic to ensure Python compatibility.
# 連結google drive
from google.colab import drive
drive.mount('/content/drive/')
# %cd /content/drive/MyDrive/AI/DL_finalProject
!pip install -q kaggle
# 上傳kaggle.json
from google.colab import files
uploaded = files.upload()
!mkdir ~/.kaggle
!cp kaggle.json ~/.kaggle/
!chmod 600 ~/.kaggle/kaggle.json
import kaggle
# download API
!kaggle datasets download -d andrewmvd/face-mask-detection
# 將檔案解壓縮並放至指定資料夾
!unzip face-mask-detection.zip
# 載入與創建資料夾
from pathlib import Path
images_dir= Path('images')
annotations_dir= Path('annotations')
labels_dir = Path('labels')
if not labels_dir.exists():
!mkdir -p labels
import xml.etree.ElementTree as ET
import os
# 將bbox轉換成yolov7可訓練的格式
def convert_bbox(size, box):
dw = 1. / size[0]
dh = 1. / size[1]
x = (box[0] + box[1]) / 2.0
y = (box[2] + box[3]) / 2.0
w = box[1] - box[0]
h = box[3] - box[2]
return (x * dw, y * dh, w * dw, h * dh)
classes = {'without_mask': 0 ,'mask_weared_incorrect': 1 ,'with_mask': 2}
# 遍歷annotations文件夾中的所有.xml文件
for xml_file in os.listdir(annotations_dir):
if not xml_file.endswith('.xml'):
continue
tree = ET.parse(os.path.join(annotations_dir, xml_file))
root = tree.getroot()
# 擷取圖片寬度及高度資訊
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
# 創建對應的txt文件
txt_file = xml_file.replace('.xml', '.txt')
with open(os.path.join(labels_dir, txt_file), 'w') as f:
for obj in root.iter('object'):
# 讀取類別名稱
cls = obj.find('name').text
# 讀取bbox資訊
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text),
float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
bb = convert_bbox((w, h), b)
f.write(f"{classes[cls]} {bb[0]} {bb[1]} {bb[2]} {bb[3]}\n")
import os, shutil, random
# 設置比例
train_ratio = 0.7
val_ratio = 0.2
test_ratio = 0.1
# 準備文件夾
base_dir = 'data'
if not os.path.exists(base_dir):
os.makedirs(base_dir, exist_ok=True)
for subset in ['train', 'val', 'test']:
for folder in ['images', 'labels']:
os.makedirs(f"{base_dir}/{subset}/{folder}", exist_ok=True)
# 抓取圖片檔名(maksssksksss___.png)並打亂順序
image_files = [f for f in os.listdir(images_dir)]
random.seed(603)
random.shuffle(image_files)
# 計算集合大小
total = len(image_files)
train_size = int(total * train_ratio)
val_size = int(total * val_ratio)
print('train:', train_size, 'val:', val_size, 'test:', total-train_size-val_size)
# 分割數據集
train_files = image_files[:train_size]
val_files = image_files[train_size:train_size + val_size]
test_files = image_files[train_size + val_size:]
# 移動文件
for subset, files in [('train', train_files), ('val', val_files), ('test', test_files)]:
for file in files:
# images
src_img = os.path.join(images_dir, file)
dst_img = os.path.join(f"{base_dir}/{subset}/images", file)
shutil.copy(src_img, dst_img)
# labels
label_file = file.rsplit('.', 1)[0] + '.txt'
src_label = os.path.join(labels_dir, label_file)
dst_label = os.path.join(f"{base_dir}/{subset}/labels", label_file)
shutil.copy(src_label, dst_label)
# 寫入data.yaml
yaml= 'data/data.yaml'
with open(yaml, 'w') as f:
f.write(f"""
train: ../data/train
val: ../data/val
test: ../data/test
nc: 3
names: ['without_mask', 'mask_weared_incorrect', 'with_mask']
""")
# Commented out IPython magic to ensure Python compatibility.
# 下載YOLOv7
!git clone https://github.com/WongKinYiu/yolov7
# %cd yolov7/
!pip install -r requirements.txt
# Commented out IPython magic to ensure Python compatibility.
# %cd yolov7
# 模型訓練
!python train.py --img 640 \
--batch 16 \
--epochs 80 \
--data ../data/data.yaml \
--cfg cfg/training/yolov7.yaml \
--weights yolov7.pt \
--name results \
--device 0 \
# Commented out IPython magic to ensure Python compatibility.
# 模型測試
# %cd yolov7
!python test.py --data ../data/data.yaml\
--weights runs/train/results/weights/best.pt\
--batch-size 4\
--conf 0.2\
--img-size 640\
--task test