FaceRecognition慢慢来

FaceRecognition慢慢来

这是一个艰难的项目。

python

显示静态图像

以灰度模式读取图像并显示
按下任意键退出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import cv2 as cv

# 用灰度模式加载图像
img = cv.imread('test.jpg',0)
# 自定义窗口,参数1为名称,参数2为大小
cv.namedWindow("image",0);
# 窗口大小
cv.resizeWindow("image", 480, 480);
# 显示窗口位置,从最左上角开始,第一个是x坐标偏移,第二个是y坐标偏移
cv.moveWindow("image", 800, 150)
# 显示图像
cv.imshow('image',img)
# 设置图片窗口延迟,参数为0,键盘无限期的等待键入,按任意键退出
# waitKey()函数的参数非零值的单位为毫秒(ms)
cv.waitKey(0)

若将最后一个语句

1
cv.waitKey(0)

改为

1
2
3
4
5
6
7
8
9
10
# 按键控制
k = cv.waitKey(0)
if k == 27: # ESC 退出
# 关闭所有窗口
cv.destroyAllWindows()
elif k == ord('s'): # s键保存退出
# 保存图片
cv.imwrite('new.jpg',img)
# 关闭所有窗口
cv.destroyAllWindows()

可以实现新的按键功能
按下s键会保存图像并退出
按下Esc键退出并保存

捕捉实时图像

调用笔记本内置摄像头捕捉实时图像并显示
按下s键会保存图像
按下Esc键退出

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
import cv2 as cv

# 调用笔记本内置摄像头,所以参数为0,如果有其他的摄像头可以调整参数为1,2
cap=cv.VideoCapture(0)
# 死循环
while True:
# 从摄像头读取图片,一帧一帧捕捉
ret,img=cap.read()
# 图像左右水平反转-1 0 1
img = cv.flip(img, 1)
# 对帧的操作,转为灰度图片
gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 新建一个显示窗口并命名
cv.namedWindow("image", 0)
# 显示窗口大小
cv.resizeWindow("image", 640, 480)
# 显示窗口位置,从最左上角开始,第一个是x坐标偏移,第二个是y坐标偏移
cv.moveWindow("image", 800, 150)
# 显示返回的每帧图像
cv.imshow("image",gray)
# 图片窗口延迟为1ms,等待按键触发,保持画面的持续
k=cv.waitKey(1)
if k == 27:
# ESC键关闭所有窗口
cv.destroyAllWindows()
break
elif k==ord("s"):
# s键保存图片(彩色和灰度)
cv.imwrite("new1.jpg",img)
cv.imwrite("new2.jpg",gray)
# 关闭摄像头,当所有事完成,释放 VideoCapture 对象
cap.release()

Haar级联人脸静态图像检测

下载opencv对应的xml数据文件
文件
将test1.jpg识别完成后生成new.jpg

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
import cv2 as cv

# 加载使用数据库
face_cascade = cv.CascadeClassifier(r'./haarcascade_frontalface_default.xml')
eye_cascade = cv.CascadeClassifier(r'./haarcascade_eye.xml')
# 读取待检测图片
img = cv.imread('test1.jpg')
# 转换为灰度图
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 检测图像中的人脸
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
# 为每个人脸绘制一个蓝色矩形
for (x,y,w,h) in faces:
# (255,0,0)是color,为BGR数值(与RGB相反) 2是thickness宽度
cv.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
# 人眼检测更为不精准,不建议使用
# 检测人脸中的眼睛
#roi_gray = gray[y:y+h, x:x+w]
#roi_color = img[y:y+h, x:x+w]
#eyes = eye_cascade.detectMultiScale(roi_gray)
# 为每只眼睛绘制一个绿色矩形
#for (ex,ey,ew,eh) in eyes:
# cv.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
# 显示图像
cv.imshow('new',img)
# 储存图像
cv.imwrite('new.jpg',img)
cv.waitKey(0)
cv.destroyAllWindows()

Haar级联人脸动态图像检测

开启摄像头后进行人脸动态图像检测

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
import cv2 as cv

