示例#1
0
def do_enhanement(name):
    # 获取指定name的图像路径列表
    directory_path = cfg_manager.read_cfg('Common', 'face_directory')
    folderPath = os.path.sep.join([directory_path, name])
    pathlist = oshelper.dirwalker(folderPath, ('.jpg', '.jpeg'))

    ePath = './data/enhanced/%s' % name   # 数据增强存储地址
    isExists = os.path.exists(ePath)
    if isExists:
        key = input('name has already exists, would you like to cover it?(y/n) :')
        if key == 'n':
            return
        if key == 'y':
            # 删除文件夹中所有增强文件
            # 保留原有目录
            oshelper.deleteAll(path=ePath, removedir=False)
    else:
        # 若不存在创建目录
        os.makedirs('./data/enhanced/%s' % name)
    # 对指定照片库使用数据增强
    for imagePath in pathlist:
        img = cv2.imread(imagePath)
        # 随机应用多种变换中的一种
        random_key = random.randint(1, 3)
        if random_key == 1:
            rotate(img)
        elif random_key == 2:
            flip(img)
        elif random_key == 3:
            blurred(img)
    # 将增强过的列表写入文件夹
    i = 0
    for pic in output:
        pic_name = "enhanced%i.jpg" % i
        cv2.imwrite('./data/enhanced/%s/%s' % (name, pic_name), pic)  # 存至硬盘
        i += 1
    # 验证图片可用性
    # 移除无效增强
    enumerated_list = oshelper.dirwalker(ePath, ('.jpg', '.jpeg'))
    for enumerated in enumerated_list:
        enumerated_pic = cv2.imread(enumerated)
        flag, detections = tool_interface.where_face(enumerated_pic)
        if flag:
            if len(detections) > 0:
                # 取人脸最大可能性的位置
                i = np.argmax(detections[0, 0, :, 2])
                confidence = detections[0, 0, i, 2]

                # 如果置信度小于设定值
                if confidence < float(cfg_manager.read_cfg('FaceEmbeddings', 'confidence')):
                    os.remove(enumerated)
                    print('removed')
                else:
                    print('enumerated')
        else:
            print('\033[1;31m[ERROR]enumerate failed\033[0m')
示例#2
0
def get_path():
    pickle_directory = cfg_manager.read_cfg('Common', 'pickle_directory')
    empickle = os.path.sep.join([pickle_directory, "embeddings.pickle"])
    lepickle = os.path.sep.join([pickle_directory, "le.pickle"])
    recopickle = os.path.sep.join([pickle_directory, "recognizer.pickle"])
    pickledic = {
        'embedding': empickle,
        'le': lepickle,
        'recognizer': recopickle
    }
    return pickledic
示例#3
0
def where_face(img):

    flag = True  # 成功执行的标志
    detections = []

    protoPath = os.path.sep.join(
        [cfg_manager.read_cfg('Common', 'detector_path'), "deploy.prototxt"])
    modelPath = os.path.sep.join([
        cfg_manager.read_cfg('Common', 'detector_path'),
        "res10_300x300_ssd_iter_140000.caffemodel"
    ])

    # 加载图片,保持纵横比更改宽度维600
    # 取得标准化后的图像高度与宽度
    image = imutils.resize(img, width=600)
    (h, w) = image.shape[:2]

    # 取得图片的RGB均值
    resized = cv2.resize(image, (300, 300))
    r_mean = np.mean(resized[:, :, 0])
    g_mean = np.mean(resized[:, :, 1])
    b_mean = np.mean(resized[:, :, 2])
    rgb_means = (r_mean, g_mean, b_mean)

    # 对整张图片构建blob
    imageBlob = cv2.dnn.blobFromImage(resized,
                                      1.0, (300, 300),
                                      rgb_means,
                                      swapRB=False,
                                      crop=False)

    # 输入深度学习模型并取得预测结果
    try:
        detector = cv2.dnn.readNetFromCaffe(protoPath, modelPath)
        detector.setInput(imageBlob)
        detections = detector.forward()
    except SyntaxError:
        flag = False
    finally:
        return flag, detections
