├── .idea
├── .name
├── encodings.xml
├── modules.xml
├── misc.xml
└── FlaskFaceRecognition.iml
├── static
├── pyy.jpg
├── Obama.jpg
├── bg_grey.jpeg
├── icon_add.png
├── icon_fold.png
└── icon_recognize.png
├── screenshot
├── pc1.png
└── pc2.png
├── know_images
├── 乔布斯
│ ├── images.jpg
│ └── 5f3c2640b18f4f498b44175d6b825959.jpg
├── obama
│ └── Obama.jpg
├── trump
│ └── trump.jpeg
├── 沈腾
│ └── ab27e6e6b6d64df885f0f5e1a646eb37.jpg
├── 雷军
│ └── f790130b239346928ff36cc290adb744.jpg
├── 马云
│ └── 3ac36edd286c465c9d86544777210a01.jpg
├── 黄渤
│ └── 5f3c16429c3045d2ade48acc2fde0f86.jpg
└── 马化腾
│ └── 8dbe23dcc123492d917280df8ea930cd.jpg
├── requirements.txt
├── test.py
├── README.md
├── train.py
├── app.py
└── templates
├── video.js
└── index.html
/.idea/.name:
--------------------------------------------------------------------------------
1 | FlaskFaceRecognition
--------------------------------------------------------------------------------
/static/pyy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/static/pyy.jpg
--------------------------------------------------------------------------------
/static/Obama.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/static/Obama.jpg
--------------------------------------------------------------------------------
/screenshot/pc1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/screenshot/pc1.png
--------------------------------------------------------------------------------
/screenshot/pc2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/screenshot/pc2.png
--------------------------------------------------------------------------------
/static/bg_grey.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/static/bg_grey.jpeg
--------------------------------------------------------------------------------
/static/icon_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/static/icon_add.png
--------------------------------------------------------------------------------
/static/icon_fold.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/static/icon_fold.png
--------------------------------------------------------------------------------
/know_images/乔布斯/images.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/know_images/乔布斯/images.jpg
--------------------------------------------------------------------------------
/static/icon_recognize.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/static/icon_recognize.png
--------------------------------------------------------------------------------
/know_images/obama/Obama.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/know_images/obama/Obama.jpg
--------------------------------------------------------------------------------
/know_images/trump/trump.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/know_images/trump/trump.jpeg
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/know_images/沈腾/ab27e6e6b6d64df885f0f5e1a646eb37.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/know_images/沈腾/ab27e6e6b6d64df885f0f5e1a646eb37.jpg
--------------------------------------------------------------------------------
/know_images/雷军/f790130b239346928ff36cc290adb744.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/know_images/雷军/f790130b239346928ff36cc290adb744.jpg
--------------------------------------------------------------------------------
/know_images/马云/3ac36edd286c465c9d86544777210a01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/know_images/马云/3ac36edd286c465c9d86544777210a01.jpg
--------------------------------------------------------------------------------
/know_images/黄渤/5f3c16429c3045d2ade48acc2fde0f86.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/know_images/黄渤/5f3c16429c3045d2ade48acc2fde0f86.jpg
--------------------------------------------------------------------------------
/know_images/乔布斯/5f3c2640b18f4f498b44175d6b825959.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/know_images/乔布斯/5f3c2640b18f4f498b44175d6b825959.jpg
--------------------------------------------------------------------------------
/know_images/马化腾/8dbe23dcc123492d917280df8ea930cd.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fishrong/FlaskFaceRecognition/HEAD/know_images/马化腾/8dbe23dcc123492d917280df8ea930cd.jpg
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Click==7.0
2 | dlib==19.16.0
3 | face-recognition==1.2.3
4 | face-recognition-models==0.3.0
5 | Flask==1.0.2
6 | Flask-Script==2.0.6
7 | itsdangerous==1.1.0
8 | Jinja2==2.10
9 | MarkupSafe==1.1.0
10 | numpy==1.15.4
11 | Pillow==5.4.1
12 | Werkzeug==0.14.1
13 |
--------------------------------------------------------------------------------
/test.py:
--------------------------------------------------------------------------------
1 | import face_recognition
2 |
3 | import train
4 |
5 | known_image = face_recognition.load_image_file("timg.jpg")
6 | known_encoding = face_recognition.face_encodings(known_image)#对脸部信息编码,一个人
7 | train.init()
8 | reconize_result = train.recognize_from_upload(known_image) # 识别结果
9 | print(reconize_result)
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 基于web的在线人脸识别系统
2 | ## 所涉及的python库
3 | * Flask
4 | * face_recognition
5 |
6 | ## 实现功能
7 | * 可以拖拽文件或者在系统的文件浏览中选择文件进行人脸识别
8 | * 可以对未知的人脸进行训练命名
9 | * 支持调用摄像头实时识别
10 | * 适配移动端与pc端
11 |
12 | ## 界面截图
13 | 
14 | 
15 |
--------------------------------------------------------------------------------
/.idea/FlaskFaceRecognition.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/train.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import face_recognition
4 | face_datas ={}#存图片信息以及人脸编码,格式:{"bob":[...,..],...}
5 |
6 | #添加数据:人脸编码信息
7 | def add_data(who,pic_name):
8 | known_image = face_recognition.load_image_file(pic_name)
9 | known_encoding = face_recognition.face_encodings(known_image)#对脸部信息编码,一个人
10 | if known_encoding==[]:
11 | print("图片错误:",pic_name)
12 | else:
13 | known_encoding = known_encoding[0]
14 | if who in face_datas:
15 | face_datas[who].append(known_encoding)
16 |
17 | else:
18 | face_datas[who] = [known_encoding]
19 |
20 |
21 | # 初始化,即训练文件中已有人脸信息
22 | def init():
23 | names = [x for x in os.listdir("know_images")]#获取该文件夹下的目录名
24 | # print(names)
25 | for i in names:
26 | name = [x for x in os.listdir("./know_images/"+i)]
27 | # print(name)
28 | for j in name:#获取每一个文件夹下的图片名称
29 | add_data(i,"./know_images/"+i+"/"+j)#将文件夹名称及其目录下所有图片名称
30 |
31 |
32 | # 从服务端选择文件识别,用于测试
33 | def recognize_from_fold(who):
34 | unknown_image = face_recognition.load_image_file("obama2.jpeg") # 需识别图片
35 | unknown_encoding = face_recognition.face_encodings(unknown_image)[0]
36 |
37 | results = face_recognition.compare_faces(who, unknown_encoding) # 比较,返回[true] 或[false]
38 | print(results)
39 |
40 |
41 | # 从上传文件中识别
42 | def recognize_from_upload(file):
43 | img_info = []
44 |
45 | unknown_image = face_recognition.load_image_file(file) # 待识别图片
46 |
47 | unknown_encoding = face_recognition.face_encodings(unknown_image)
48 | if unknown_encoding==[]: # 无人脸
49 | return "noface"
50 | face_locations = face_recognition.face_locations(unknown_image)
51 | print("face_locations",face_locations)
52 |
53 | for k in unknown_encoding: #遍历多张脸
54 |
55 | find = False
56 | for i in face_datas: # 遍历已训练的人脸编码信息
57 | if face_recognition.compare_faces(face_datas[i], k,tolerance=0.4)[0]: # 比较字典中与待识别图片,第一个参数为数组!!!
58 | img_info.append(i)
59 | find = True
60 | break
61 | if not find:
62 | img_info.append("somebody")
63 | return img_info,face_locations
64 |
65 | if __name__ == '__main__':
66 | init()
67 | # recognize_from_fold(face_datas['trump']['encoding'])
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | import base64
2 | import os
3 |
4 | import uuid
5 |
6 |
7 |
8 | from PIL import Image
9 | from flask import Flask, render_template, request
10 | import face_recognition
11 | from flask_script import Manager
12 | import train
13 |
14 |
15 | app = Flask(__name__)
16 | # manager = Manager(app)
17 | app.config['secret_key'] = "ddddd"
18 | train.init()
19 |
20 |
21 | @app.route('/')
22 | def index():
23 | return render_template("index.html")
24 |
25 |
26 | @app.route('/pichandler', methods=['post', 'get'])
27 | def pichandler():
28 | name = ""
29 | locations =""
30 |
31 | pic_data_url = request.form.get("picdata")
32 | # print(">>>>>>>",request.form.get('picdata'))
33 | imgdata = base64.b64decode(pic_data_url.split(',')[1])
34 | with open("temp3.jpg", 'wb') as f: # 把上传图片保存为文件,!!!有待优化
35 | f.write(imgdata)
36 |
37 | # pic = request.files.get("myPic") # 上传图片
38 | # print("pic:",pic)
39 |
40 | reconize_result = train.recognize_from_upload("temp3.jpg") # 识别结果
41 | print("Recognize_result:", reconize_result)
42 | print(type(reconize_result))
43 | for i in reconize_result[0]:
44 | if name == "":
45 | name = i
46 | else:
47 | name = name + "," + i
48 | for i in reconize_result[1]:
49 | if locations == "":
50 | locations = i
51 | else:
52 | locations = str(locations) + ";" + str(i)
53 |
54 | return str(name)+"-"+str(locations)
55 |
56 |
57 | @app.route('/update', methods=['post', 'get'])
58 | def update():
59 | pic_data_url = request.form.get("picdata")
60 | imgdata = base64.b64decode(pic_data_url.split(',')[1])
61 |
62 | with open("temp.jpg", 'wb') as f: # 把上传图片保存为文件,!!!有待优化
63 | f.write(imgdata)
64 | known_image = face_recognition.load_image_file("temp.jpg")
65 | name_list = request.form.get("picinfo").split(",") # 上传名字
66 | print("need_to_update:", name_list)
67 | for name in name_list: # * 为内容未改变
68 | if name != "*":
69 | # known_encoding = face_recognition.face_encodings(known_image)[name_list.index(name)] # 对改变名字的脸部信息编码
70 | face_location = face_recognition.face_locations(known_image)[name_list.index(name)]
71 | top, right, bottom, left = face_location
72 | face_image = known_image[top:bottom, left:right]
73 | pil_image = Image.fromarray(face_image)
74 | if not os.path.exists("know_images/" + name):
75 | os.mkdir("know_images/" + name)
76 | uuid_str = uuid.uuid4().hex
77 | pil_image.save("know_images/" + name + "/" + uuid_str + ".jpg") # 保存图片
78 | train.add_data(name, "know_images/" + name + "/" + uuid_str + ".jpg")
79 |
80 | # print(known_encoding)
81 | return "success"
82 |
83 |
84 | @app.route('/vidohandler',methods=['get','post'])
85 | def vido_handler():
86 | name = ""
87 | locations = ""
88 | pic_data_url = request.form.get("picdata")
89 | imgdata = base64.b64decode(pic_data_url.split(',')[1])
90 |
91 | with open("temp2.jpg", 'wb') as f: # 把上传图片保存为文件,!!!有待优化
92 | f.write(imgdata)
93 | reconize_result = train.recognize_from_upload("temp2.jpg") # 识别结果
94 | print("reconize_result:",reconize_result)
95 | if reconize_result=="noface":
96 | return reconize_result
97 | for i in reconize_result[0]:
98 | if name == "":
99 | name = i
100 | else:
101 | name = name + "," + i
102 | for i in reconize_result[1]:
103 | if locations == "":
104 | locations = i
105 | else:
106 | locations = str(locations) + ";" + str(i)
107 |
108 | return str(name)+"-"+str(locations)
109 |
110 |
111 | @app.route('/testjpg',methods=['post','get'])
112 | def testjpg():
113 | pic_data_url = request.form.get("picdata")
114 | #print(">>>>>>>",request.form.get('picdata'))
115 |
116 | imgdata = base64.b64decode(pic_data_url.split(',')[1])
117 |
118 | with open("temp3.jpg", 'wb') as f: # 把上传图片保存为文件,!!!有待优化
119 | f.write(imgdata)
120 | return "success"
121 |
122 |
123 |
124 | if __name__ == '__main__':
125 | app.run(host="0.0.0.0",port="5001",ssl_context='adhoc')
126 |
--------------------------------------------------------------------------------
/templates/video.js:
--------------------------------------------------------------------------------
1 | //访问用户媒体设备的兼容方法
2 | function getUserMedia(constraints, success, error) {
3 | if (navigator.mediaDevices.getUserMedia) {
4 | //最新的标准API
5 | navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
6 | } else if (navigator.webkitGetUserMedia) {
7 | //webkit核心浏览器
8 | navigator.webkitGetUserMedia(constraints, success, error)
9 | } else if (navigator.mozGetUserMedia) {
10 | //firfox浏览器
11 | navigator.mozGetUserMedia(constraints, success, error);
12 | } else if (navigator.getUserMedia) {
13 | //旧版API
14 | navigator.getUserMedia(constraints, success, error);
15 | }
16 | }
17 |
18 | // let video = document.getElementById('video');
19 |
20 |
21 | context.strokeStyle = "red";
22 | context2.strokeStyle = "red";
23 |
24 | function success(stream) {
25 | //兼容webkit核心浏览器
26 | let CompatibleURL = window.URL || window.webkitURL;
27 | //将视频流设置为video元素的源
28 | //console.log(stream);
29 | myStream = stream;
30 | //video.src = CompatibleURL.createObjectURL(stream);
31 | video.srcObject = stream;
32 | video.play();
33 | }
34 |
35 | function error(error) {
36 | console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
37 | document.getElementById("testvideo").innerHTML=`访问用户媒体设备失败${error.name}`+`${error.message}`;
38 | }
39 |
40 | function playvideo() {
41 | if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
42 | //调用用户媒体设备, 访问摄像头
43 | getUserMedia({video: {width: 640, height: 480}}, success, error);
44 | } else {
45 | alert('不支持访问用户媒体');
46 | }
47 | }
48 |
49 |
50 | $('#upload').click(function () {
51 | console.log("开始上传...");
52 | context2.drawImage(video, 0, 0, video_width, video_height);
53 | var src = canvas2.toDataURL("image/jpeg");
54 | console.log(src);
55 | send(src, "{{ url_for('vido_handler') }}")
56 | });
57 | var timer;
58 |
59 | function start_recognization() {
60 | timer = setInterval(upload, 800);
61 | }
62 |
63 | function stop_recognization() {
64 | clearInterval(timer);
65 | context.clearRect(0, 0, video_width, video_height);
66 | }
67 |
68 | function upload() {
69 | // console.log("开始上传...");
70 |
71 | context2.drawImage(video, 0, 0, video_width, video_height);
72 | var src = canvas2.toDataURL("image/jpeg");
73 | send_video_pic(src, "{{ url_for('vido_handler') }}")
74 | }
75 |
76 | function send_video_pic(fileList, url) {
77 | var fd = new FormData();
78 | fd.append("picdata", fileList);
79 | var xhr = new XMLHttpRequest();
80 | xhr.open("post", url, true);
81 | //服务器响应
82 |
83 | xhr.onreadystatechange = function () {
84 | context.clearRect(0, 0, video_width, video_height);
85 |
86 | if (xhr.status === 200 && xhr.readyState === 4 && xhr.responseText !== 'noface') {
87 | // console.log("success");
88 |
89 | var responses = xhr.responseText.split("-");//'-'分开名字和位置
90 | var response_names = responses[0].split(",");//名字数组
91 | // console.log("res_names:", response_names);
92 |
93 |
94 | var response_loctions = responses[1].split(";");//位置数组
95 | //div_names.innerHTML = "";//与服务器传回顺序颠倒
96 |
97 | for (var i = 0; i < response_names.length; i++) {
98 |
99 |
100 | //设置名字位置
101 | var res_loction = response_loctions[i].replace("(", "").replace(")", "").split(",");
102 | //console.log("res_locations:", res_loction);
103 | var top = parseInt(res_loction[0]);
104 | var right = parseInt(res_loction[1]);
105 | var bottom = parseInt(res_loction[2]);
106 | var left = parseInt(res_loction[3]);
107 | context.strokeStyle = "red";
108 | context.fillStyle = "red";
109 |
110 | context.fillRect(left, bottom, right - left, 30);//文字背景色
111 | context.strokeRect(left, top, right - left, bottom - top);//脸部框
112 | context.fillStyle = "white";
113 | context.font = "24px serif";
114 | context.textAlign = "center";
115 | context.fillText(response_names[i], (left + right) / 2, bottom + 20);//文字
116 |
117 |
118 | }
119 |
120 | }
121 |
122 | };
123 | xhr.send(fd);
124 | }
--------------------------------------------------------------------------------
/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | 在线人脸识别系统
11 |
18 |
19 |
20 |
21 |
22 |
23 |
在线人脸识别系统
24 |
25 |
27 |
28 |
30 |
31 |
32 |
33 |
34 |
35 |
37 |
40 |
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 |
457 |
460 |
461 |
--------------------------------------------------------------------------------