实现流程从摄像头获取视频流,并转换为一帧一帧的图像,然后将图像信息传递给opencv这个工具库处理,返回灰度图像(就像你使用本地静态图片一样)

程序启动后,根据监听器信息,使用一个while循环,不断的加载视频图像,然后返回给opencv工具呈现图像信息。

创建一个键盘事件监听,按下"d"键,则开始执行面部匹配,并进行面具加载(这个过程是动态的,你可以随时移动)。

面部匹配使用Dlib中的人脸检测算法来查看是否有人脸存在。如果有,它将为每个人脸创建一个结束位置,眼镜和烟卷会移动到那里结束。

然后我们需要缩放和旋转我们的眼镜以适合每个人的脸。我们将使用从Dlib的68点模型返回的点集来找到眼睛和嘴巴的中心,并为它们之间的空间旋转。

在我们实时获取眼镜和烟卷的最终位置后,眼镜和烟卷从屏幕顶部进入,开始匹配你的眼镜和嘴巴。

假如没有人脸,程序会直接返回你的视频信息,不会有面具移动的效果。

默认一个周期是4秒钟。然后你可以通过"d"键再次检测。

程序退出使用"q"键。

这里我将这个功能抽象成一个面具加载服务,请跟随我的代码一窥究竟吧。1.导入对应的工具包

from time import sleep

import cv2

import numpy as np

from PIL import Image

from imutils import face_utils, resize

try:

from dlib import get_frontal_face_detector, shape_predictor

except ImportError:

raise

创建面具加载服务类DynamicStreamMaskService及其对应的初始化属性:

class DynamicStreamMaskService(object):

"""

动态黏贴面具服务

"""

def __init__(self, saved=False):

self.saved = saved # 是否保存图片

self.listener = True # 启动参数

self.video_capture = cv2.VideoCapture(0) # 调用本地摄像头

self.doing = False # 是否进行面部面具

self.speed = 0.1 # 面具移动速度

self.detector = get_frontal_face_detector() # 面部识别器

self.predictor = shape_predictor("shape_predictor_68_face_landmarks.dat") # 面部分析器

self.fps = 4 # 面具存在时间基础时间

self.animation_time = 0 # 动画周期初始值

self.duration = self.fps * 4 # 动画周期最大值

self.fixed_time = 4 # 画图之后,停留时间

self.max_width = 500 # 图像大小

self.deal, self.text, self.cigarette = None, None, None # 面具对象

按照上面介绍,我们先实现读取视频流转换图片的函数:

def read_data(self):

"""

从摄像头获取视频流,并转换为一帧一帧的图像

:return: 返回一帧一帧的图像信息

"""

_, data = self.video_capture.read()

return data

接下来我们实现人脸定位函数,及眼镜和烟卷的定位:

def get_glasses_info(self, face_shape, face_width):

"""

获取当前面部的眼镜信息

:param face_shape:

:param face_width:

:return:

"""

left_eye = face_shape[36:42]

right_eye = face_shape[42:48]

left_eye_center = left_eye.mean(axis=0).astype("int")

right_eye_center = right_eye.mean(axis=0).astype("int")

y = left_eye_center[1] - right_eye_center[1]

x = left_eye_center[0] - right_eye_center[0]

eye_angle = np.rad2deg(np.arctan2(y, x))

deal = self.deal.resize(

(face_width, int(face_width * self.deal.size[1] / self.deal.size[0])),

resample=Image.LANCZOS)

deal = deal.rotate(eye_angle, expand=True)

deal = deal.transpose(Image.FLIP_TOP_BOTTOM)

left_eye_x = left_eye[0, 0] - face_width // 4

left_eye_y = left_eye[0, 1] - face_width // 6

return {"image": deal, "pos": (left_eye_x, left_eye_y)}

def get_cigarette_info(self, face_shape, face_width):

"""

获取当前面部的烟卷信息

:param face_shape:

:param face_width:

:return:

"""

mouth = face_shape[49:68]

mouth_center = mouth.mean(axis=0).astype("int")

cigarette = self.cigarette.resize(

(face_width, int(face_width * self.cigarette.size[1] / self.cigarette.size[0])),

resample=Image.LANCZOS)

x = mouth[0, 0] - face_width + int(16 * face_width / self.cigarette.size[0])

y = mouth_center[1]

return {"image": cigarette, "pos": (x, y)}

