天池学习-深度学习入门与实践-2.基于人脸的常见表情识别——数据获取与整理

天池学习-深度学习入门与实践-2.基于人脸的常见表情识别——数据获取与整理

这个 Task 会涉及到数据集等文件的下载,请运行以下代码下载相关文件,由于需要对下载的文件进行解压,所以速度会比较慢,请耐心等候。(大概需要 8 分钟左右)

如果你不是第一次运行这个项目,那么就跳过以下代码
print("****************下载文件中。。。")
!wget http://tianchi-media.oss-cn-beijing.aliyuncs.com/dragonball/DL/other/data/Emotion_Recognition_File.zip
print("****************下载完成。。。")
print("****************解压文件中。。。")
!unzip -q -o ./Emotion_Recognition_File.zip -d Emotion_Recognition_File/
print("****************解压完毕***************")

所有下载的文件均在 Emotion_Recognition_File (表情识别的英文名称)文件夹下,以下对各个文件进行说明

img_type_test:放置了不同后缀名的图片,在 3.1 图片格式统一 将会使用到
face_detect_model:放置了人脸检测所需要的模型,在 3.2 数据清洗、3.3 提取嘴唇区域 将会使用到
face_det_img:放置了一些包含人脸的图片和不包含人人脸的图片,在 3.2 数据清洗 将会使用到
mouth_det_img:放置了一些包含人脸的图片,在 3.3 提取嘴唇区域 将会使用到
train_val_data:放置了本训练营为各位读者准备的数据集,将会在下一个 Task 用到
test_img:放置了包含 4 种表情的图片各一张,将会在下一个 Task 用到,我们就是使用这个文件夹里的图片来展示我们的成果

1.项目背景

⼈脸表情识别(facial expression recognition, FER)作为⼈脸识别技术中的⼀个重要组成部分,近年来在⼈机交互、安全、机器⼈制造、⾃动化、医疗、通信和驾驶领域得到了⼴泛的关注,成为学术界和⼯业界的研究热点,是⼈脸属性分析的重点。

2.数据获取

学会使⽤爬⾍爬取图像。
对获得的图⽚数据进⾏整理,包括重命名,格式统⼀。
利⽤⼈脸检测算法删选出有⽤的样本,利⽤关键点检测算法裁剪出⽤于算法训练的嘴唇区域。

免费爬虫深度学习所需爬虫

1 综述类项目与学习资料

1、awesome-spider 地址:awesome-spider
搜集了几乎所有可以爬取的中文网址,从知乎豆瓣到知网,抖音微博到QQ
2、Nyspider 地址:Nyspider
都是各类网址
3、awesome-python-login-model
地址:awesome-python-login-model
模拟各种网址登陆,分析各大网站的登录方式,也包含一些简单的爬虫
4、python-spider
地址:python-spider
包含不少的实战项目
https://github.com/jhao104/proxy_pool
https://github.com/Ehco1996/Python-crawler
2、各大视频网站爬虫
地址:各大视频网站爬虫
Annie是一款以go语言编码的视频下载工具,使用便捷并支持youtube,腾讯视频,抖音等多个网站视频和图像的下载
虽然这个项目可以下载图片,但是我们还是来用它下载视频吧,使用方法很简单:
annie [可选参数]http://… (视频网址)
3、有三AI刚刚开源了一个深度学习项目,如下:
有三AI深度学习项目
内容包含计算机视觉,语音,自然语言处理,支持caffe,tensorflow,pytorch,mxnet,paddlepaddle,darknet,deeplearning4j,matconvnet,keras,chainer,cntk,lasadge等框架

2 优秀图片/视频项目

1、Google,Baidu,Bing三大搜素引擎图片爬虫
地址:https://github.com/sczhengyabin/Image-Downloader
足够满足小型项目初始数据集的积累(爬几千张高质量图片)命名也非常整齐规范,最大的优势就是稳定

2.1 数据爬取(github我没登上去)

本项目使用的爬虫项目是:https://github.com/sczhengyabin/Image-Downloader ,可以按要求爬取百度、Bing、Google 上的图片,提供了非常人性化的 GUI 方便操作,使用方法如下:

  1. 下载爬虫工具
  2. 调用GUI界面,配置好参数(关键词,路径,爬取数目等)python image_downloader_gui.py
  3. 配置需要爬取的样本数目

3.数据整理

