人脸识别0-06:insightFace-半监督系统搭建(1)-人脸检测

以下链接是个人关于insightFace所有见解,如有错误欢迎大家指出,我会第一时间纠正,如有兴趣可以加QQ:17575010159 相互讨论技术。
人脸识别0-00:insightFace目录:https://blog.csdn.net/weixin_43013761/article/details/99646731:
这是本人项目的源码:https://github.com/944284742/1.FaceRecognition
其中script目录下的文件为本人编写,主要用于适应自己的项目,可以查看该目录下的redeme文件。

系统搭建目的

做过深度学习的哥们应该都知道,收集数据的过程是十分复杂的,无论是手工标签,还是通过其他商家购买,都是十分消耗财力和人力的,为了人脸系统有足够的训练数据,所以我打算搭建这套系统,也分享给大家。这里的是半监督学习,也就是说,还是需要一些人力工作,才能维持该系统的正常运转。搭建这套系统之后,只需要包含人脸的图像就可以了,不需要做任何分类,标定,直接丢到该系统中,就能当作训练的数据(需要人进行小量的筛选)。下面我们就开始把。

人脸检测

假设,我们随便收集了一下,或者抓拍了一下包含人脸,也可能没有包含人脸的照片,那么我们首先是要把这些人脸的都截取出来,并且还要进行人脸矫正。编写insightface-master\src\align\align_my.py(在本人的源码中,作者的代码不知道如何就设置人脸矫正,所以自己重新改写了一下)脚本如下:

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from scipy import misc
import sys
import os
import argparse
import tensorflow as tf
import numpy as np
# import facenet
import detect_face
import random
from time import sleep

sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'common'))
import face_image
import src.common.face_preprocess as face_preprocess
from skimage import transform as trans
import cv2


def to_rgb(img):
    w, h = img.shape
    ret = np.empty((w, h, 3), dtype=np.uint8)
    ret[:, :, 0] = ret[:, :, 1] = ret[:, :, 2] = img
    return ret


def IOU(Reframe, GTframe):
    x1 = Reframe[0];
    y1 = Reframe[1];
    width1 = Reframe[2] - Reframe[0];
    height1 = Reframe[3] - Reframe[1];

    x2 = GTframe[0]
    y2 = GTframe[1]
    width2 = GTframe[2] - GTframe[0]
    height2 = GTframe[3] - GTframe[1]

    endx = max(x1 + width1, x2 + width2)
    startx = min(x1, x2)
    width = width1 + width2 - (endx - startx)

    endy = max(y1 + height1, y2 + height2)
    starty = min(y1, y2)
    height = height1 + height2 - (endy - starty)

    if width <= 0 or height <= 0:
        ratio = 0
    else:
        Area = width * height
        Area1 = width1 * height1
        Area2 = width2 * height2
        ratio = Area * 1. / (Area1 + Area2 - Area)
    return ratio
def list_image(root, recursive, exts):
    """Traverses the root of directory that contains images and
    generates image list iterator.
    Parameters
    ----------
    root: string
    recursive: bool
    exts: string
    Returns
    -------
    image iterator that contains all the image under the specified path
    """

    i = 0
    if recursive:
        cat = {}
        for path, dirs, files in os.walk(root, followlinks=True):
            dirs.sort()
            files.sort()
            for fname in files:
                fpath = os.path.join(path, fname)
                suffix = os.path.splitext(fname)[1].lower()
                if os.path.isfile(fpath) and (suffix in exts):
                    if path not in cat:
                        cat[path] = len(cat)
                    yield (i, os.path.relpath(fpath, root), cat[path])
                    i += 1
        for k, v in sorted(cat.items(), key=lambda x: x[1]):
            print(os.path.relpath(k, root), v)
    else:
        for fname in sorted(os.listdir(root)):
            fpath = os.path.join(root, fname)
            suffix = os.path.splitext(fname)[1].lower()
            if os.path.isfile(fpath) and (suffix in exts):
                yield (i, os.path.relpath(fpath, root), 0)
                i += 1