def orientation(self, rects, img_gray):

"""

人脸定位

:return:

"""

faces = []

for rect in rects:

face = {}

face_shades_width = rect.right() - rect.left()

predictor_shape = self.predictor(img_gray, rect)

face_shape = face_utils.shape_to_np(predictor_shape)

face['cigarette'] = self.get_cigarette_info(face_shape, face_shades_width)

face['glasses'] = self.get_glasses_info(face_shape, face_shades_width)

faces.append(face)

return faces

刚才我们提到了键盘监听事件,这里我们实现一下这个函数:

def listener_keys(self):

"""

设置键盘监听事件

:return:

"""

key = cv2.waitKey(1) & 0xFF

if key == ord("q"):

self.listener = False

self.console("程序退出")

sleep(1)

self.exit()

if key == ord("d"):

self.doing = not self.doing

接下来我们来实现加载面具信息的函数:

def init_mask(self):

"""

加载面具

:return:

"""

self.console("加载面具...")

self.deal, self.text, self.cigarette = (

Image.open(x) for x in ["images/deals.png", "images/text.png", "images/cigarette.png"]

)

上面基本的功能都实现了,我们该实现画图函数了,这个函数原理和之前我写的那篇用AI人脸识别技术实现抖音特效实现是一样的,这里我就不赘述了,可以去github或Python中文社区微信公众号查看。

def drawing(self, draw_img, faces):

"""

画图

:param draw_img:

:param faces:

:return:

"""

for face in faces:

if self.animation_time < self.duration - self.fixed_time:

current_x = int(face["glasses"]["pos"][0])

current_y = int(face["glasses"]["pos"][1] * self.animation_time / (self.duration - self.fixed_time))

draw_img.paste(face["glasses"]["image"], (current_x, current_y), face["glasses"]["image"])

cigarette_x = int(face["cigarette"]["pos"][0])

cigarette_y = int(face["cigarette"]["pos"][1] * self.animation_time / (self.duration - self.fixed_time))

draw_img.paste(face["cigarette"]["image"], (cigarette_x, cigarette_y),

face["cigarette"]["image"])

else:

draw_img.paste(face["glasses"]["image"], face["glasses"]["pos"], face["glasses"]["image"])

draw_img.paste(face["cigarette"]["image"], face["cigarette"]["pos"], face["cigarette"]["image"])

draw_img.paste(self.text, (75, draw_img.height // 2 + 128), self.text)

既然是一个服务类,那该有启动与退出函数吧,最后我们来写一下吧。简单介绍一下这个start()函数, 启动后根据初始化监听信息,不断监听视频流,并将流信息通过opencv转换成图像展示出来。

并且调用按键监听函数,不断的监听你是否按下"d"键进行面具加载,如果监听成功,则进行图像人脸检测,并移动面具,

并持续一个周期的时间结束,面具此时会根据你的面部移动而移动。最终呈现文章顶部图片的效果.

def start(self):

"""

启动程序

:return:

"""

self.console("程序启动成功.")

self.init_mask()

while self.listener:

frame = self.read_data()

frame = resize(frame, width=self.max_width)

img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

rects = self.detector(img_gray, 0)

faces = self.orientation(rects, img_gray)

draw_img = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))

if self.doing:

self.drawing(draw_img, faces)

self.animation_time += self.speed

self.save_data(draw_img)

if self.animation_time > self.duration:

self.doing = False

self.animation_time = 0

else:

frame = cv2.cvtColor(np.asarray(draw_img), cv2.COLOR_RGB2BGR)

cv2.imshow("hello mask", frame)

self.listener_keys()

def exit(self):

"""

程序退出

:return:

"""

self.video_capture.release()

cv2.destroyAllWindows()

最后,让我们试试:

if __name__ == '__main__':

ms = DynamicStreamMaskService()

ms.start()

写到这里,这个小功能就已经实现了,大家不妨事来使用一下。