示例#4
0
def do_alignment(image):
    # 加载Haar分类器
    glasses_eyes_classifier = cv2.CascadeClassifier(
        cfg_manager.read_cfg('FaceAlignment', 'glasseseyes_classifier_path'))
    lefteye_classifier = cv2.CascadeClassifier(
        cfg_manager.read_cfg('FaceAlignment', 'lefteye_classifier_path'))
    righteye_classifier = cv2.CascadeClassifier(
        cfg_manager.read_cfg('FaceAlignment', 'righteye_classifier_path'))
    # 对传入照片进行浅度复制
    img = image.copy()
    # 初始化人眼中心点数组
    eye_location = []

    # 获取人脸图像尺寸
    (fH, fW) = img.shape[:2]
    # 裁剪人脸上半部分
    eye_region = img[0:int(fH / 2.1), 0:int(fW)]
    # 首先使用Haar分类器对两只眼睛分别进行定位
    lefteye = lefteye_classifier.detectMultiScale(eye_region, 1.2, 10,
                                                  cv2.CASCADE_SCALE_IMAGE)
    righteye = righteye_classifier.detectMultiScale(eye_region, 1.2, 10,
                                                    cv2.CASCADE_SCALE_IMAGE)
    # 若两个分类器均检测到结果
    if len(righteye) == 1 and len(lefteye) == 1:
        # 分析左右眼坐标差异性
        difference = reduce(operator.add, lefteye - righteye)
        var = np.var(difference)
        # 若左右眼区域之差的方差大于200
        # 视为成功分别检测到左右眼
        if var > 200:
            faceRects_eye = [lefteye, righteye]
            for faceRect_eye in faceRects_eye:
                # 压缩二维数组至一维
                _faceRect_eye = reduce(operator.add, faceRect_eye)
                x1, y1, w1, h1 = _faceRect_eye
                cv2.rectangle(eye_region, (int(x1), int(y1)),
                              (int(x1) + int(w1), int(y1) + int(h1)),
                              (0, 255, 0), 2)
                # 标出人眼中心点
                eye_region_center = (int(x1) + int(w1 / 2),
                                     int(y1) + int(h1 / 2))
                cv2.circle(eye_region,
                           eye_region_center,
                           radius=3,
                           color=(0, 0, 255))
                for num in eye_region_center:
                    eye_location.append(num)
            if len(eye_location) == 4:
                cv2.line(eye_region, (eye_location[0], eye_location[1]),
                         (eye_location[2], eye_location[3]), (0, 0, 255),
                         thickness=3)
                k = (eye_location[3] - eye_location[1]) / (eye_location[2] -
                                                           eye_location[0])

            cv2.imshow('eye', eye_region)
            cv2.waitKey(10)
            return

        else:
            print('face_alignment failed')

    # 当仅仅检测到一只眼时
    elif len(righteye) == 1 or len(lefteye) == 1:
        faceRects_eye = [lefteye, righteye]
        for faceRect_eye in faceRects_eye:
            # 若存在某一人眼的坐标
            # 压缩二维数组至一维
            if len(faceRect_eye) != 0:
                _faceRect_eye = reduce(operator.add, faceRect_eye)
                print(_faceRect_eye)
                # 使用戴眼镜的人眼检测查找另一只眼睛
                glasses_eyes = glasses_eyes_classifier.detectMultiScale(
                    eye_region, 1.2, 10, cv2.CASCADE_SCALE_IMAGE)
                print(glasses_eyes)
                # 若能找到两只人眼
                if len(glasses_eyes) == 2:
                    # 分析左右眼坐标差异性
                    difference = glasses_eyes[0] - glasses_eyes[1]
                    var = np.var(difference)
                    # 若左右眼区域之差的方差大于200
                    # 视为成功分别检测到左右眼
                    if var > 200:
                        for glasses_eye in glasses_eyes:
                            # 压缩二维数组至一维
                            _faceRect_eye = reduce(operator.add, glasses_eye)
                            x1, y1, w1, h1 = _faceRect_eye
                            cv2.rectangle(
                                eye_region, (int(x1), int(y1)),
                                (int(x1) + int(w1), int(y1) + int(h1)),
                                (0, 255, 0), 2)
                            cv2.imshow('eye', eye_region)
                            cv2.waitKey(10)
                        return
                    else:
                        print('face_alignment failed')

                # 若只检测到一只眼
                elif len(glasses_eyes) == 1:
                    eyes = [faceRect_eye, glasses_eyes]
                    difference = reduce(operator.add, eyes[0] - eyes[1])
                    var = np.var(difference)
                    if var > 200:
                        for eye in eyes:
                            _faceRect_eye = reduce(operator.add, eye)
                            x1, y1, w1, h1 = _faceRect_eye
                            cv2.rectangle(
                                eye_region, (int(x1), int(y1)),
                                (int(x1) + int(w1), int(y1) + int(h1)),
                                (0, 255, 0), 2)
                            cv2.imshow('eye', eye_region)
                            cv2.waitKey(10)
                        return
                    else:
                        print('face_alignment failed')
            else:
                print('face_alignment failed')
    else:
        print('face_alignment failed')
