Posts 一种简单人脸识别定位的实现
Post
Cancel

一种简单人脸识别定位的实现

一、 前言

基于Github开源项目face_recogition与opencv实现

功能特性如下:

  • 良好的交互性
  • 快速配置相关参数
  • 调用便捷

在使用前请确保face_recognition库, opencv库部署完毕

二、 功能演示

文件夹中有五张图片和一个python源码文件, 我们要做的是定位五张图片中的人脸

运行前文件夹

打开Linux Shell, 只需执行预设好的脚本, 即可生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
reina@LAPTOP-CISSPIC4:/mnt/c/WorkSpace/face_recognition/known$ bash face_position #(执行脚本)
/mnt/c/WorkSpace/face_recognition/known/positioned/
processing Cai Xukun.jpeg ...
229 303 55 130
processing Nick Yang.jpg ...
167 322 64 219
processing Solvay Conference.jpg ...
2584 2674 853 942
#(中间输出的若干组坐标省略)
1847 1955 1143 1250
processing t.py ...
Format not supported!
#(当遇到不支持格式的时候, 会提示并暂停, 询问是否查看所有格式)
Show all supported formats? (Y/n): y
.jpg
.jpeg
.gif
.png
processing Trump.jpg ...
798 1463 872 1538
processing Zhou Jielun.jpg ...
195 285 86 176
All completed!

可以看到目录中多出一个positioned文件夹

运行后文件夹

里面是定位后的图片

运行后positioned文件夹

即使是人脸最多的Solvay Conference也能快速准确地定位

Solvay Conference

三、 源码

face_position.py: 配置参数, 调用facekit_reina模块实现功能

1
2
3
4
5
6
7
8
9
#coding=utf-8
import facekit_reina
import os 
#未处理图片存放路径
raw_path = os.getcwd()+'/'
#处理后图片路径
positioned_path = raw_path + 'positioned/'

facekit_reina.start_generation(raw_path, positioned_path)

facekit_reina.py: 基于face_recognition的自定义的人脸识别模块, 正在逐渐完善

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#coding=utf-8
import face_recognition
from cv2 import cv2
import os

# generate for each image
# 每个文件生成图片
def generate_face_positioned_img(path, filename, positioned_path):
    image = face_recognition.load_image_file(path + filename)
    face_locations=face_recognition.face_locations(image)
   
    # face_locations eg:(139,283,325,97) (y1,x1,y2,x2)
    # reference of coordinate
    # 坐标系参考
    # ######################---------→ x
    # #                    #
    # #                    #
    # #                    #
    # #                    #
    # #       IMAGE        #
    # #                    #
    # #                    #
    # #                    #
    # #                    #
    # ######################
    # |
    # |
    # |
    # ↓
    # y

    for face in face_locations:
      y1=face[0]
      x1=face[1]
      y2=face[2]
      x2=face[3]
      xmin = min(x1,x2)
      ymin = min(y1,y2)
      xmax = max(x1,x2)
      ymax = max(y1,y2)
      print(xmin,xmax,ymin,ymax)
      cv2.rectangle(image,(xmin,ymin),(xmax,ymax),(255,0,0),3)

    #os.mkdir(positioned_path)
    cv2.imwrite(positioned_path+filename,cv2.cvtColor(image, cv2.COLOR_RGB2BGR))

# flow control
# 流程控制
def start_generation(raw_image_path, positioned_image_path):
    
    # directory of source files
    # 源文件的目录
    #raw_image_path='src/known/'

    # directory of output files
    # 输出文件的目录
    #positioned_image_path=raw_image_path+'positioned/'

    # filename List under the path (all file and floder included)
    # 文件名的列表 (包括所有的文件和文件夹)
    image_name_list=os.listdir(raw_image_path)

    if not os.path.exists(positioned_image_path):
        os.mkdir(positioned_image_path)

    # Compatible Formats  
    # 支持的文件格式
    compatible_formats=['.jpg','.jpeg','.gif','.png']

    all_overwrite = False

    for ifilename in image_name_list:
        if os.path.isdir(raw_image_path + ifilename):
            continue
        print("processing " + ifilename + ' ...')
        if (os.path.splitext(ifilename)[1] in compatible_formats):
            if (ifilename not in os.listdir(positioned_image_path)):
                generate_face_positioned_img(raw_image_path, ifilename, positioned_image_path)
            else:
                if all_overwrite == True:
                    pass
                else:
                    while True:
                        is_overwrite = input(ifilename+" already exists, do you want to overwrite it? (Y/n/all): ")
                        if str.lower(is_overwrite) == 'y':
                            generate_face_positioned_img(raw_image_path, ifilename, positioned_image_path)
                            break
                        elif str.lower(is_overwrite) == 'n':
                            break
                        elif str.lower(is_overwrite) == 'all':
                            generate_face_positioned_img(raw_image_path, ifilename, positioned_image_path)
                            all_overwrite = True
                            break
                        else:
                            pass
        else:
            print("Format not supported!")
            while True:
                is_show_compatible_formats = input('Show all supported formats? (Y/n): ')
                if str.lower(is_show_compatible_formats) == 'y':
                    for one_format in compatible_formats:
                        print(one_format)
                    break
                elif str.lower(is_show_compatible_formats) == 'n':
                        break
                else:
                    pass

    print("All completed!")

脚本face_position: 仅仅用于调用python3, 定位运行程序

1
2
3
#!/bin/bash

python3 /home/reina/code/python/face_recog/face_position.py

将脚本所在文件夹添加到环境变量之后, 即可在任何地方通过简短的命令调用了

四、 待完善

  • 完善功能, 能够根据已知人脸识别未知人脸
  • 加入命令行参数, 实现更精细的选项控制(完善功能后计划添加)

五、 07-27更新

facekit_reina等模块已在Github托管, 这是链接

This post is licensed under CC BY 4.0 by the author.