# 创建新的对象
cap = cv.VideoCapture(0,cv.CAP_DSHOW)
# 初始化人脸识别器(默认的人脸haar级联),加载使用数据库
face_cascade = cv.CascadeClassifier(r'./haarcascade_frontalface_default.xml')
# 死循环
while True:
# 从摄像头读取图像
_, image = cap.read()
# 图像左右水平反转
image = cv.flip(image, 1)
# 转换为灰度
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
# 检测图像中的所有人脸
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
# 为每个人脸绘制一个蓝色矩形
for x, y, w, h in faces:
cv.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2)
# 显示图像
cv.imshow("image", image)
# ESC键跳出循环
if cv.waitKey(1) == 27:
break
# 当所有事完成,释放对象
cap.release()
# 关闭所有窗口
cv.destroyAllWindows()

基于caffe训练模型的人脸静态图像检测

下载opencv对应的xml数据文件
文件1
文件2

将test1.jpg识别完成后生成new.jpg

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

import cv2 as cv
import numpy as np

# 加载使用数据库
prototxt_path = r"./deploy.prototxt"
model_path =r"./res10_300x300_ssd_iter_140000_fp16.caffemodel"

# 读取待检测图片
image = cv.imread("test1.jpg")
# 读取图片尺寸
h, w = image.shape[:2]
# 一些没搞懂的参数
model = cv.dnn.readNetFromCaffe(prototxt_path, model_path)
blob = cv.dnn.blobFromImage(image, 1.0, (300, 300),(104.0, 177.0, 123.0))
model.setInput(blob)
output = np.squeeze(model.forward())

# 辨识度计算
for i in range(0, output.shape[0]):
confidence = output[i, 2]
# 辨识度判断
if confidence > 0.5:
box = output[i, 3:7] * np.array([w, h, w, h])
start_x, start_y, end_x, end_y = box.astype(np.int_)
# 绘制矩形
cv.rectangle(image, (start_x, start_y), (end_x, end_y), color=(255, 0, 0), thickness=2)
# 辨识度显示
cv.putText(image, f"{confidence*100:.2f}%", (start_x, start_y-5), cv.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)

# 存储图片
cv.imwrite("new.jpg", image)

基于caffe训练模型的人脸动态图像检测

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
import cv2 as cv
import numpy as np

# 加载使用数据库
prototxt_path = "deploy.prototxt"
model_path = "res10_300x300_ssd_iter_140000_fp16.caffemodel"

model = cv.dnn.readNetFromCaffe(prototxt_path, model_path)
# 创建新的对象
cap = cv.VideoCapture(0)
# 死循环
while True:
# 读取图像
_, image = cap.read()
# 图像左右水平反转
image = cv.flip(image, 1)
# 读取图片尺寸
h, w = image.shape[:2]
# 一些没搞懂的参数
blob = cv.dnn.blobFromImage(image, 1.0, (300, 300), (104.0, 177.0, 123.0))
model.setInput(blob)
output = np.squeeze(model.forward())

# 辨识度计算
for i in range(0, output.shape[0]):
confidence = output[i, 2]
# 辨识度判断
if confidence > 0.5:
box = output[i, 3:7] * np.array([w, h, w, h])
start_x, start_y, end_x, end_y = box.astype(np.int_)
# 绘制矩形
cv.rectangle(image, (start_x, start_y), (end_x, end_y), color=(255, 0, 0), thickness=2)
# 辨识度显示
cv.putText(image, f"{confidence * 100:.2f}%", (start_x, start_y - 5), cv.FONT_HERSHEY_SIMPLEX, 1,
(255, 0, 0), 2)
# 显示图像
cv.imshow("image", image)
# 按键控制
if cv.waitKey(1) == 27:
break
cv.destroyAllWindows()
cap.release()

基于Haar级联人脸图像采集

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
import cv2 as cv