示例#5
0
def do_encoding(name):
    global run_flag
    global main_box
    global knownNames
    global knownEmbeddings
    global pic_num

    # 从磁盘中加载embedder
    print("\033[1;33m[INFO] loading face recognizer...\033[0m")
    try:
        embedder = cv2.dnn.readNetFromTorch(
            cfg_manager.read_cfg('Common', 'embedder_path'))
    except cv2.error:
        # 返回模型加载失败错误
        print('\033[1;31m[ERROR]load embedder failed\033[0m')
        print(">>>HELP")
        print(
            "  * Confirm that the corresponding model file exists in the specified path"
        )
        flag = 'Embedder_Error'
        return flag
    print("\033[22;32m>>>success\033[0m")

    # 获取编码pickle路径
    pickledic = pickle_helper.get_path()
    # 尝试从硬盘中读取pickle
    try:
        data = pickle_helper.load_pickle_from_disk(pickledic['embedding'])
        knownNames = data["names"]  # pickle中已有的name
        knownEmbeddings = data["embeddings"]  # pickle中以有的人脸编码
    # 捕获异常
    # 尝试通过已有图像重新生成pickle
    except FileNotFoundError:
        flag = face_encoding.do_embedding()
        if flag == 'FaceNum_Error':
            # 程序刹车
            run_flag = False
        else:
            # 成功重新生成则再次读取pickle
            data = pickle_helper.load_pickle_from_disk(pickledic['embedding'])
            knownNames = data["names"]  # pickle中已有的name
            knownEmbeddings = data["embeddings"]  # pickle中以有的人脸编码

    pic_num = 0
    while run_flag:
        # 按下s开始编码
        if pressed_key == 's':
            # 若main_box中存在数据
            # 说明camera_shot中存在人脸需要执行编码
            if len(main_box) != 0:
                pic_name = time.strftime("%Y%m%d_%H_%M_%S.jpg",
                                         time.localtime())
                cv2.imwrite("./face_directory/%s/%s" % (name, pic_name),
                            camera_shot)  # 存至硬盘
                startX = main_box[0]
                startY = main_box[1]
                endX = main_box[2]
                endY = main_box[3]
                # 将ROI区域截出
                face = camera_shot[startY:endY, startX:endX]
                (fH, fW) = face.shape[:2]
                # 剔除较小的人脸
                if fW < 20 or fH < 20:
                    continue

                # 取得图片RGB均值
                r_mean = np.mean(face[:, :, 0])
                g_mean = np.mean(face[:, :, 1])
                b_mean = np.mean(face[:, :, 2])
                rgb_means = (r_mean, g_mean, b_mean)

                # 构造blob
                # 对人脸进行编码
                faceBlob = cv2.dnn.blobFromImage(face,
                                                 1.0 / 255, (96, 96),
                                                 rgb_means,
                                                 swapRB=True,
                                                 crop=False)
                embedder.setInput(faceBlob)
                vec = embedder.forward()

                # 将姓名写入列表
                # 编码存储至列表
                knownNames.append(name)
                knownEmbeddings.append(vec.flatten())

                pic_num += 1  # 已捕获照片数量+1
        # 按下任意键暂停编码
        else:
            continue

        time.sleep(1)
    if pic_num != 0:
        data = {"embeddings": knownEmbeddings, "names": knownNames}
        pickle_helper.write_pickle_to_disk(pickledic['embedding'], data)
        train_model.do_modeltrain()
    else:
        os.removedirs('./face_directory/%s' % name)
        print('[INFO] no pic added')
