程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

戴口罩人臉檢測和戴口罩識別(含Python Android源碼)

編輯:Python

戴口罩人臉檢測和戴口罩識別(含Python Android源碼)

目錄

戴口罩人臉檢測和戴口罩識別(含Python Android源碼)

1.戴口罩識別的方法

(1)基於多類別目標檢測的戴口罩識別方法

(2)基於人臉檢測+戴口罩分類識別方法

2.戴口罩人臉數據集

3.戴口罩人臉檢測

4.戴口罩識別模型訓練

(1)准備數據

(2)戴口罩分類模型訓練(Pytorch)

(3) 可視化訓練過程

(4) 戴口罩識別效果

5.戴口罩識別模型Android部署

(1) 將Pytorch模型轉換ONNX模型

(2) 將ONNX模型轉換為TNN模型

(3) Android端上部署戴口罩識別

6.項目源碼下載


當前疫情反反復復,而防控新冠病毒的最有效手段之一就是戴口罩,因此研究戴口罩檢測和識別具有重大意義。疫情防控,人人有責,作為一名程序狗,分享一下鄙人開發的戴口罩人臉檢測和戴口罩識別方法。目前項目開發的戴口罩識別(face-mask recognition)的准確率還挺高的,在resnet50,可以高達99%的准確率,即使采用輕量化版本MobileNet-v2,准確率也可以高達98.18%左右。

本項目將手把手教你訓練一個戴口罩分類識別模型,包括如何轉為ONNX,TNN模型,並移植到Android上進行部署,實現一個戴口罩識別的Android Demo APP 。數據和源碼都已備好了,准備好上船吧~

Demo效果展示: 

圖片測試視頻測試
  1. 戴口罩人臉檢測和戴口罩識別Android Demo APP免費體檢:https://download.csdn.net/download/guyuealian/85771596
  2. 戴口罩人臉檢測和戴口罩識別整套項目(含數據,訓練代碼,Android源碼):戴口罩人臉檢測和戴口罩識別(含Python Android源碼)

整套項目項目,支持的主要內容主要有:

  1. 包含5個數據集:  facemask-train1,  facemask-train2,facemask-train3,  synthetic-train1,synthetic-train2 ,facemask-test ,總共約有50000+的數據:
  2. 生成戴口罩人臉代碼: python create_facemask.py
  3. 支持戴口罩人臉檢測
  4. 支持戴口罩識別:mask(戴口罩)和nomask(未佩戴口罩)
  5. 提供戴口罩識別Python Demo源碼,在普通電腦CPU/GPU上可以實時檢測和識別
  6. 提供戴口罩識別Android Demo源碼,在普通手機CPU/GPU上可以實時檢測和識別,約30ms左右

1.戴口罩識別的方法

(1)基於多類別目標檢測的戴口罩識別方法

基於多類別目標檢測的戴口罩識別方法,一步到位,把未戴口罩(nomask)和戴口罩(mask)兩個類別直接當成兩個目標檢測的類別進行訓練

  • 優點:直接端到端訓練,任務簡單,速度快
  • 缺點:需要人工標注人臉框mask和nomask,時間花費比較大;訓練數據不足的情況下,容易出現誤檢測的情況

(2)基於人臉檢測+戴口罩分類識別方法

該方法,先采用通用的人臉檢測模型,進行人臉檢測,然後裁剪人臉區域,再訓練一個戴口罩分類器,對人臉進行分類識別(未戴口罩和戴口罩)

  • 優點:不需要標注人臉框數據,可以自己合成戴口罩人臉數據,人工成本低;精度高,可針對分類模型進行輕量化
  • 缺點:需要部署兩個模型(人臉檢測模型和戴口罩分類模型),人臉越多,速度越慢

考慮到數據標注成本的問題,本項目采用第二種方法,即采用基於人臉檢測+戴口罩分類識別方法


2.戴口罩人臉數據集

網上絕大部分人臉數據都是不戴口罩的人臉,不能直接用於戴口罩識別中。鑒於此,我們可以考慮自己合成/生成戴口罩的人臉數據,以下是鄙人收藏和整理的戴口罩人臉數據集和合成的數據集,總共約有50000+的數據:

原始圖片生成戴口罩人臉

 關於戴口罩人臉數據和生成方法,詳細使用說明請參考我的一篇博客《戴口罩人臉數據集和戴口罩人臉生成方法》