数据整理:主要包括统⼀图片后缀重命名
统⼀后缀格式—减少以后写数据 API 时的压⼒、测试图⽚是不是可以正常的读取,及时防⽌未知问题的出现

3.1 图片格式统一

以下代码可以实现对图片格式的统一,我们在 img_type_test 文件下放置了几张测试图片,读者可以运行尝试。『读者也可以上传不同格式(如 jpg、jpeg、png 等)的图片到 img_type_test 文件下,然后运行下面的代码,下面的代码读取每种图片,然后将其转为 jpg 格式,同时会将原始的图片删除』

import os
import sys
import cv2
import numpy as np


def listfiles(rootDir):
    list_dirs = os.walk(rootDir) 
    for root, dirs, files in list_dirs:  # 遍历文件夹下的图片
        for d in dirs:
            print((os.path.join(root, d)))
        for f in files:
            fileid = f.split('.')[0]  # 获得图片的名字,不含后缀
            filepath = os.path.join(root, f) 
            print(filepath)
            try:
                src = cv2.imread(filepath, 1)  # 读取原始图片,数据会加载到内存中
                print("src=", filepath, src.shape)
                os.remove(filepath) # 移除原来的图片
                cv2.imwrite(os.path.join(root, fileid + ".jpg"), src)  # 保存经过格式转换的图片
            except:
                os.remove(filepath)
                continue

path = "./Emotion_Recognition_File/img_type_test/"  # 输入图片路径即可,可以在这个文件夹下放置各种后缀名的图片,代码会将所有图片统一成 jpg 格式
listfiles(path)

ImportErrorTraceback (most recent call last)
in ()
1 import os
2 import sys
----> 3 import cv2
4 import numpy as np
5
ImportError: No module named cv2

3.2 数据清洗

数据清洗—删除不合适的图⽚,即⾮⼈脸的照⽚。
程序进⾏筛选,我们调⽤ OpenCV 的⼈脸检测算法进⾏筛选,代码如下:

# coding:utf8
import cv2
import dlib
import numpy as np
import sys
import os
import matplotlib.pyplot as plt

# 人脸检测的接口,这个是 OpenCV 中自带的
cascade_path = './Emotion_Recognition_File/face_detect_model/haarcascade_frontalface_default.xml'
cascade = cv2.CascadeClassifier(cascade_path)

img_path = "./Emotion_Recognition_File/face_det_img/" # 测试图片路径
images = os.listdir(img_path)
for image in images:
    im = cv2.imread(os.path.join(img_path, image), 1) # 读取图片
    rects = cascade.detectMultiScale(im, 1.3, 5)  # 人脸检测函数
    print("检测到人脸的数量", len(rects))
    if len(rects) == 0:  # len(rects) 是检测人脸的数量,如果没有检测到人脸的话,会显示出图片,适合本地调试使用,在服务器上可能不会显示
#         cv2.namedWindow('Result', 0)
#         cv2.imshow('Result', im)
#         print("没有检测到人脸")
        pass
    plt.imshow(im[:, :, ::-1])  # 显示
    plt.show()
#         os.remove(os.path.join(img_path, image)) # 
#         k = cv2.waitKey(0)
#         if k == ord('q'): # 在英文状态下,按下按键 q 会关闭显示窗口    
#             break
#     print()
# cv2.destroyAllWindows()   

利⽤⼈脸检测算法仍然⽆法清除⼲净样本—⼿动筛选
当然如果你使⽤多个关键词或者使⽤不同的搜索引擎同样的关键词,或者从视频中提取图⽚,那么爬取回来的图⽚很可能有重复或者⾮常的相似—去重

3.3 提取嘴唇区域

将样本处理成我们真正训练所需要的图像,本任务只对嘴唇部分的表情进⾏识别,所以我们的目标就是获取人脸嘴唇区域的图像,然后进行分类。
我们利⽤ Opencv+Dlib 算法提取嘴唇区域, Dlib 算法会得到⾯部的 68 个关键点,我们从中得到嘴唇区域,并适当扩⼤。

人脸 68 点位置图如下:
在这里插入图片描述
代码对图片进行人脸检测,检测到人脸后,会将嘴巴区域分割出来,形成数据集

# coding:utf8

import cv2
import dlib
import numpy as np
import sys
import os
import matplotlib.pyplot as plt