示例#6
0
def camera_tracking():
    # 从磁盘加载detector
    print("\033[1;33m[INFO] loading face detector from \033[4;32m%s\033[0m" %
          cfg_manager.read_cfg('Common', 'detector_path'))
    protoPath = os.path.sep.join(
        [cfg_manager.read_cfg('Common', 'detector_path'), "deploy.prototxt"])
    modelPath = os.path.sep.join([
        cfg_manager.read_cfg('Common', 'detector_path'),
        "res10_300x300_ssd_iter_140000.caffemodel"
    ])
    try:
        detector = cv2.dnn.readNetFromCaffe(protoPath, modelPath)
    except cv2.error:
        # 返回模型加载失败错误
        print('\033[1;31m[ERROR]load detector failed\033[0m')
        print(">>>HELP")
        print(
            "  * Confirm that the corresponding model file exists in the specified path"
        )
        flag = 'Detector_Error'
        return flag
    print("\033[22;32m>>>success\033[0m")

    capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)
    while run_flag:
        ret, frame = capture.read()
        if ret is False:
            break
        image = imutils.resize(frame, width=600)
        (h, w) = image.shape[:2]

        # 取得图片的RGB均值
        resized = cv2.resize(image, (300, 300))
        r_mean = np.mean(resized[:, :, 0])
        g_mean = np.mean(resized[:, :, 1])
        b_mean = np.mean(resized[:, :, 2])
        rgb_means = (r_mean, g_mean, b_mean)

        # 构建Blob
        imageBlob = cv2.dnn.blobFromImage(resized,
                                          1.0, (300, 300),
                                          rgb_means,
                                          swapRB=False,
                                          crop=False)
        detector.setInput(imageBlob)
        detections = detector.forward()

        # 根据box面积将人脸主体与其他人分离
        # 使用绿色box标记主体,红色box标记路人

        box_list = []  # box区域列表
        box_measure = []  # box面积列表

        global main_box
        global camera_shot
        # 扫描循环
        for i in range(0, detections.shape[2]):
            confidence = detections[0, 0, i, 2]
            if confidence > 0.4:
                box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
                intbox = box.astype("int")
                (startX, startY, endX, endY) = intbox
                face_box = intbox
                camera_shot = image.copy()
                measure = (endX - startX) * (endY - startY)  # 计算box面积
                box_measure.append(measure)  # 写入box面积列表
                box_item = [startX, startY, endX, endY]
                box_list.append(box_item)  # 写入box区域列表

        try:
            max_measure = box_measure.index(max(box_measure))
        except ValueError:
            continue

        # 绘制循环
        for i in range(0, len(box_measure)):
            startX = box_list[i][0]
            startY = box_list[i][1]
            endX = box_list[i][2]
            endY = box_list[i][3]
            if i == max_measure:
                cv2.rectangle(image, (startX, startY), (endX, endY),
                              (0, 255, 0), 2)
                global main_box
                main_box = [startX, startY, endX, endY]
            else:
                cv2.rectangle(image, (startX, startY), (endX, endY),
                              (0, 0, 255), 2)
        cv2.putText(image, 'captured:' + str(pic_num), (0, 40),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
        cv2.imshow('camera', image)
        cv2.waitKey(1)
    capture.release()
    cv2.destroyAllWindows()
示例#7
0
def do_recognition():
    parent_directory = os.getcwd()
    # 获取存储人脸检测器的face_detection_model路径
    detector_path = os.path.sep.join(
        [parent_directory,
         cfg_manager.read_cfg('Common', 'detector_path')])
    # load detector from disk
    print("[INFO] loading face detector...")
    protoPath = os.path.sep.join(
        [cfg_manager.read_cfg('Common', 'detector_path'), "deploy.prototxt"])
    modelPath = os.path.sep.join([
        cfg_manager.read_cfg('Common', 'detector_path'),
        "res10_300x300_ssd_iter_140000.caffemodel"
    ])
    detector = cv2.dnn.readNetFromCaffe(protoPath, modelPath)

    print("[INFO] loading face recognizer...")
    # 获取用于生成128维人脸向量的Torch模型存储位置
    embedder_path = os.path.sep.join(
        [parent_directory,
         cfg_manager.read_cfg('Common', 'embedder_path')])
    embedderPath = os.path.sep.join(
        [embedder_path, "openface_nn4.small2.v1.t7"])
    # 加载Torch模型
    embedder = cv2.dnn.readNetFromTorch(
        cfg_manager.read_cfg('Common', 'embedder_path'))

    # 读取SVM模型及对应编码文件
    recognizer = pickle.loads(
        open(r'./data/pickleHere/recognizer.pickle', "rb").read())
    le = pickle.loads(open(r'./data/pickleHere/le.pickle', "rb").read())

    # 从摄像头获取图像
    # 转换每张图的宽度为600,保持其纵横比并读取高度
    capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)

    # 启动键盘监控线程
    kthread = keyboardThread()
    kthread.start()
    while run_flag:
        ret, frame = capture.read()
        if ret is False:
            break
        image = imutils.resize(frame, width=600)
        (h, w) = image.shape[:2]
        # 构建Blob
        imageBlob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)),
                                          1.0, (300, 300),
                                          (104.0, 177.0, 123.0),
                                          swapRB=False,
                                          crop=False)
        detector.setInput(imageBlob)
        detections = detector.forward()

        # 提取人脸ROI
        for i in range(0, detections.shape[2]):
            # 取得置信度
            confidence = detections[0, 0, i, 2]

            # 根据置信度筛选是否存在人脸
            if confidence > 0.4:
                # 取得最高置信度对应的box区域
                box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
                (startX, startY, endX, endY) = box.astype("int")

                # 框出ROI区域
                face = image[startY:endY, startX:endX]
                (fH, fW) = face.shape[:2]

                # 过滤过小的人脸
                if fW < 20 or fH < 20:
                    continue

                # 识别人脸姓名
                faceBlob = cv2.dnn.blobFromImage(face,
                                                 1.0 / 255, (96, 96),
                                                 (0, 0, 0),
                                                 swapRB=True,
                                                 crop=False)
                embedder.setInput(faceBlob)
                vec = embedder.forward()
                # 使用训练好的SVM分类器识别人脸
                preds = recognizer.predict_proba(vec)[0]
                # 使用最高概率索引器查询标签编码器
                j = np.argmax(preds)
                proba = preds[j]
                name = le.classes_[j]
                # 绘制box
                text = "{}: {:.2f}%".format(name, proba * 100)
                y = startY - 10 if startY - 10 > 10 else startY + 10
                cv2.rectangle(image, (startX, startY), (endX, endY),
                              (0, 255, 0), 2)
                cv2.putText(image, text, (startX, y), cv2.FONT_HERSHEY_SIMPLEX,
                            0.45, (0, 255, 0), 2)
                cv2.imshow('', image)
                cv2.waitKey(1)
    capture.release()
    cv2.destroyAllWindows()
    kthread.join()
