深度学习DFace框架和视频人脸检测

一、准备工作

1.Anaconda3环境:pytorch-gpu

CUDA:8.0 
cuDNN:5.1 
环境配置请参考https://blog.csdn.net/hhy_csdn/article/details/82263078

二、修改代码

激活环境

activate pytorch-gpu
  • 1

运行test_image.py,执行python test_image.py 
出现bug

Traceback (most recent call last):
  File "test_image.py", line 20, in <module>
    bboxs, landmarks = mtcnn_detector.detect_face(img)
  File "K:\Desktop\face_detect\DFace-win64\src\core\detect.py", line 602, in detect_face
    boxes, boxes_align = self.detect_pnet(img)
  File "K:\Desktop\face_detect\DFace-win64\src\core\detect.py", line 263, in detect_pnet
    cls_map, reg = self.pnet_detector(feed_imgs)
  File "D:\Program Files\Anaconda3\envs\pytorch-gpu\lib\site-packages\torch\nn\modules\module.py", line 325, in __call__
    result = self.forward(*input, **kwargs)
  File "K:\Desktop\face_detect\DFace-win64\src\core\models.py", line 97, in forward
    x = self.pre_layer(x)
  File "D:\Program Files\Anaconda3\envs\pytorch-gpu\lib\site-packages\torch\nn\modules\module.py", line 325, in __call__
    result = self.forward(*input, **kwargs)
  File "D:\Program Files\Anaconda3\envs\pytorch-gpu\lib\site-packages\torch\nn\modules\container.py", line 67, in forward
    input = module(input)
  File "D:\Program Files\Anaconda3\envs\pytorch-gpu\lib\site-packages\torch\nn\modules\module.py", line 325, in __call__
    result = self.forward(*input, **kwargs)
  File "D:\Program Files\Anaconda3\envs\pytorch-gpu\lib\site-packages\torch\nn\modules\conv.py", line 277, in forward
    self.padding, self.dilation, self.groups)
  File "D:\Program Files\Anaconda3\envs\pytorch-gpu\lib\site-packages\torch\nn\functional.py", line 90, in conv2d
    return f(input, weight, bias)
RuntimeError: Input type (CUDADoubleTensor) and weight type (CUDAFloatTensor) should be the same

说的是detect.py某处的数据类型不匹配,也就是说,输入的image是double类型的,但模型文件的权重都是float类型的。通过反复排查,问题出在./src/core/detect.py的255行。只需要做这样的修改:

255行
feed_imgs.append(image_tensor)改成
feed_imgs.append(image_tensor.float())

394行
cls_map, reg = self.rnet_detector(feed_imgs)改成
cls_map, reg = self.rnet_detector(feed_imgs.float())

514行
cls_map, reg, landmark = self.onet_detector(feed_imgs)改成
cls_map, reg, landmark = self.onet_detector(feed_imgs.float())

image_tensor强制转化为float类型,就好了。

重新运行,又出现bug 这个错误是说,在画Bounding Box的时候,bbox的高和宽都负数。。。。 

经过两个通宵的排查,最后发现问题出在另一个文件./src/core/image_tools.py的第20行。 
image_tools.py的一部分长这个样子。

import torchvision.transforms as transforms
import torch
from torch.autograd.variable import Variable
import numpy as np

transform = transforms.ToTensor()

def convert_image_to_tensor(image):
    """convert an image to pytorch tensor

        Parameters:
        ----------
        image: numpy array , h * w * c

        Returns:
        -------
        image_tensor: pytorch.FloatTensor, c * h * w
        """
    image = image.astype(np.float)
    return transform(image)
    # return transform(image)

网上查到说ToTensor()这个函数可以把shape=(H x W x C)的像素值范围为[0, 255]的PIL.Image或者numpy.ndarray转换成shape=(C x H x W)的像素值范围为[0.0, 1.0]的torch.FloatTensor。 
但是我把transform(image)的值打印出来,发现依然是[0,255],估计模型文件中都是[0,1]的数据分布,所以把bbox的结果算错了。 
在函数的最后改成return transform(image)/255

 

这下终于好了。 
这里写图片描述

PS:我在另一台电脑重复了这个操作,同样的环境和pytorch版本,但是ToTensor()的返回值就是[0,1],所以就不存在ValueError: negative dimensions are not allowed,真是邪了门了。所以在debug时,可以先看一下image_tools.py里面到底正常不正常。

三、视频检测

不再使用自带的vision.py文件进行可视化,而是利用OpenCV。 对test_image.py进行修改,完整的代码是这样的。

import cv2
from src.core.detect import create_mtcnn_net, MtcnnDetector
import src.core.vision as vision
import torch
import numpy as np