# 配置 Dlib 关键点检测路径
# 文件可以从 http://dlib.net/files/ 下载
PREDICTOR_PATH = "./Emotion_Recognition_File/face_detect_model/shape_predictor_68_face_landmarks.dat"
predictor = dlib.shape_predictor(PREDICTOR_PATH)
# 配置人脸检测器路径
cascade_path = './Emotion_Recognition_File/face_detect_model/haarcascade_frontalface_default.xml'
cascade = cv2.CascadeClassifier(cascade_path)

# 调用 cascade.detectMultiScale 人脸检测器和 Dlib 的关键点检测算法 predictor 获得关键点结果
def get_landmarks(im):
    rects = cascade.detectMultiScale(im, 1.3, 5) # 人脸检测
    x, y, w, h = rects[0]  # 获取人脸的四个属性值,左上角坐标 x,y 、高宽 w、h
#     print(x, y, w, h)
    rect = dlib.rectangle(int(x), int(y), int(x + w), int(y + h)) 
    return np.matrix([[p.x, p.y] for p in predictor(im, rect).parts()])


def annotate_landmarks(im, landmarks):
    im = im.copy()
    for idx, point in enumerate(landmarks):
        pos = (point[0, 0], point[0, 1])
        cv2.putText(im,
                    str(idx),
                    pos,
                    fontFace=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,
                    fontScale=0.4,
                    color=(0, 0, 255))
        cv2.circle(im, pos, 5, color=(0, 255, 255))
    return im


def getlipfromimage(im, landmarks):
    xmin = 10000
    xmax = 0
    ymin = 10000
    ymax = 0
    # 根据最外围的关键点获取包围嘴唇的最小矩形框
    # 68 个关键点是从
    # 左耳朵0 -下巴-右耳朵16-左眉毛(17-21)-右眉毛(22-26)-左眼睛(36-41)
    # 右眼睛(42-47)-鼻子从上到下(27-30)-鼻孔(31-35)
    # 嘴巴外轮廓(48-59)嘴巴内轮廓(60-67)
    for i in range(48, 67):
        x = landmarks[i, 0]
        y = landmarks[i, 1]
        if x < xmin:
            xmin = x
        if x > xmax:
            xmax = x
        if y < ymin:
            ymin = y
        if y > ymax:
            ymax = y

    print("xmin=", xmin)
    print("xmax=", xmax)
    print("ymin=", ymin)
    print("ymax=", ymax)

    roiwidth = xmax - xmin
    roiheight = ymax - ymin

    roi = im[ymin:ymax, xmin:xmax, 0:3]
    if roiwidth > roiheight:
        dstlen = 1.5 * roiwidth
    else:
        dstlen = 1.5 * roiheight

    diff_xlen = dstlen - roiwidth
    diff_ylen = dstlen - roiheight

    newx = xmin
    newy = ymin

    imagerows, imagecols, channel = im.shape
    if newx >= diff_xlen / 2 and newx + roiwidth + diff_xlen / 2 < imagecols:
        newx = newx - diff_xlen / 2
    elif newx < diff_xlen / 2:
        newx = 0
    else:
        newx = imagecols - dstlen

    if newy >= diff_ylen / 2 and newy + roiheight + diff_ylen / 2 < imagerows:
        newy = newy - diff_ylen / 2
    elif newy < diff_ylen / 2:
        newy = 0
    else:
        newy = imagerows - dstlen

    roi = im[int(newy):int(newy + dstlen), int(newx):int(newx + dstlen), 0:3]
    return roi


def listfiles(rootDir):
    list_dirs = os.walk(rootDir)
    for root, dirs, files in list_dirs:
        for d in dirs:
            print(os.path.join(root, d))
        for f in files:
            fileid = f.split('.')[0]

            filepath = os.path.join(root, f)
            try:
                im = cv2.imread(filepath, 1)
                landmarks = get_landmarks(im)
                roi = getlipfromimage(im, landmarks)
                roipath = filepath.replace('.jpg', '_mouth.png')
#                 cv2.imwrite(roipath, roi)
                plt.imshow(roi[:, :, ::-1])
                plt.show()
            except:
#                 print("error")
                continue


listfiles("./Emotion_Recognition_File/mouth_det_img/")

每种表情放置在各自的文件夹下并命名在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

-KWOK-

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

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

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

打赏作者

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

抵扣说明:

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

余额充值