日萌社
人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)
OpenCV:python调用摄像头同时使用OpenCV中自带已训练好的检测器来检测实时图像中的人脸和眼睛
使用opencv中haar人脸特征实时检测识别人脸
import cv2
import os
datpath = 'data/'
# img = cv2.imread('1.jpg')
# gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml")
face_cascade.load("haarcascade_frontalface_alt2.xml")
for img in os.listdir(datpath):
frame = cv2.imread(datpath+img)
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray,1.3,5)
for(x,y,w,h) in faces:
frame = cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
cv2.imwrite('result/'+img,frame)
# cv2.imshow('img',img)
# cv2.waitKey()
调用摄像头使用opencv中haar人脸特征实时检测识别人脸
import numpy as np
import cv2
import cv2 as cv
import matplotlib.pyplot as plt
# 实例化检测器
face_cas = cv.CascadeClassifier("haarcascade_frontalface_default.xml" )
face_cas.load('haarcascade_frontalface_default.xml')
eyes_cas = cv.CascadeClassifier("haarcascade_eye.xml")
eyes_cas.load("haarcascade_eye.xml")
# 调用笔记本内置摄像头,所以参数为0,如果有其他的摄像头可以调整参数为1,2
cap = cv2.VideoCapture(0)
while True:
# 从摄像头读取图片
sucess, img = cap.read()
# 转为灰度图片
# gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 显示摄像头,背景是灰度。
# cv2.imshow("img", gray)
#彩色显示图像
# cv2.imshow("img", img)
# 以灰度图的形式读取图片
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 调用识别人脸
faceRects = face_cas.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))
for faceRect in faceRects:
x, y, w, h = faceRect
# 框出人脸
cv.rectangle(img, (x, y), (x + h, y + w), (0, 255, 0), 3)
# 4.在识别出的人脸中进行眼睛的检测
roi_color = img[y:y + h, x:x + w]
roi_gray = gray[y:y + h, x:x + w]
eyes = eyes_cas.detectMultiScale(roi_gray)
for (ex, ey, ew, eh) in eyes:
cv.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)
## 检测结果的绘制
# plt.figure(figsize=(8, 6), dpi=100)
# plt.imshow(img[:, :, ::-1]), plt.title('检测结果')
# plt.xticks([]), plt.yticks([])
# plt.show()
#彩色显示图像
cv2.imshow("img", img)
# 保持画面的持续。
k = cv2.waitKey(1)
if k == 27:
# 通过esc键退出摄像
cv2.destroyAllWindows()
break
elif k == ord("s"):
# 通过s键保存图片,并退出。
cv2.imwrite("image2.jpg", img)
cv2.destroyAllWindows()
break
# 关闭摄像头
cap.release()
使用face_recognition实时检测识别人脸
from PIL import Image, ImageDraw
import face_recognition
"""
图像载入函数 load_image_file load_image_file(file, mode='RGB')
加载一个图像文件到一个numpy array类型的对象上。
参数:
file:待加载的图像文件名字
mode:转换图像的格式 只支持“RGB”(8位RGB, 3通道)和“L”(黑白)
返回值: 一个包含图像数据的numpy array类型的对象
"""
# image = face_recognition.load_image_file("obama.jpg")
image = face_recognition.load_image_file("threepeople.jpg")
"""
人脸特征提取函数 face_landmarks(face_image,face_locations=None,model="large")
给定一个图像,提取图像中每个人脸的脸部特征位置。
人脸特征提取函数face_landmarks 提取后的脸部特征包括:
鼻梁nose_bridge、鼻尖nose_tip、 下巴chin、左眼left_eye、右眼right_eye、左眉 left_eyebrow、
右眉right_eyebrow、上唇top_lip、下 唇bottom_lip
参数:
face_image:输入的人脸图片
face_locations=None:
可选参数,默认值为None,代表默认解码图片中的每一个人脸。
若输入face_locations()[i]可指定人脸进行解码
model="large"/"small":
输出的特征模型,默认为“large”,可选“small”。
当选择为"small"时,只提取左眼、右眼、鼻尖这三种脸部特征。
"""
face_landmarks_list = face_recognition.face_landmarks(image)
#加载图片
pil_image = Image.fromarray(image)
"""
Python图像处理库PIL的ImageDraw模块.
ImageDraw模块提供了图像对 象的简单2D绘制。用户可以 使用这个模块创建新的图像,注释或润饰已存在图像,为 web应用实时产生各种图形
"""
#载入图片,构建一个ImageDraw对象
d = ImageDraw.Draw(pil_image, 'RGBA')
""" 遍历图片中可能存在的多个人脸特征数据 """
for face_landmarks in face_landmarks_list:
"""
1.polygon()方法用于绘制多边形
第一个参数是多边形的几个顶点位置组成的list,第二个参数fill是填充该多边形的颜色。
例子:d.polygon(face_landmarks['left_eyebrow'], fill=(68, 54, 39, 128))
2.line()方法是用来画多个点之间构成的线段
第一个参数是 点位置组成的list,第二个参数fill是线段的颜色,第三个参数width是线段的宽度。
例子:d.line(face_landmarks['right_eyebrow'], fill=(68, 54, 39, 150), width=5)
"""
# 画个浓眉
d.polygon(face_landmarks['left_eyebrow'], fill=(68, 54, 39, 128))
d.polygon(face_landmarks['right_eyebrow'], fill=(68, 54, 39, 128))
d.line(face_landmarks['left_eyebrow'], fill=(1,1, 1, 1), width=15)
#d.line(face_landmarks['left_eyebrow'], fill=(68, 54, 39, 150), width=5)
d.line(face_landmarks['right_eyebrow'], fill=(68, 54, 39, 150), width=5)
# 涂个性感的嘴唇
d.polygon(face_landmarks['top_lip'], fill=(150, 0, 0, 128))
d.polygon(face_landmarks['bottom_lip'], fill=(150, 0, 0, 128))
d.line(face_landmarks['top_lip'], fill=(150, 0, 0, 64), width=8)
d.line(face_landmarks['bottom_lip'], fill=(150, 0, 0, 64), width=8)
# 闪亮的大眼睛
d.polygon(face_landmarks['left_eye'], fill=(255, 255, 255, 30))
d.polygon(face_landmarks['right_eye'], fill=(255, 255, 255, 30))
# 画眼线
d.line(face_landmarks['left_eye'] + [face_landmarks['left_eye'][0]], fill=(0, 0, 0, 110), width=6)
d.line(face_landmarks['right_eye'] + [face_landmarks['right_eye'][0]], fill=(0, 0, 0, 110), width=6)
pil_image.show()
from PIL import Image,ImageDraw
import face_recognition
"""
图像载入函数 load_image_file load_image_file(file, mode='RGB')
加载一个图像文件到一个numpy array类型的对象上。
参数:
file:待加载的图像文件名字
mode:转换图像的格式 只支持“RGB”(8位RGB, 3通道)和“L”(黑白)
返回值: 一个包含图像数据的numpy array类型的对象
"""
image = face_recognition.load_image_file('two_people.jpg')
"""
人脸特征提取函数 face_landmarks(face_image,face_locations=None,model="large")
给定一个图像,提取图像中每个人脸的脸部特征位置。
人脸特征提取函数face_landmarks 提取后的脸部特征包括:
鼻梁nose_bridge、鼻尖nose_tip、 下巴chin、左眼left_eye、右眼right_eye、左眉 left_eyebrow、
右眉right_eyebrow、上唇top_lip、下 唇bottom_lip
参数:
face_image:输入的人脸图片
face_locations=None:
可选参数,默认值为None,代表默认解码图片中的每一个人脸。
若输入face_locations()[i]可指定人脸进行解码
model="large"/"small":
输出的特征模型,默认为“large”,可选“small”。
当选择为"small"时,只提取左眼、右眼、鼻尖这三种脸部特征。
"""
face_landmarks_list = face_recognition.face_landmarks(image)
#获取到图片中所包含的两个人的人脸特征
print('找到 {} 个脸在这张图中'.format(len(face_landmarks_list))) #2
#加载图片
pil_image = Image.fromarray(image)
"""
Python图像处理库PIL的ImageDraw模块.
ImageDraw模块提供了图像对 象的简单2D绘制。用户可以 使用这个模块创建新的图像,注释或润饰已存在图像,为 web应用实时产生各种图形
"""
d = ImageDraw.Draw(pil_image)
i = 1
""" 遍历图片中可能存在的多个人脸特征数据 """
for face_landmarks in face_landmarks_list:
print('第 {} 个人的脸在这张图中'.format(i))
i+=1
""" keys():获取鼻梁nose_bridge、鼻尖nose_tip、 下巴chin、左眼left_eye、右眼right_eye、左眉 left_eyebrow、
右眉right_eyebrow、上唇top_lip、下 唇bottom_lip
"""
for facial_feature in face_landmarks.keys():
print('脸部特征:{}。脸部特征值: {}'.format(facial_feature, face_landmarks[facial_feature]))
"""
1.polygon()方法用于绘制多边形
第一个参数是多边形的几个顶点位置组成的list,第二个参数fill是填充该多边形的颜色。
例子:d.polygon(face_landmarks['left_eyebrow'], fill=(68, 54, 39, 128))
2.line()方法是用来画多个点之间构成的线段
第一个参数是 点位置组成的list,第二个参数fill是线段的颜色,第三个参数width是线段的宽度。
例子:d.line(face_landmarks['right_eyebrow'], fill=(68, 54, 39, 150), width=5)
"""
d.line(face_landmarks[facial_feature],width=5)
pil_image.show()
调用摄像头使用face_recognition实时检测识别人脸、给人脸打马赛克/给人脸贴图
import face_recognition
import cv2
from PIL import Image
"""
图像载入函数 load_image_file load_image_file(file, mode='RGB')
加载一个图像文件到一个numpy array类型的对象上。
参数:
file:待加载的图像文件名字
mode:转换图像的格式 只支持“RGB”(8位RGB, 3通道)和“L”(黑白)
返回值: 一个包含图像数据的numpy array类型的对象
"""
# 加载一些示例图片并学习如何识别它们。
lmm_image = face_recognition.load_image_file("2.jpg")
mask_image = face_recognition.load_image_file("1.jpg")
"""
人脸编码函数 face_encodings
face_encodings(face_image, known_face_locations=None, num_jitters=1)
给定一个图像,返回图像中每个人脸的128脸部编码(特征向量)。
参数:
face_image:输入的人脸图像
known_face_locations:可选参数,如果你知道每个人脸所在的边界框
num_jitters=1:在计算编码时要重新采样的次数。越高越准确,但速度越慢(100就会慢100倍)
返回值: 一个128维的脸部编码列表
"""
#获取一个128维的脸部编码列表
face_encoding = face_recognition.face_encodings(lmm_image)[0]
# print(face_encoding)
known_faces = [face_encoding]
# 初始化一些变量
face_locations = []
face_encodings = []
face_names = []
frame_number = 0
# 调用笔记本内置摄像头,所以参数为0,如果有其他的摄像头可以调整参数为1,2
cap = cv2.VideoCapture(0)
while True:
# 从摄像头读取图片
sucess, frame = cap.read()
# 将图像从BGR颜色(OpenCV使用)转换为RGB颜色(人脸识别使用)
rgb_frame = frame[:, :, ::-1]
"""
face_locations(img, number_of_times_to_upsample=1, model='hog')
给定一个图像,返回图像中每个人脸的面部特征位置(眼睛、鼻子等),也即是获取每个人脸所在的边界框/人脸的位置(top, right, bottom, left)。
参数:
img:一个image(numpy array类型)
number_of_times_to_upsample:从images的样本中查找多少次人脸,该参数值越高的话越能发现更小的人脸。
model:使用哪种人脸检测模型。“hog” 准确率不高,但是在CPUs上运行更快,
“cnn” 更准确更深度(且 GPU/CUDA加速,如果有GPU支持的话),默认是“hog”
返回值: 一个元组列表,列表中的每个元组包含人脸的位置(top, right, bottom, left)
"""
# 获取每个人脸所在的边界框/人脸的位置(top, right, bottom, left)
# 一个元组列表,列表中的每个元组包含人脸的位置(top, right, bottom, left)
face_locations = face_recognition.face_locations(rgb_frame)
# print(face_locations)
#face_encodings获取一个128维的脸部编码列表,其中传入第二个参数known_face_locations(可选参数,如果你知道每个人脸所在的边界框 )
face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)
face_names = []
# 遍历列表中 每个128维的脸部编码
for face_encoding in face_encodings:
"""
compare_faces(known_face_encodings, face_encoding_to_check, tolerance=0.6)
比较脸部编码列表和候选编码,看看它们是否匹配。
参数:
known_face_encodings:已知的人脸编码列表
face_encoding_to_check:待进行对比的单张人脸编码数据
tolerance:两张脸之间的距离小于相似阈值才算匹配。该值越小对比越严格,0.6是典型的最佳值。
返回值: 一个 True或者False值的列表,代表了known_face_encodings列表的每个成员的匹配结果。
注意:相似阈值(tolerance容忍度)中0.6是典型的最佳值,该值越小对比越严格,即两张脸之间的距离小于相似阈值才算匹配。
比如 face_distance 计算出来的距离为 0.4和 0.8,然后设置的相似阈值(tolerance容忍度)为0.6,
那么只有 0.4 小于 0.6 才认为是 相似, 0.8 大于 0.6 则认为是 不相似。
其中compare_faces(known_face_encodings, face_encoding_to_check, tolerance=0.6) 也可以设置相似阈值(tolerance容忍度)
"""
# 查看该脸是否与已知脸匹配
match = face_recognition.compare_faces(known_faces, face_encoding, tolerance=0.50)
""" match列表中的True或者False值 对应 known_faces = [lmm_face_encoding, al_face_encoding] """
# 如果你有两张以上的脸,你可以让这个逻辑更漂亮 但是为了演示我把它简单化了
name = None
if match[0]:
name = "nagisa"
face_names.append(name)
# elif match[1]:
# name = "Quxiaoxiao"
# face_names.append(name)
# 标记结果
#列表中的每个元组包含人脸的位置(top, right, bottom, left)
for (top, right, bottom, left), name in zip(face_locations, face_names):
if not name:
name = "Unknown"
""" 第一种方式:绘制人脸检测框 """
# # 根据 人脸的位置(top, right, bottom, left) 在脸上画一个方框
# cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
# # 画一个带文本信息的方框
# cv2.rectangle(frame, (left, bottom - 25), (right, bottom), (0, 0, 255), cv2.FILLED)
# #设置文本信息的字体
# font = cv2.FONT_HERSHEY_DUPLEX
# #要填入的文本信息
# cv2.putText(frame, name, (left + 6, bottom - 6), font, 0.5, (255, 255, 255), 1)
""" 第二种方式:使用高斯滤波生成类似马赛克 贴到指定人脸位置 """
# face_image = frame[top:bottom, left:right]
# face_image = cv2.GaussianBlur(face_image, (99, 99), 30)
# frame[top:bottom, left:right] = face_image
""" 第三种方式:把小图贴到每一帧图片中的指定人脸位置 """
face_image = frame[top:bottom, left:right]
# print(face_image.shape[0:2])
mask_image = cv2.resize(mask_image, (face_image.shape[1], face_image.shape[0]))
frame[top:bottom, left:right] = mask_image
#彩色显示图像
cv2.imshow("img", frame)
# 保持画面的持续。
k = cv2.waitKey(1)
if k == 27:
# 通过esc键退出摄像
cv2.destroyAllWindows()
break
elif k == ord("s"):
# 通过s键保存图片,并退出。
cv2.imwrite("image2.jpg", frame)
cv2.destroyAllWindows()
break
# 关闭摄像头
cap.release()