示例#8
0
def do_management():
    # 得到name_list
    try:
        data = pickle_helper.load_pickle_from_disk(
            r'C:\Users\ZHIYUAN\PycharmProjects\Facepro\data\pickleHere\embeddings.pickle'
        )
        names = data["names"]
        name_list = []
    except FileNotFoundError:
        print(
            "\033[1;31m[ERROR]no pickle here, please load your face and encode first\033[0m"
        )
        return
    for name in names:
        if name not in name_list:
            name_list.append(name)
    print('|  id  |      name      |')
    for i in range(len(name_list)):
        print(' %i       %s' % (i, name_list[i]))

    # 选定操作用户
    flag = True
    global selected
    while flag:
        try:
            n = int(input('\033[4;33menter an id :\033[0m'))
            selected = name_list[n]
            flag = False
        except ValueError:
            print('no such id please enter again ')
        except IndexError:
            print('index out of range')
    try:
        global directory_path
        global folder_names
        directory_path = cfg_manager.read_cfg('Common', 'face_directory')
        folder_names = os.listdir(os.path.sep.join([directory_path, selected]))
        lastchange = 0
        for folder_name in folder_names:
            time = folder_name.replace('_', '').replace('.jpg', '')
            if int(time) > int(lastchange):
                lastchange = time
    finally:
        pass

    # 展示选中用户信息
    print(
        '\033[1;32m=======================User Info========================\033[0m'
    )
    print('- Name: %s' % selected)
    print('- Pic num: %i' % names.count(selected))
    print('- Data enhanced: %s' %
          os.path.exists('./data/enhanced/%s' % selected))
    print('- Last modified: %s' % lastchange)
    print(
        '\033[1;32m========================================================\033[0m'
    )
    print('press 1 for : Delete')
    print('press 2 for : DataEnhancement')
    print('press 3 for : Backup')
    # 选择对用户的操作
    key = input('\033[4;33menter num and press enter : \033[0m')
    function_choose(key)
