人脸检测与识别:AlexNet人脸检测

最终目标:为课题组做一个人脸打卡系统。

项目1阶段已更新完毕,如有错误请不吝赐教~

注:作为一个负责任的博主,虽然过了好几个月了,但必须要说明一下,文中代码有bug,cv2.resize时,参数输入是 宽×高×通道。

遂在inference做高斯金字塔的代码中:scale_img=cv2.resize(img,((int(img.shape[0]*scale)),(int(img.shape[1]*scale))))

更改为:scale_img=cv2.resize(img,((int(img.shape[1]*scale)),(int(img.shape[0]*scale))))。

同时作为一个懒惰的博主,这只是个入门,弄着玩的所以懒得再把测试的地方重新修改博客了,反正修改bug后结果是挺好的。

2019.3.20

 

项目1阶段:基于Alexnet的人脸检测

项目环境及配置:Window10+GTX 1060+Python3.6+Anaconda5.2.0+Tensorflow1.9+gpu

 

1、数据获取

人脸数据网上的资源非常非常的多,如下附上了几个获取数据的网站。在下载和查找数据的时候需要同时百度一下这个数据的使用方法,如:原始图片在哪,含有标注的.txt文件或.mat文件都在哪等,否则自己瞎搞很容易浪费时间。

这两个链接包含了大多数开源的人脸数据

http://www.cvmart.net/community/article/detail/148

https://blog.csdn.net//chenriwei2/article/details/50631212

项目1阶段训练与验证使用的人脸数据集均为AFLW,如下可下载,其中aflw-images-0.tar.gz,aflw-images-2.tar.gz,aflw-images-3.tar.gz这三个文件是图片数据,windows下解压的时候把后面那个.gz删掉就可以解压了。AFLW的标注在aflw/data下的aflw.txt文件。至于标注的格式我认为是矩形框的左上角x、y坐标值和长度w高度h。

AFLW:https://pan.baidu.com/s/14McWGRZCnOcP2SBhK2ryrQ

非人脸数据截取于人脸数据,具体截取代码见后文。

 

2、数据集制作

本项目数据集使用Tensorflow的TFRecord格式,比较方便。

首先要从ALFW数据集种截取出人脸图片和非人脸图片,ALFW总共有21123张图片。25000多张人脸,我要做出人脸和非人脸数据训练集规模1:3,5W人脸对15万非人脸,测试集规模1:1,2W人脸和2万非人脸,此程序运行完人脸图片可得到7.2W张左右,非人脸可得到17.2W张左右。

正常的流程此时需要引入IoU的概念。

IoU代码如下:

def IoU(box,boxes):
    
    """
    box为实际,boxes为人脸
    """
    face_area=boxes[:,2]*boxes[:,3]
    actual_area=(box[2]-box[0])**2
    
    x1=np.maximum(box[0],boxes[:,0])
    y1=np.maximum(box[1],boxes[:,1])    
    x2=np.minimum(box[2],boxes[:,2]+boxes[:,0])
    y2=np.minimum(box[3],boxes[:,3]+boxes[:,1]) 
    
    w=np.maximum(0,x2-x1+1)
    h=np.maximum(0,y2-y1+1)
    
    inter_area=w*h
    
    return inter_area/(face_area+actual_area-inter_area)

由于ALFW的标注非常烦人,一张图片内有几张人脸,可是他的标注是一个个给出的,还好一张图片的几乎都是挨着的,运行了3638.5秒,设定的阈值IoU<0.3为非人脸样本,IoU>0.65为人脸样本。

制作数据集代码如下:

import os
import cv2
import time
import numpy as np
from numpy.random import randint
import random


def gen_pic(path,boxes,j,k):
        
    img=cv2.imread(path)
    if img is None:
        return j,k
    h1,w1,_=img.shape
    if(min(w1,h1)<=210):
        return j,k
    
    num=8
    while(num):
        size=randint(100,min(w1,h1)/2)
        x1=randint(1,w1-size)
        y1=randint(1,h1-size)
        box=np.array([x1,y1,x1+size,y1+size])
        _boxes=boxes.copy()
        if(np.max(IoU(box,np.array(_boxes)))<0.3):
            resize_img=cv2.resize(img[y1:y1+size,x1:x1+size,:],(224,224))
            cv2.imwrite('E:\\friedhelm\\Data\\Alexnet_data\\non-face\\non_face_%d.jpg'%(j),resize_img)            
            j=j+1
            num=num-1

    for bbox in boxes:
        x=max(bbox[0],0)
        y=max(bbox[1],0)
        w=max(bbox[2],0)
        h=max(bbox[3],0)
        num=2 
        while(num):

            size=randint(np.floor(0.5*min(w,h))+1,np.ceil(1.5*max(w,h))+2)
            x1=randint(np.floor(0.5*x)+1,np.ceil(1.5*x)+2)
            y1=randint(np.floor(0.5*y)+1,np.ceil(1.5*y)+2)
            box=np.array([x1,y1,x1+size,y1+size])

            _bbox=np.array(bbox).reshape(1,-1)
            if(IoU(box,_bbox)>0.65):
                resize_img=cv2.resize(img[y1:y1+size,x1:x1+size,:],(224,224))
                cv2.imwrite('E:\\friedhelm\\Data\\Alexnet_data\\face\\face_%d.jpg'%(k),resize_img)            
                k=k+1

                if(random.choice([0,1])):
                    resize_img=cv2.flip(resize_img,1)
                    cv2.imwrite('E:\\friedhelm\\Data\\Alexnet_data\\face\\face_%d.jpg'%(k),resize_img)             
                    k=k+1
                num=num-1  
    return j,k

def IoU(box,boxes):
    
    """
    box为实际,boxes为人脸
    """
    face_area=boxes[:,2]*boxes[:,3]
    actual_area=(box[2]-box[0])**2
    
    x1=np.maximum(box[0],boxes[:,0])
    y1=np.maximum(box[1],boxes[:,1])    
    x2=np.minimum(box[2],boxes[:,2]+boxes[:,0])
    y2=np.minimum(box[3],boxes[:,3]+boxes[:,1]) 
    
    w=np.maximum(0,x2-x1+1)
    h=np.maximum(0,y2-y1+1)
    
    inter_area=w*h
    
    return inter_area/(face_area+actual_area-inter_area)

def main():
    
    begin=time.time()
    addr='E:\\friedhelm\\AFLW\\'
    with open(r'E:\friedhelm\alfw.txt') as f:
        j=0
        k=0
        boxes=[]
        path_compare="1"
        for line in f.readlines():
            line=line.strip().split()
            path=addr+line[0]
            x=int(line[1])
            if x<0:x=0
            y=int(line[2])
            if y<0:y=0
            w=int(line[3])
            h=int(line[4])

            if(path_compare==path):
                boxes.append([x,y,w,h])
            else:
                if(path_compare!="1"):
                    j,k=gen_
  • 3
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值