def main(args):
    imgs_info = list_image(args.indir, args.recursive, args.exts)

    print('Creating networks and loading parameters')

    with tf.Graph().as_default():
        # gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=args.gpu_memory_fraction)
        # sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
        sess = tf.Session()
        with sess.as_default():
            pnet, rnet, onet = detect_face.create_mtcnn(sess, None)

    minsize = 20
    threshold = [0.6, 0.7, 0.9]
    factor = 0.85

    # Add a random key to the filename to allow alignment using multiple processes
    # random_key = np.random.randint(0, high=99999)
    # bounding_boxes_filename = os.path.join(output_dir, 'bounding_boxes_%05d.txt' % random_key)
    # output_filename = os.path.join(output_dir, 'faceinsight_align_%s.lst' % args.name)

    if not os.path.exists(args.outdir):
        os.makedirs(args.outdir)

    output_filename = os.path.join(args.outdir, 'lst')

    nrof_images_total = 0
    nrof = np.zeros((5,), dtype=np.int32)
    face_count = 0
    for src_img_info in imgs_info:
        src_img_path = os.path.join(args.indir,src_img_info[1])
        if nrof_images_total % 100 == 0:
            print("Processing %d, (%s)" % (nrof_images_total, nrof))
        nrof_images_total += 1
        if not os.path.exists(src_img_path):
            print('image not found (%s)' % src_img_path)
            continue
        # print(image_path)
        try:
            img = misc.imread(src_img_path)
        except (IOError, ValueError, IndexError) as e:
            errorMessage = '{}: {}'.format(src_img_path, e)
            print(errorMessage)
        else:
            if img.ndim < 2:
                print('Unable to align "%s", img dim error' % src_img_path)
                # text_file.write('%s\n' % (output_filename))
                continue
            if img.ndim == 2:
                img = to_rgb(img)
            img = img[:, :, 0:3]

            target_dir = ''
            src_img_path_list = src_img_info[1].replace('\\','/').split('/')
            #print(src_img_path_list)
            if len(src_img_path_list) <= 1:
                target_dir = args.outdir
            elif len(src_img_path_list) ==2:
                src_img_path_prefix = src_img_path_list[:-1]
                target_dir = os.path.join(args.outdir, str(src_img_path_prefix[0]))
            else:
                src_img_path_prefix = ['/'.join(bar) for bar in src_img_path_list[:-1]]

                #print('src_img_path_prefix: ',src_img_path_prefix)
                target_dir = os.path.join(args.outdir, str(src_img_path_prefix[0]))
            #print(target_dir)
            if not os.path.exists(target_dir):
                os.makedirs(target_dir)

            _minsize = minsize
            _bbox = None
            _landmark = None
            bounding_boxes, points = detect_face.detect_face(img, _minsize, pnet, rnet, onet, threshold, factor)
            #print(points)
            if points == []:
                points = None

            else:
                _landmark = points.T

            #print(_landmark.shape)
            faces_sumnum = bounding_boxes.shape[0]
            for  num  in  range(faces_sumnum):
                warped = face_preprocess.preprocess(img, bbox=bounding_boxes[num], landmark=_landmark[num].reshape([2,5]).T, image_size=args.image_size)
                bgr = warped[..., ::-1]
                #cv2.imshow(str(num),bgr)
                target_file = os.path.join(target_dir, '%08d.jpg'%face_count)
                #print(target_file)
                cv2.imwrite(target_file,bgr)
                face_count += 1

def parse_arguments(argv):
    parser = argparse.ArgumentParser()

    parser.add_argument('--indir',
                        default='D:/03.work/02.development/04.PaidOn/1.FaceRecognition/2.Dataset/2.PaidOnData/1.TrainData/CASIA-WebFace/CASIA-WebFace',
                        type=str, help='Directory with unaligned images.')
    parser.add_argument('--outdir',
                        default='D:/03.work/02.development/04.PaidOn/1.FaceRecognition/2.Dataset/2.PaidOnData/1.TrainData/CASIA-WebFace/CASIA-WebFace_112x112a',
                        type=str, help='Directory with aligned face thumbnails.')
    parser.add_argument('--image-size', type=str, help='Image size (height, width) in pixels.', default='112,112')
    # parser.add_argument('--margin', type=int,
    #    help='Margin for the crop around the bounding box (height, width) in pixels.', default=44)
    parser.add_argument('--exts', nargs='+', default=['.jpeg', '.jpg', '.png','.bmp'],
                        help='list of acceptable image extensions.')

    parser.add_argument('--recursive', default=True,
                        help='If true recursively walk through subdirs and assign an unique label\
        to images in each folder. Otherwise only include images in the root folder\
        and give them label 0.')
    return parser.parse_args(argv)


if __name__ == '__main__':
    main(parse_arguments(sys.argv[1:]))

该脚本我们部位大家讲解了,有兴趣的哥们可以自己去分析。使用该脚本只需要指定输入输出目录,以及输出的图片大小即可,下面是演示的效果:

人脸识别0-06:insightFace-半监督系统搭建(1)-人脸检测_第1张图片
人脸识别0-06:insightFace-半监督系统搭建(1)-人脸检测_第2张图片
这里提示一下大家,作者源码的检测,不知道什么原因,不能进行人脸矫正,如果需要人脸矫正的,请粘贴我的代码,如果运行不了,可以拷贝我的整个项目,保证是没有问题的。

下面我们当然就需要对人脸进行分类,如何分类呢?请看下小节。

你可能感兴趣的:(#,人脸技术,人脸识别,人脸检测)