python获取摄像头数据_用Python获取摄像头并实时控制人脸 !相关推荐

  1. python处理行情数据_利用Python脚本来获取期货行情数据

    因为自己最近在学习做期货交易,想要下载期货的行情数据来做分析.有一些交易软件是可以导出数据的,但是导出的过程还是需要很多的手工操作,自己在想能不能通过Python程序来实现呢. 新浪期货数据接口介绍 ...

  2. 如何用python批量下载数据_使用Python批量下载数据

    这次依旧是,不过下载的是Australian Bureau of Statistics的数据,都是xls的表格,网址为:http://www.abs.gov.au.网页打开左边有棵树目录,里面记录的澳 ...

  3. python处理nc数据_利用python如何处理nc数据详解

    利用python如何处理nc数据详解 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  利用python如何处理nc数据详解.txt ] (友情提示:右键点上行txt ...

  4. python处理期货数据_用python中的Pandas库实现一个商品期货网格策略

    Pandas是基于NumPy的一种工具,该工具是为了解决数据分析任务而创建的.Pandas纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具.pandas提供了大量能使我们快速便捷 ...

  5. python读取大智慧数据_用Python抓取大智慧除权数据

    继续做的数据分析,由于新浪获取的是未复权数据,所以在分析的时候出了些小问题,结果变得扑所迷离.于是又用了几天Tushare的获取复权数据功能,本来是写了个循环,每天自动获取,可是几乎每次下载都卡死了, ...

  6. python读取mt4数据_[转载]如何获取MT4完整的历史数据?

    你还在为找不到MT4完整的历史数据发愁吗?本软件将为你获得自2000年1月1日起的任意货币对完整数据!!!终极解决方案!!!!! 一些经纪商的MT4平台数据不全或有缺失,这个MT5脚本能够把MT5终端 ...

  7. python提取wind数据_用Python从wind获取数据,转换成dataframe格式,并保存为Excel文件,excel...

    import openpyxl from openpyxl.workbook import Workbook from WindPy import * from pandas import * imp ...

  8. python如何收集数据_用Python做数据清洗:采集几百个xls或csv中的数据并汇总

    需求:从几百个CSV或xls中读取某些重要数据,并汇总在一个单独的excel中进行数据分析 Python实现: # coding:utf-8 # File Name: csv_data_sort # ...

  9. python检测异常数据_用Python中从头开始的实现完整的异常检测算法

    利用概率的异常检测算法 异常检测可以作为离群分析的统计任务来对待. 但是,如果我们开发一个机器学习模型,它可以自动化,并且像往常一样可以节省大量时间. 有很多异常检测用例. 信用卡欺诈检测,故障机器检 ...

最新文章

  1. python配置opencv最简单_【萌新】面向(Windows10)python的opencv环境配置“个人向”报错总结...
  2. html显示php值,HTML窗体加载显示通过PHP的十六进制值
  3. apache 隐藏php版本,PHP+Apache环境中怎么隐藏Apache版本
  4. GitHub下载文件时缓慢的问题
  5. “3D几何与视觉技术”全球在线研讨会第五期~隐式3D形状表示学习
  6. 数据传输服务 DTS > 产品简介 > 功能特性 > 数据订阅(新版)
  7. 每天一道剑指offer-包含min函数的栈
  8. 红帽全年总营收24亿美元,同比增长18%
  9. 将txt格式的地图导入到ArcMap
  10. codeblocks安装包和主题及中文语言包百度云下载
  11. 如何发布Flash ZXP/MXP扩展
  12. mac删除默认ABC输入法,mac删除自带ABC输入法
  13. icm20602姿态解算
  14. win10+Ubuntu16.04双系统安装及卸载
  15. 想入门自学编程,应该怎么开始?
  16. Android进阶之路 - 毛玻璃遮罩层
  17. 微信小程序使用云函数进行mysql操作
  18. 华宇软件华为鸿蒙,舒华体育携手华为打造:全球首款搭载鸿蒙操作系统跑步机面世...
  19. 【分布式计算】什么是分布式系统
  20. 有趣的数学问题-鸽巢原理

热门文章

  1. 数据增强方法:图片镜像、图片缩放、图片旋转、加噪点
  2. 改变世界的五位程序员
  3. 排序算法之插入排序法
  4. 萧萧雨落情未绝,瑟瑟风起愁又涌
  5. Why That Big Meal You Just Ate Made You Hungry
  6. 第031讲:永久存储,腌制一缸美味的泡菜 | 学习记录(小甲鱼零基础入门学习Python)
  7. 031永久储存:腌制一缸美味的泡菜
  8. 手工实现:SVM with Stochastic Gradient Descent
  9. 【Kubernetes 企业项目实战】05、基于云原生分布式存储 Ceph 实现 K8s 数据持久化(下)
  10. Alpha阶段敏捷冲刺⑥