數據集說明facemask-train1
  • 從網上收集的戴口罩人臉數據集(如virus-mask-dataset),約7000+張圖片,並清洗了部分標注錯誤的樣本
  • 每張圖片都被標注了mask(戴口罩)和nomask(未佩戴口罩)的檢測框
  • 標注格式為標准的VOC xml格式,可用於人臉檢測訓練數據使用
  • 已經裁剪了人臉區域,並清洗了部分標注錯誤的樣本;其中mask(戴口罩)人臉有3000+張,nomask(未佩戴口罩)人臉有10000+張,可作為分類訓練數據集,
facemask-train2
  • 從網上收集的戴口罩人臉數據集,約3500+張圖片,
  • 每張圖片都被標注了mask(戴口罩)和nomask(未佩戴口罩)的檢測框
  • 標注格式為標准的VOC格式,但標注的人臉框比較大,不建議用於人臉檢測訓練數據使用
  • 已經裁剪了人臉區域圖像,並清洗了部分標注錯誤的樣本;其中mask(戴口罩)人臉有2000+張,nomask(未佩戴口罩)人臉有6000+張,可作為分類訓練數據集
facemask-train3
  • 從網上收集的戴口罩人臉數據集,其中mask(戴口罩)人臉有600+張,nomask(未佩戴口罩)人臉有1700+張,可作為分類訓練數據集
  • 原始圖片都被裁剪為人臉圖像了,所以不合適用於人臉檢測;可作為分類訓練數據集
synthetic-train1
  • 這是合成的戴口罩人臉數據
  • 其中mask(戴口罩)人臉有7000+張,nomask(未佩戴口罩)人臉有7000+張,可作為分類訓練數據集
synthetic-train2
  • 這是合成的戴口罩人臉數據
  • 其中mask(戴口罩)人臉有6000+張,nomask(未佩戴口罩)人臉有6000+張,可作為分類訓練數據集
facemask-test
  • 這是戴口罩人臉測試集
  • 其中mask(戴口罩)人臉有300+張,nomask(未佩戴口罩)人臉有300+張,用於分類模型測試

3.戴口罩人臉檢測

通常我們理解的人臉檢測是指沒有遮擋或者只有少許遮擋情況下的人臉檢測,當人臉戴有口罩,其檢測效果勢必會變得比較差,而大量標注帶有人臉口罩的人臉數據集還是比較耗時費力的。所以我的方法是:

先在WiderFace人臉數據集上,訓練人臉檢測;然後在facemask-train1數據集finetune人臉檢測模型,經過這個方法訓練後,其戴口罩檢測效果會好很多。

當然,即使使用開源的人臉檢測算法,在帶有口罩人臉檢測,其實效果也不會太差,比如使用FaceBox,MTCNN檢測帶有口罩的圖片,效果也可以的,只不過會經常出現人臉檢測框不完整,存在缺少等問題,對後續的戴口罩的識別有一定的影響。

關於人臉檢測的方法,可以參考我的另一篇博客:

又快又好,行人檢測和人臉檢測和人臉關鍵點檢測(C++/Android源碼)_pan_jinquan的博客-CSDN博客考慮到人臉人體檢測的需求,本人開發了一套輕量化的,高精度的,可實時的人臉/人體檢測Android Demo,主要支持功能如下:支持人臉檢測算法模型支持人臉檢測和人臉關鍵點檢測(5個人臉關鍵點)算法模型支持人體檢測(行人檢測)算法模型支持人臉和人體同時檢測算法模型所有算法模型都使用C++開發,推理框架采用TNN,Android通過JNI接口進行算法調用;所有算法模型都可在普通Android手機實時跑,在普通Android手機,CPU和GPU都可以達到實時檢測的效果(CPU約25毫秒左右,GPU約1https://panjinquan.blog.csdn.net/article/details/125348189


4.戴口罩識別模型訓練

本項目將手把手教你訓練一個戴口罩分類識別模型,包括如何轉為ONNX,TNN模型,並移植到
Android上進行部署,實現一個戴口罩識別的Android APP Demo

整套工程項目基本結構如下:

.
├── classifier                 # 訓練模型相關工具
├── configs                    # 訓練配置文件
├── data                      # 訓練數據
├── libs           
│   ├── convert                     # 將模型轉換為ONNX工具
│   ├── facemask                    # 戴口罩人臉數據生成工具
│   ├── light_detector              # 人臉檢測
│   ├── create_facemask.py  #  戴口罩人臉數據生成demo
│   ├── detector.py                 #  人臉檢測demo
│   └── README.md               
├── demo.py              # 戴口罩人臉識別demo
├── README.md            # 項目工程說明文檔
├── requirements.txt    # 項目相關依賴包
└── train.py             # 訓練文件

(1)准備數據

總共有5個數據集,包括 facemask-train1,  facemask-train2,facemask-train3,synthetic-train1,synthetic-train2 ,facemask-test ,總共約有50000+的數據。

 當然,你也可以使用自己的數據集,數據結構如下,其中mask目錄存放戴口罩的人臉圖片,而nomask目錄存放未戴口罩的人臉圖像。

(2)戴口罩分類模型訓練(Pytorch)

鄙人在《Pytorch基礎訓練庫Pytorch-Base-Trainer(支持模型剪枝 分布式訓練)》基礎上實現了戴口罩和未佩戴口罩二分類識別訓練和測試,整套訓練代碼非常簡單操作,用戶只需要將相同類別的數據放在同一個目錄下,並填寫好對應的數據路徑,即可開始訓練了。

訓練框架采用Pytorch,整套訓練代碼支持的內容主要有:

  • 目前支持的backbone有:googlenet,resnet[18,34,50], ,mobilenet_v2等, 其他backbone可以自定義添加
  • 訓練參數可以通過(configs/config.yaml)配置文件進行設置

訓練參數說明如下:

# 設置訓練數據集,支持多個訓練數據集
train_data:
- 'dataset/face_mask/facemask-train1/crops'
- 'dataset/face_mask/facemask-train2/crops'
- 'dataset/face_mask/facemask-train3/crops'
- 'dataset/face_mask/synthetic-train1/crops'
- 'dataset/face_mask/synthetic-train1/crops'
# 設置測試數據集
test_data: 'dataset/face_mask/facemask-test/crops'
class_name: 'dataset/face_mask/class_name.txt' # 類別標簽
train_transform: "train" # 訓練使用的數據增強方法
test_transform: "val" # 測試使用的數據增強方法
work_dir: "work_space/" # 保存輸出模型的目錄
net_type: "mobilenet_v2" # 骨干網絡,支持:resnet18,mobilenet_v2,googlenet
resample: True # 進行樣本均衡
width_mult: 1.0
input_size: [ 128,128 ]
rgb_mean: [ 0.5, 0.5, 0.5 ] # for normalize inputs to [-1, 1],Sequence of means for each channel.
rgb_std: [ 0.5, 0.5, 0.5 ] # for normalize,Sequence of standard deviations for each channel.
batch_size: 64
lr: 0.01 # 初始學習率
optim_type: "SGD" # 選擇優化器,SGD,Adam
loss_type: "LabelSmoothing" # 選擇損失函數:支持CrossEntropyLoss,LabelSmoothing
momentum: 0.9 # SGD momentum
num_epochs: 100 # 訓練循環次數
num_warn_up: 3 # warn-up次數
num_workers: 8 # 加載數據工作進程數
weight_decay: 0.0005 # weight_decay,默認5e-4
scheduler: "multi-step" # 學習率調整策略
milestones: [ 20,50,80 ] # 下調學習率方式
gpu_id: [ 0 ] # GPU ID
log_freq: 50 # LOG打印頻率
progress: True # 是否顯示進度條
pretrained: False # 是否使用pretrained模型
finetune: False # 是否進行finetune

開始訓練: 

python train.py -c configs/config.yaml

訓練完成後,訓練集的Accuracy在99%以上,測試集的Accuracy在98%左右

(3) 可視化訓練過程

訓練過程可視化工具是使用Tensorboard,使用方法:
# 基本方法
tensorboard --logdir=path/to/log/
# 例如
tensorboard --logdir=work_space/mobilenet_v2_1.0_CrossEntropyLoss/log

可視化效果 

(4) 戴口罩識別效果

5.戴口罩識別模型Android部署

(1) 將Pytorch模型轉換ONNX模型

訓練好Pytorch模型後,你可以將模型轉換為ONNX模型,方便後續模型部署

python libs/convert/convert_torch_to_onnx.py
"""
This code is used to convert the pytorch model into an onnx format model.
"""
import sys
import os
sys.path.insert(0, os.getcwd())
import torch.onnx
import onnx
from classifier.models.build_models import get_models
from basetrainer.utils import torch_tools
def build_net(model_file, net_type, input_size, num_classes, width_mult=1.0):
"""
:param model_file: 模型文件
:param net_type: 模型名稱
:param input_size: 模型輸入大小
:param num_classes: 類別數
:param width_mult:
:return:
"""
model = get_models(net_type, input_size, num_classes, width_mult=width_mult, is_train=False, pretrained=False)
state_dict = torch_tools.load_state_dict(model_file)
model.load_state_dict(state_dict)
return model
def convert2onnx(model_file, net_type, input_size, num_classes, width_mult=1.0, device="cpu", onnx_type="default"):
model = build_net(model_file, net_type, input_size, num_classes, width_mult=width_mult)
model = model.to(device)
model.eval()
model_name = os.path.basename(model_file)[:-len(".pth")] + ".onnx"
onnx_path = os.path.join(os.path.dirname(model_file), model_name)
# dummy_input = torch.randn(1, 3, 240, 320).to("cuda")
dummy_input = torch.randn(1, 3, input_size[1], input_size[0]).to(device)
# torch.onnx.export(model, dummy_input, onnx_path, verbose=False,
# input_names=['input'],output_names=['scores', 'boxes'])
do_constant_folding = True
if onnx_type == "default":
torch.onnx.export(model, dummy_input, onnx_path, verbose=False, export_params=True,
do_constant_folding=do_constant_folding,
input_names=['input'],
output_names=['output'])
elif onnx_type == "det":
torch.onnx.export(model,
dummy_input,
onnx_path,
do_constant_folding=do_constant_folding,
export_params=True,
verbose=False,
input_names=['input'],
output_names=['scores', 'boxes', 'ldmks'])
elif onnx_type == "kp":
torch.onnx.export(model,
dummy_input,
onnx_path,
do_constant_folding=do_constant_folding,
export_params=True,
verbose=False,
input_names=['input'],
output_names=['output'])
onnx_model = onnx.load(onnx_path)
onnx.checker.check_model(onnx_model)
print(onnx_path)
if __name__ == "__main__":
net_type = "mobilenet_v2"
width_mult = 1.0
input_size = [128, 128]
num_classes = 2
model_file = "work_space/mobilenet_v2_1.0_CrossEntropyLoss/model/best_model_022_98.1848.pth"
convert2onnx(model_file, net_type, input_size, num_classes, width_mult=width_mult)

(2) 將ONNX模型轉換為TNN模型

目前CNN模型有多種部署方式,可以采用TNN,MNN,NCNN,以及TensorRT等部署工具,鄙人采用TNN進行Android端上部署:

將ONNX模型轉換為TNN模型,請參考TNN官方說明:

TNN/onnx2tnn.md at master · Tencent/TNN · GitHub

(3) Android端上部署戴口罩識別

項目實現了Android版本的戴口罩識別Demo,部署框架采用TNN,支持多線程CPU和GPU加速推理,在普通手機上可以實時處理。戴口罩識別Android源碼,核心算法均采用C++實現,上層通過JNI接口調用.

如果你想在這個Android Demo部署你自己訓練的分類模型,你可將訓練好的Pytorch模型轉換ONNX ,再轉換成TNN模型,然後把TNN模型代替你模型即可。

package com.cv.tnn.model;
import android.graphics.Bitmap;
public class Detector {
static {
System.loadLibrary("tnn_wrapper");
}
/***
* 初始化人臉檢測和戴口罩識別模型
* @param face_model: 人臉檢測模型(不含後綴名)
* @param class_model:戴口罩識別模型(不含後綴名)
* @param root:模型文件的根目錄,放在assets文件夾下
* @param model_type:模型類型
* @param num_thread:開啟線程數
* @param useGPU:關鍵點的置信度,小於值的坐標會置-1
*/
public static native void init(String face_model, String class_model, String root, int model_type, int num_thread, boolean useGPU);
/***
* 人臉檢測和戴口罩識別
* @param bitmap 圖像(bitmap),ARGB_8888格式
* @param score_thresh:置信度阈值
* @param iou_thresh: IOU阈值
* @return
*/
public static native FrameInfo[] detect(Bitmap bitmap, float score_thresh, float iou_thresh);
}

6.項目源碼下載

整套項目源碼內容包含:

  1. 包含5個數據集:  facemask-train1,  facemask-train2,facemask-train3,  synthetic-train1,synthetic-train2 ,facemask-test ,總共約有50000+的數據:
  2. 生成戴口罩人臉代碼: python create_facemask.py
  3. 戴口罩分類模型訓練和測試代碼 Pytorch版本,測試Demo在普通電腦CPU/GPU上可以實時檢測和識別
  4. 戴口罩識別Android Demo源碼,支持CPU和GPU,在普通手機上可以實時檢測和識別,約30ms左右
  1.  戴口罩人臉檢測和戴口罩識別Android Demo APP免費體檢:https://download.csdn.net/download/guyuealian/85771596
  2. 戴口罩人臉檢測和戴口罩識別整套項目(含數據,訓練代碼,Android源碼):戴口罩人臉檢測和戴口罩識別(含Python Android源碼)

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved