实践教程|OpenCV + OpenVINO实现人脸AR – 给人脸戴上口罩

2021 年 11 月 25 日 极市平台
↑ 点击 蓝字  关注极市平台

作者丨gloomy fish
来源丨OpenCV学堂
编辑丨极市平台

极市导读

 

本文作者实用OpenVINO实现了一个简单的自动给人脸带上口罩的AR演示,附相关代码。 >>加入极市CV技术交流群,走在计算机视觉的最前沿

前言

最近在看我之前的写的一篇关于人脸landmark的文章,里面有提到OpenVINO自带模型人脸的35个点位,有人问我这个landmark检测有什么用,我斗胆抛砖引玉一下,做了个简单的自动戴口罩的AR演示。

模型介绍

用到两个OpenVINO模型,分别是:

face-detection-0204  人脸检测
facial-landmarks-35-adas-0002  landmark检测35点

face-detection-0204模型的输入与输出格式如下:

输入:1x3x448x448, BGR顺序
输出:1x1x200x7

facial-landmarks-35-adas-0002模型的输入与输出格式如下:

输入:1x3x60x60
输出:1x70

其中70是35个点的xy坐标,取值范围在0~1之间

代码实现

代码实现部分首先检测人脸,然后截取人脸的ROI区域,检测35点landmark坐标,选择(18,34)或者(19、33)两个点位作为起始位置,与对应口罩图象对齐,高度选编码26的点,这样计算X与Y方向的放缩比率,完成对齐,然后贴图口罩到指定的人脸区域。

其中人脸检测的代码如下:

# Read IR
net = ie.read_network(model=face_xml, weights=face_bin)

input_blob = next(iter(net.input_info))
out_blob = next(iter(net.outputs))

# 输入设置
n, c, h, w = net.input_info[input_blob].input_data.shape

# 设备关联推理创建
exec_net = ie.load_network(network=net, device_name="CPU")

# 加载landmark模型并设置
landmark_net = ie.read_network(model=landmark_35_xml, weights=landmark_35_bin)
landmark_input_blob = next(iter(landmark_net.input_info))
landmark_out_blob = next(iter(landmark_net.outputs))

# 输入设置
pn, pc, ph, pw = landmark_net.input_info[landmark_input_blob].input_data.shape

# 设备关联推理创建
landmark_exec_net = ie.load_network(network=landmark_net, device_name="CPU")

src = cv.imread("D:/1.jpg")
image = cv.resize(src, (w, h))
image = image.transpose(2, 0, 1)

# 推理
prob = exec_net.infer(inputs={input_blob: [image]})

# 后处理
ih, iw, ic = src.shape
res = prob[out_blob]
if res.ndim == 4:  # SSD
    for obj in res[0][0]:
        if obj[2] > 0.5:
            xmin = int(obj[3] * iw) - 15
            ymin = int(obj[4] * ih) - 15
            xmax = int(obj[5] * iw) + 15
            ymax = int(obj[6] * ih) + 15
            if xmin < 0:
                xmin = 0
            if ymin < 0:
                ymin = 0
            if xmax >= iw:
                xmax = iw - 1
            if ymax >= ih:
                ymax = ih - 1
            roi = src[ymin:ymax, xmin:xmax, :]
            infer_landmark(roi, landmark_exec_net, landmark_input_blob, landmark_out_blob, pw, ph)
            # cv.rectangle(src, (xmin, ymin), (xmax, ymax), (0, 255, 255), 2, 8)
            # cv.putText(src, str("%.3f" % obj[2]), (xmin, ymin), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1, 8)
cv.imshow("Face AR Demo", src)

Landmark检测的方法代码如下:

def infer_landmark(faceImg, landmark_exe_net, input_name, output_name, pw, ph):
    # 处理输入图象
    rh, rw, rc = faceImg.shape
    roi = cv.resize(faceImg, (pw, ph))
    roi = roi.transpose(2, 0, 1)

    # 推理
    prob = landmark_exe_net.infer(inputs={input_name: [roi]})
    landmarks = prob[output_name]
    pts = np.reshape(landmarks, (-1, 2))

对齐口罩图象与贴图代码如下:

# 寻找点位
for idx, pt in enumerate(pts):
    if idx == 18:
        left_x = 0 # int(pt[0] * rw)
        left_y = int(pt[1] * rh)
        # cv.circle(faceImg, (left_x, left_y), 1, (255, 0, 255), 2, 8, 0)
    if idx == 34:
        right_x = (rw - 1) # int(pt[0] * rw)
        right_y = int(pt[1] * rh)
        # cv.circle(faceImg, (right_x, right_y), 1, (255, 0, 255), 2, 8, 0)
    if idx == 26:
        p26_x = int(pt[0] * rw)
        p26_y = int(pt[1] * rh)

# 对齐与放缩
dx_t = right_x - left_x
dx_m = anchor_pts[2] - anchor_pts[0]
rate_x = dx_t / dx_m
rate_y = (p26_y - left_y) / (anchor_pts[3] - anchor_pts[1])
dst_mask = cv.resize(mask, (0, 0), fx=rate_x, fy=rate_y)
start_x = np.int(anchor_pts[0] * rate_x);
start_y = np.int(anchor_pts[1] * rate_y);
end_x = np.int(anchor_pts[2] * rate_x)
end_y = np.int(anchor_pts[3] * rate_y)

# 贴图
for row in range(end_y - start_y):
    for col in range(end_x - start_x):
        b2, g2, r2 = dst_mask[start_y+row, start_x+col]
        if b2 < 127 and g2 < 127 and r2 < 127:
            faceImg[row+left_y, left_x+col] = ( b2, g2, r2)

最终运行结果如下:

如果觉得有用,就请分享到朋友圈吧!

△点击卡片关注极市平台,获取 最新CV干货

公众号后台回复“transformer”获取最新Transformer综述论文下载~


极市干货
课程/比赛: 珠港澳人工智能算法大赛 保姆级零基础人工智能教程
算法trick 目标检测比赛中的tricks集锦 从39个kaggle竞赛中总结出来的图像分割的Tips和Tricks
技术综述: 一文弄懂各种loss function 工业图像异常检测最新研究总结(2019-2020)


CV技术社群邀请函 #

△长按添加极市小助手
添加极市小助手微信(ID : cvmart4)

备注:姓名-学校/公司-研究方向-城市(如:小极-北大-目标检测-深圳)


即可申请加入极市目标检测/图像分割/工业检测/人脸/医学影像/3D/SLAM/自动驾驶/超分辨率/姿态估计/ReID/GAN/图像增强/OCR/视频理解等技术交流群


每月大咖直播分享、真实项目需求对接、求职内推、算法竞赛、干货资讯汇总、与 10000+来自港科大、北大、清华、中科院、CMU、腾讯、百度等名校名企视觉开发者互动交流~



觉得有用麻烦给个在看啦~   
登录查看更多
2

相关内容

一个跨平台的计算机视觉处理库,全称是Open Source Computer Vision。
Linux导论,Introduction to Linux,96页ppt
专知会员服务
77+阅读 · 2020年7月26日
【ICIP2019教程-NVIDIA】图像到图像转换,附7份PPT下载
专知会员服务
53+阅读 · 2019年11月20日
【书籍】深度学习框架:PyTorch入门与实践(附代码)
专知会员服务
163+阅读 · 2019年10月28日
实践教程 | 轻松入门模型转换和可视化
极市平台
0+阅读 · 2022年3月5日
实践教程|使用 OpenCV 进行虚拟缩放
极市平台
0+阅读 · 2022年2月28日
实践教程|最简单的代码实现语义分割!
极市平台
0+阅读 · 2022年2月18日
实操教程|基于OpenCV的条形码区域分割
极市平台
3+阅读 · 2022年2月7日
OpenVINO部署Mask-RCNN实例分割网络
极市平台
0+阅读 · 2022年1月27日
实践教程 | 浅谈 PyTorch 中的 tensor 及使用
极市平台
1+阅读 · 2021年12月14日
keras实战︱人脸表情分类与识别:人脸检测+情绪分类
数据挖掘入门与实战
21+阅读 · 2017年12月16日
Caffe 深度学习框架上手教程
黑龙江大学自然语言处理实验室
14+阅读 · 2016年6月12日
国家自然科学基金
0+阅读 · 2015年12月31日
国家自然科学基金
1+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2011年12月31日
国家自然科学基金
0+阅读 · 2009年12月31日
Arxiv
0+阅读 · 2022年4月20日
Arxiv
0+阅读 · 2022年4月18日
Deep Face Recognition: A Survey
Arxiv
18+阅读 · 2019年2月12日
VIP会员
相关资讯
实践教程 | 轻松入门模型转换和可视化
极市平台
0+阅读 · 2022年3月5日
实践教程|使用 OpenCV 进行虚拟缩放
极市平台
0+阅读 · 2022年2月28日
实践教程|最简单的代码实现语义分割!
极市平台
0+阅读 · 2022年2月18日
实操教程|基于OpenCV的条形码区域分割
极市平台
3+阅读 · 2022年2月7日
OpenVINO部署Mask-RCNN实例分割网络
极市平台
0+阅读 · 2022年1月27日
实践教程 | 浅谈 PyTorch 中的 tensor 及使用
极市平台
1+阅读 · 2021年12月14日
keras实战︱人脸表情分类与识别:人脸检测+情绪分类
数据挖掘入门与实战
21+阅读 · 2017年12月16日
Caffe 深度学习框架上手教程
黑龙江大学自然语言处理实验室
14+阅读 · 2016年6月12日
相关基金
国家自然科学基金
0+阅读 · 2015年12月31日
国家自然科学基金
1+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2011年12月31日
国家自然科学基金
0+阅读 · 2009年12月31日
Top
微信扫码咨询专知VIP会员