调用摄像头使用face_recognition 或 opencv中haar人脸特征实时检测识别人脸、给人脸打马赛克/给人脸贴图

日萌社

 

人工智能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()

  

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

あずにゃん

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值