# 创建新的对象
cap = cv.VideoCapture(0, cv.CAP_DSHOW)
# 初始化人脸识别器(默认的人脸haar级联),加载使用数据库
face_cascade = cv.CascadeClassifier(r'./haarcascade_frontalface_default.xml')
# 初始化计数器
num = 0
# 死循环
while True:
# 从摄像头读取图像
_, image = cap.read()
# 图像左右水平反转
image = cv.flip(image, 1)
# 转换为灰度
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
# 检测图像中的所有人脸
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
if len(faces) > 0: # 大于0则检测到人脸
# 检索每张人脸
for x, y, w, h in faces:
# 图像命名和存储路径
img_name = '%s/%d.jpg' % ('D:\database', num)
# 图像裁切
image_new = image[y - 10: y + h + 10, x - 10: x + w + 10]
# 图像存储
cv.imwrite(img_name, image_new)
# 计数
num += 1
# 绘制蓝色矩形
cv.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2)
# 显示当前人脸采集数
cv.putText(image, 'num:%d' % (num), (x, y - 20), cv.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 255), 4)
# 如果超过指定最大保存数量退出循环
if num > 100: break
# 显示图像
cv.imshow("image", image)
# ESC键跳出循环
if cv.waitKey(1) == 27: break
# 当所有事完成,释放对象
cap.release()
# 关闭所有窗口
cv.destroyAllWindows()

基于caffe训练模型的人脸图像采集

未完成

人脸图像的裁剪和标注

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
import os
import sys
import numpy as np
import cv2

IMAGE_SIZE = 64

# 按照指定图像大小调整尺寸
def resize_image(image, height=IMAGE_SIZE, width=IMAGE_SIZE):
top, bottom, left, right = (0, 0, 0, 0)
# 获取图像尺寸
h, w, _ = image.shape
# 对于长宽不相等的图片,找到最长的一边
longest_edge = max(h, w)

# 计算短边需要增加多少像素宽度使其与长边等长
if h < longest_edge:
dh = longest_edge - h
top = dh // 2
bottom = dh - top
elif w < longest_edge:
dw = longest_edge - w
left = dw // 2
right = dw - left
else:
pass

# RGB颜色
BLACK = [0, 0, 0]

# 给图像增加边界,是图片长、宽等长,cv2.BORDER_CONSTANT指定边界颜色由value指定
constant = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT, value=BLACK)

# 调整图像大小并返回
return cv2.resize(constant, (height, width))


# 读取训练数据
images = []
labels = []

def read_path(path_name):
for dir_item in os.listdir(path_name):
# 从初始路径开始叠加,合并成可识别的操作路径
full_path = os.path.abspath(os.path.join(path_name, dir_item))

if os.path.isdir(full_path): # 如果是文件夹,继续递归调用
read_path(full_path)
else: # 文件
if dir_item.endswith('.jpg'):
image = cv2.imread(full_path)
# 调用resize_image()函数,将图像转为正方形
image = resize_image(image, IMAGE_SIZE, IMAGE_SIZE)
images.append(image)
labels.append(path_name)

return images, labels


# 从指定路径读取训练数据
def load_dataset(path_name):
images, labels = read_path(path_name)

# 将输入的所有图片转成四维数组,尺寸为(图片数量*IMAGE_SIZE*IMAGE_SIZE*3)
# 图片为64 * 64像素,一个像素3个颜色值(RGB)
images = np.array(images)
print(images.shape)

# 标注数据,'database1'文件夹下即为要识别的脸部图像,全部指定为0,另外一个文件夹下是其他识别对象,全部指定为1
labels = np.array([0 if label.endswith('database1') else 1 for label in labels])

return images, labels

if __name__ == '__main__':
if len(sys.argv) != 1:
print("Usage:%s path_name\r\n" % (sys.argv[0]))
else:
images, labels = load_dataset(r"D:\face") # 路径

基于keras的人脸模型训练

未完成 利用CNN进行训练自己的人脸模型

使用自建人脸模型进行人脸识别

未完成

参考

OpenCV中文官方文档
OpenCV中文文档4.0.0
https://cloud.tencent.com/developer/article/1890671
https://zhuanlan.zhihu.com/p/127039696
https://blog.csdn.net/python_pycharm/article/details/80808179
https://blog.csdn.net/qq_35166974/article/details/98181593
https://cloud.tencent.com/developer/article/1890671
https://blog.csdn.net/melancholyming/article/details/83501946
https://zhuanlan.zhihu.com/p/56699632
https://blog.csdn.net/A541925504/article/details/120917191
https://zhuanlan.zhihu.com/p/36962109
https://blog.csdn.net/great_yzl/article/details/119844700
-
https://blog.csdn.net/qq_42633819/article/details/81191308


FaceRecognition慢慢来
http://example.com/2023/03/13/Project项目-FaceRecognition慢慢来/
许可协议