if __name__ == '__main__':


    p_model_path = "./model_store/pnet_epoch.pt"
    r_model_path = "./model_store/rnet_epoch.pt"
    o_model_path = "./model_store/onet_epoch.pt"
    video_path = "./2.jpg"
    pnet, rnet, onet = create_mtcnn_net(p_model_path, r_model_path, o_model_path, use_cuda=True)
    mtcnn_detector = MtcnnDetector(pnet=pnet, rnet=rnet, onet=onet, min_face_size=24)
    # 启用摄像头,可以改成视频的路径
    cap = cv2.VideoCapture(0)
    while cap.isOpened():
        # 逐帧捕获
        ret, frame = cap.read()
        bboxs = mtcnn_detector.detect_face(frame)
        # print(type(bboxs),bboxs[0],bboxs[1])
        # bboxs = bboxs.tolist()

        # mtcnn_detector检测不到人脸就会返回一个空的元组,所以加if判断,在不是元组的情况下,才画bbox
        if not isinstance(bboxs,tuple):
            bboxs = np.round(bboxs).astype('int32')
            # print(bboxs)
            for i in range(0,int(np.shape(bboxs)[0])):
                cv2.rectangle(frame,(bboxs[i,0],bboxs[i,1]),(bboxs[i,2],bboxs[i,3]),(55,255,155),3)
        cv2.imshow('video_face_detect',frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    # 一切完成后,释放捕获
    cap.release()
    cv2.destroyAllWindows()
 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
----------------- # DFace • [![License](http://pic.dface.io/apache2.svg)](https://opensource.org/licenses/Apache-2.0) | **`Linux CPU`** | **`Linux GPU`** | **`Mac OS CPU`** | **`Windows CPU`** | |-----------------|---------------------|------------------|-------------------| | [![Build Status](http://pic.dface.io/pass.svg)](http://pic.dface.io/pass.svg) | [![Build Status](http://pic.dface.io/pass.svg)](http://pic.dface.io/pass.svg) | [![Build Status](http://pic.dface.io/pass.svg)](http://pic.dface.io/pass.svg) | [![Build Status](http://pic.dface.io/pass.svg)](http://pic.dface.io/pass.svg) | **基于多任务卷积网络(MTCNN)和Center-Loss的多人实时人脸检测和人脸识别系统。** [Github项目地址](https://github.com/kuaikuaikim/DFace) [Slack 聊天组](https://dfaceio.slack.com/) **DFace** 是个开源的深度学习人脸检测和人脸识别系统。所有功能都采用 **[pytorch](https://github.com/pytorch/pytorch)** 框架开发。pytorch是一个由facebook开发的深度学习框架,它包含了一些比较有趣的高级特性,例如自动求导,动态构图等。DFace天然的继承了这些优点,使得它的训练过程可以更加简单方便,并且实现的代码可以更加清晰易懂。 DFace可以利用CUDA来支持GPU加速模式。我们建议尝试linux GPU这种模式,它几乎可以实现实时的效果。 所有的灵感都来源于学术界最近的一些研究成果,例如 [Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks](https://arxiv.org/abs/1604.02878) 和 [FaceNet: A Unified Embedding for Face Recognition and Clustering](https://arxiv.org/abs/1503.03832) **MTCNN 结构**   ![mtcnn](http://affluent.oss-cn-hangzhou.aliyuncs.com/html/images/mtcnn_st.png) ** 如果你对DFace感兴趣并且想参与到这个项目中, 以下TODO是一些需要实现的功能,我定期会更新,它会实时展示一些需要开发的清单。提交你的fork request,我会用issues来跟踪和反馈所有的问题。也可以加DFace的官方Q群 681403076 也可以加本人微信 jinkuaikuai005 ** ### TODO(需要开发的功能) - 基于center loss 或者triplet loss原理开发人脸对比功能,模型采用ResNet inception v2. 该功能能够比较两张人脸图片的相似性。具体可以参考 [Paper](https://arxiv.org/abs/1503.03832)和[FaceNet](https://github.com/davidsandberg/facenet) - 反欺诈功能,根据光线,质地等人脸特性来防止照片攻击,视频攻击,回放攻击等。具体可参考LBP算法和SVM训练模型。 - 3D人脸反欺诈。 - mobile移植,根据ONNX标准把pytorch训练好的模型迁移到caffe2,一些numpy算法改用c++实现。 - Tensor RT移植,高并发。 - Docker支持,gpu版 ## 安装 DFace主要有两大模块,人脸检测和人脸识别。我会提供所有模型训练和运行的详细步骤。你首先需要构建一个pytorch和cv2的python环境,我推荐使用Anaconda来设置一个独立的虚拟环境。目前作者倾向于Linux Ubuntu安装环境。感谢山东一位网友提供windows DFace安装体验,windos安装教程具体 可参考他的[博客](http://www.alearner.top/index.php/2017/12/23/dface-pytorch-win64-gpu) ### 依赖 * cuda 8.0 * anaconda * pytorch * torchvision * cv2 * matplotlib ```shell git clone https://gitee.com/kuaikuaikim/dface.git ``` 在这里我提供了一个anaconda的环境依赖文件environment.yml (windows请用environment-win64.yml),它能方便你构建自己的虚拟环境。 ```shell cd dface conda env create -f environment.yml ``` 添加python搜索模块路径 ```shell export PYTHONPATH=$PYTHONPATH:{your local DFace root path} ``` ### 人脸识别和检测 如果你对mtcnn模型感兴趣,以下过程可能会帮助到你。 #### 训练mtcnn模型 MTCNN主要有三个网络,叫做**PNet**, **RNet** 和 **ONet**。因此我们的训练过程也需要分三步先后进行。为了更好的实现效果,当前被训练的网络都将依赖于上一个训练好的网络来生成数据。所有的人脸数据集都来自 **[WIDER FACE](http://mmlab.ie.cuhk.edu.hk/projects/WIDERFace/)** 和 **[CelebA](http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html)**。WIDER FACE仅提供了大量的人脸边框定位数据,而CelebA包含了人脸关键点定位数据。以下训练除了 生成ONet的人脸关键点训练数据和标注文件 该步骤使用CelebA数据集,其他一律使用WIDER FACE。如果使用wider face的 wider_face_train.mat 注解文件需要转换成txt格式的,我这里用h5py写了个 [转换脚本](https://gitee.com/kuaikuaikim/dface/blob/master/dface/prepare_data/widerface_annotation_gen/transform.py). 这里我提供一个已经转换好的wider face注解文件 [anno_store/wider_origin_anno.txt](https://gitee.com/kuaikuaikim/dface/blob/master/anno_store/wider_origin_anno.txt), 以下训练过程参数名--anno_file默认就是使用该转换好的注解文件。 * 创建 dface 训练数据临时目录,对应于以下所有的参数名 --dface_traindata_store ```shell mkdir {your dface traindata folder} ``` * 生成PNet训练数据和标注文件 ```shell python dface/prepare_data/gen_Pnet_train_data.py --prefix_path {注解文件中图片的目录前缀,就是wider face图片所在目录} --dface_traindata_store {之前创建的dface训练数据临时目录} --anno_file {wider face 注解文件,可以不填,默认使用anno_store/wider_origin_anno.txt} ``` * 乱序合并标注文件 ```shell python dface/prepare_data/assemble_pnet_imglist.py ``` * 训练PNet模型 ```shell python dface/train_net/train_p_net.py ``` * 生成RNet训练数据和标注文件 ```shell python dface/prepare_data/gen_Rnet_train_data.py --prefix_path {注解文件中图片的目录前缀,就是wider face图片所在目录} --dface_traindata_store {之前创建的dface训练数据临时目录} --anno_file {wider face 注解文件,可以不填,默认使用anno_store/wider_origin_anno.txt} --pmodel_file {之前训练的Pnet模型文件} ``` * 乱序合并标注文件 ```shell python dface/prepare_data/assemble_rnet_imglist.py ``` * 训练RNet模型 ```shell python dface/train_net/train_r_net.py ``` * 生成ONet训练数据和标注文件 ```shell python dface/prepare_data/gen_Onet_train_data.py --prefix_path {注解文件中图片的目录前缀,就是wider face图片所在目录} --dface_traindata_store {之前创建的dface训练数据临时目录} --anno_file {wider face 注解文件,可以不填,默认使用anno_store/wider_origin_anno.txt} --pmodel_file {之前训练的Pnet模型文件} --rmodel_file {之前训练的Rnet模型文件} ``` * 生成ONet的人脸五官关键点训练数据和标注文件 ```shell python dface/prepare_data/gen_landmark_48.py ``` * 乱序合并标注文件(包括人脸五官关键点) ```shell python dface/prepare_data/assemble_onet_imglist.py ``` * 训练ONet模型 ```shell python dface/train_net/train_o_net.py ``` #### 测试人脸检测 ```shell python test_image.py ``` ### 人脸对比 @TODO 根据center loss实现人脸识别 ## 测试效果 ![mtcnn](http://affluent.oss-cn-hangzhou.aliyuncs.com/html/images/dface_demoall.PNG) ### QQ交流群(模型获取请加群) #### 681403076 ![](http://affluent.oss-cn-hangzhou.aliyuncs.com/html/images/dfaceqqsm.png) #### 本人微信 ##### jinkuaikuai005 ![](http://affluent.oss-cn-hangzhou.aliyuncs.com/html/images/perqr.jpg) ## License [Apache License 2.0](LICENSE)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值