示例#9
0
def do_embedding():
    """
    >>使用cfg_manager从硬盘加载配置文件
    >>读取模型
        人脸定位:deploy.prototxt
                res10_300x300_ssd_iter_140000.caffemodel
        Torch嵌入模型:openface_nn4.small2.v1.t7
    >>对读取到的人脸进行编码并写入 embeddings.pickle
    """
    # 错误标记
    flag = ''
    # 从磁盘加载detector
    print("\033[1;33m[INFO] loading face detector from \033[4;32m%s\033[0m" %
          cfg_manager.read_cfg('Common', 'detector_path'))
    protoPath = os.path.sep.join(
        [cfg_manager.read_cfg('Common', 'detector_path'), "deploy.prototxt"])
    modelPath = os.path.sep.join([
        cfg_manager.read_cfg('Common', 'detector_path'),
        "res10_300x300_ssd_iter_140000.caffemodel"
    ])
    try:
        detector = cv2.dnn.readNetFromCaffe(protoPath, modelPath)
    except cv2.error:
        # 返回模型加载失败错误
        print('\033[1;31m[ERROR]load detector failed\033[0m')
        print(">>>HELP")
        print(
            "  * Confirm that the corresponding model file exists in the specified path"
        )
        flag = 'Detector_Error'
        return flag
    print("\033[22;32m>>>success\033[0m")
    # 从磁盘中加载embedder
    print("\033[1;33m[INFO] loading face recognizer...\033[0m")
    try:
        embedder = cv2.dnn.readNetFromTorch(
            cfg_manager.read_cfg('Common', 'embedder_path'))
    except cv2.error:
        # 返回模型加载失败错误
        print('\033[1;31m[ERROR]load embedder failed\033[0m')
        print(">>>HELP")
        print(
            "  * Confirm that the corresponding model file exists in the specified path"
        )
        flag = 'Embedder_Error'
        return flag
    print("\033[22;32m>>>success\033[0m")

    directory_path = cfg_manager.read_cfg('Common', 'face_directory')
    folder_names = os.listdir(directory_path)

    knownEmbeddings = []
    knownNames = []
    folderPaths = []
    total = 0
    nameNum = 0

    for folder_name in folder_names:
        # 获取每个文件夹的路径
        folderPaths.append(os.path.sep.join([directory_path, folder_name]))
        nameNum += 1
    name_code = -1
    for folderPath in folderPaths:
        imagePaths = list(paths.list_images(folderPath))
        name_code += 1
        # 获取到当前处理的文件夹名
        name = folder_names[name_code]
        # 判断此用户是否启用了数据增强
        isExists = os.path.exists('./data/enhanced/%s' % name)
        # 若启用了数据增强
        # 将增强后的文件路径一并写入代编码路径中
        if isExists:
            enhancedPaths = oshelper.dirwalker('./data/enhanced/%s' % name,
                                               ('jpg', ))
            for enhancedPath in enhancedPaths:
                imagePaths.append(enhancedPath)
        for (i, imagePath) in enumerate(imagePaths):
            print("[INFO] processing image {}/{}".format(
                i + 1, len(imagePaths)))

            # 加载图片,保持纵横比更改宽度维600
            # 取得标准化后的图像高度与宽度
            image = cv2.imread(imagePath)
            image = imutils.resize(image, width=600)
            (h, w) = image.shape[:2]

            # 取得图片的RGB均值
            resized = cv2.resize(image, (300, 300))
            r_mean = np.mean(resized[:, :, 0])
            g_mean = np.mean(resized[:, :, 1])
            b_mean = np.mean(resized[:, :, 2])
            rgb_means = (r_mean, g_mean, b_mean)

            # 对整张图片构建blob
            imageBlob = cv2.dnn.blobFromImage(resized,
                                              1.0, (300, 300),
                                              rgb_means,
                                              swapRB=False,
                                              crop=False)

            # 输入深度学习模型并取得预测结果
            detector.setInput(imageBlob)
            detections = detector.forward()
            # 确认检测到人脸
            if len(detections) > 0:
                # 取人脸最大可能性的位置
                i = np.argmax(detections[0, 0, :, 2])
                confidence = detections[0, 0, i, 2]

                # 如果置信度大于设定值
                if confidence >= float(
                        cfg_manager.read_cfg('FaceEmbeddings', 'confidence')):

                    # 取得ROI区域
                    roi = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
                    (startX, startY, endX, endY) = roi.astype("int")

                    # 将ROI区域截出
                    face = image[startY:endY, startX:endX]
                    (fH, fW) = face.shape[:2]

                    # 剔除较小的人脸
                    if fW < 20 or fH < 20:
                        continue

                    # 构造blob
                    # 对人脸进行编码
                    faceBlob = cv2.dnn.blobFromImage(face,
                                                     1.0 / 255, (96, 96),
                                                     (0, 0, 0),
                                                     swapRB=True,
                                                     crop=False)
                    embedder.setInput(faceBlob)
                    vec = embedder.forward()

                    # 将姓名写入列表
                    # 编码存储至列表
                    knownNames.append(name)
                    knownEmbeddings.append(vec.flatten())
                    total += 1

            else:
                print("\033[1;31m[ERROR]no face detected\033[0m")

    # 将编码写入pickle
    print("[INFO] serializing {} encodings...".format(total))
    data = {"embeddings": knownEmbeddings, "names": knownNames}
    pickle_helper.write_pickle_to_disk(pickle_helper.get_path()['embedding'],
                                       data)
    print("-------------------------------------")

    if nameNum < 2:
        print(knownNames)
        print('\033[1;31m[ERROR]classes must be greater than one\033[0m')
        flag = 'FaceNum_Error'

    return flag