竞赛 深度学习人脸表情识别算法 - opencv python 机器视觉

news2024/11/16 11:33:10

文章目录

  • 0 前言
  • 1 技术介绍
    • 1.1 技术概括
    • 1.2 目前表情识别实现技术
  • 2 实现效果
  • 3 深度学习表情识别实现过程
    • 3.1 网络架构
    • 3.2 数据
    • 3.3 实现流程
    • 3.4 部分实现代码
  • 4 最后

0 前言

🔥 优质竞赛项目系列,今天要分享的是

🚩 深度学习人脸表情识别系统

该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:4分

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

1 技术介绍

1.1 技术概括

面部表情识别技术源于1971年心理学家Ekman和Friesen的一项研究,他们提出人类主要有六种基本情感,每种情感以唯一的表情来反映当时的心理活动,这六种情感分别是愤怒(anger)、高兴(happiness)、悲伤
(sadness)、惊讶(surprise)、厌恶(disgust)和恐惧(fear)。

尽管人类的情感维度和表情复杂度远不是数字6可以量化的,但总体而言,这6种也差不多够描述了。

在这里插入图片描述

1.2 目前表情识别实现技术

在这里插入图片描述
在这里插入图片描述

2 实现效果

废话不多说,先上实现效果

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3 深度学习表情识别实现过程

3.1 网络架构

在这里插入图片描述
面部表情识别CNN架构(改编自 埃因霍芬理工大学PARsE结构图)

其中,通过卷积操作来创建特征映射,将卷积核挨个与图像进行卷积,从而创建一组要素图,并在其后通过池化(pooling)操作来降维。

在这里插入图片描述

3.2 数据

主要来源于kaggle比赛,下载地址。
有七种表情类别: (0=Angry, 1=Disgust, 2=Fear, 3=Happy, 4=Sad, 5=Surprise, 6=Neutral).
数据是48x48 灰度图,格式比较奇葩。
第一列是情绪分类,第二列是图像的numpy,第三列是train or test。

在这里插入图片描述

3.3 实现流程

在这里插入图片描述

3.4 部分实现代码



    import cv2
    import sys
    import json
    import numpy as np
    from keras.models import model_from_json

    emotions = ['angry', 'fear', 'happy', 'sad', 'surprise', 'neutral']
    cascPath = sys.argv[1]
    
    faceCascade = cv2.CascadeClassifier(cascPath)
    noseCascade = cv2.CascadeClassifier(cascPath)

    # load json and create model arch
    json_file = open('model.json','r')
    loaded_model_json = json_file.read()
    json_file.close()
    model = model_from_json(loaded_model_json)
    
    # load weights into new model
    model.load_weights('model.h5')
    
    # overlay meme face
    def overlay_memeface(probs):
        if max(probs) > 0.8:
            emotion = emotions[np.argmax(probs)]
            return 'meme_faces/{}-{}.png'.format(emotion, emotion)
        else:
            index1, index2 = np.argsort(probs)[::-1][:2]
            emotion1 = emotions[index1]
            emotion2 = emotions[index2]
            return 'meme_faces/{}-{}.png'.format(emotion1, emotion2)
    
    def predict_emotion(face_image_gray): # a single cropped face
        resized_img = cv2.resize(face_image_gray, (48,48), interpolation = cv2.INTER_AREA)
        # cv2.imwrite(str(index)+'.png', resized_img)
        image = resized_img.reshape(1, 1, 48, 48)
        list_of_list = model.predict(image, batch_size=1, verbose=1)
        angry, fear, happy, sad, surprise, neutral = [prob for lst in list_of_list for prob in lst]
        return [angry, fear, happy, sad, surprise, neutral]
    
    video_capture = cv2.VideoCapture(0)
    while True:
        # Capture frame-by-frame
        ret, frame = video_capture.read()
    
        img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY,1)

        faces = faceCascade.detectMultiScale(
            img_gray,
            scaleFactor=1.1,
            minNeighbors=5,
            minSize=(30, 30),
            flags=cv2.cv.CV_HAAR_SCALE_IMAGE
        )
    
        # Draw a rectangle around the faces
        for (x, y, w, h) in faces:
    
            face_image_gray = img_gray[y:y+h, x:x+w]
            filename = overlay_memeface(predict_emotion(face_image_gray))
    
            print filename
            meme = cv2.imread(filename,-1)
            # meme = (meme/256).astype('uint8')
            try:
                meme.shape[2]
            except:
                meme = meme.reshape(meme.shape[0], meme.shape[1], 1)
            # print meme.dtype
            # print meme.shape
            orig_mask = meme[:,:,3]
            # print orig_mask.shape
            # memegray = cv2.cvtColor(orig_mask, cv2.COLOR_BGR2GRAY)
            ret1, orig_mask = cv2.threshold(orig_mask, 10, 255, cv2.THRESH_BINARY)
            orig_mask_inv = cv2.bitwise_not(orig_mask)
            meme = meme[:,:,0:3]
            origMustacheHeight, origMustacheWidth = meme.shape[:2]
    
            roi_gray = img_gray[y:y+h, x:x+w]
            roi_color = frame[y:y+h, x:x+w]
    
            # Detect a nose within the region bounded by each face (the ROI)
            nose = noseCascade.detectMultiScale(roi_gray)
    
            for (nx,ny,nw,nh) in nose:
                # Un-comment the next line for debug (draw box around the nose)
                #cv2.rectangle(roi_color,(nx,ny),(nx+nw,ny+nh),(255,0,0),2)
    
                # The mustache should be three times the width of the nose
                mustacheWidth =  20 * nw
                mustacheHeight = mustacheWidth * origMustacheHeight / origMustacheWidth
    
                # Center the mustache on the bottom of the nose
                x1 = nx - (mustacheWidth/4)
                x2 = nx + nw + (mustacheWidth/4)
                y1 = ny + nh - (mustacheHeight/2)
                y2 = ny + nh + (mustacheHeight/2)
    
                # Check for clipping
                if x1 < 0:
                    x1 = 0
                if y1 < 0:
                    y1 = 0
                if x2 > w:
                    x2 = w
                if y2 > h:
                    y2 = h

                # Re-calculate the width and height of the mustache image
                mustacheWidth = (x2 - x1)
                mustacheHeight = (y2 - y1)
    
                # Re-size the original image and the masks to the mustache sizes
                # calcualted above
                mustache = cv2.resize(meme, (mustacheWidth,mustacheHeight), interpolation = cv2.INTER_AREA)
                mask = cv2.resize(orig_mask, (mustacheWidth,mustacheHeight), interpolation = cv2.INTER_AREA)
                mask_inv = cv2.resize(orig_mask_inv, (mustacheWidth,mustacheHeight), interpolation = cv2.INTER_AREA)
    
                # take ROI for mustache from background equal to size of mustache image
                roi = roi_color[y1:y2, x1:x2]
    
                # roi_bg contains the original image only where the mustache is not
                # in the region that is the size of the mustache.
                roi_bg = cv2.bitwise_and(roi,roi,mask = mask_inv)
    
                # roi_fg contains the image of the mustache only where the mustache is
                roi_fg = cv2.bitwise_and(mustache,mustache,mask = mask)
    
                # join the roi_bg and roi_fg
                dst = cv2.add(roi_bg,roi_fg)
    
                # place the joined image, saved to dst back over the original image
                roi_color[y1:y2, x1:x2] = dst
    
                break
    
        #     cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
        #     angry, fear, happy, sad, surprise, neutral = predict_emotion(face_image_gray)
        #     text1 = 'Angry: {}     Fear: {}   Happy: {}'.format(angry, fear, happy)
        #     text2 = '  Sad: {} Surprise: {} Neutral: {}'.format(sad, surprise, neutral)
        #
        # cv2.putText(frame, text1, (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 3)
        # cv2.putText(frame, text2, (50, 150), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 3)
    
        # Display the resulting frame
        cv2.imshow('Video', frame)
    
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    
    # When everything is done, release the capture
    video_capture.release()
    cv2.destroyAllWindows()

需要完整代码以及学长训练好的模型,联系学长获取

4 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1130409.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ARM 汇编指令 orreq 的使用

orreq 阅读代码时&#xff0c;发现有个【组合指令】 orreq&#xff0c; orr 一般是 OR&#xff0c;也就是或操作&#xff0c;后面加个 eq 表示什么呢&#xff1f; 比如下面的代码&#xff1a;前面一个操作&#xff0c; tst&#xff0c;好像没做实际的操作&#xff0c;可能影响…

使用docker-compose私有化部署 GitLab

在软件开发和协作过程中&#xff0c;版本控制是至关重要的一环。GitLab 是一个功能强大的开源平台&#xff0c;提供了完整的代码管理功能&#xff0c;包括版本控制、问题跟踪以及持续集成等。这使得团队能够更高效地协作开发。前段时间翻阅笔记时&#xff0c;偶然发现了之前公司…

wf-docker集群搭建(未完结)

系列文章目录 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一、redis集群二、mysql集群三、nacos集群1. 环境要求2. 拉取镜像2.1. 拉取镜像方式配置集群2.2. 自定义nacos镜像配置集群 3 自定义…

怎么选择好的游戏平台开发商?

选择好的游戏平台开发商需要考虑以下几个方面&#xff1a; 开发经验 了解游戏开发公司的历史和经验是找到靠谱公司的重要步骤。查看公司的官方网站、社交媒体账号等渠道&#xff0c;了解公司的发展历程、团队规模、客户案例等。同时&#xff0c;了解公司是否有相关的游戏开发经…

创建 Edge 浏览器扩展教程(下)

创建 Edge 浏览器扩展教程&#xff08;下&#xff09; 创建扩展教程&#xff0c;第 2 部分1&#xff1a;更新弹出窗口.html以包含按钮2&#xff1a;更新弹出窗口.html在浏览器选项卡顶部显示图像3&#xff1a;创建弹出式 JavaScript 以发送消息4&#xff1a;从任何浏览器选项卡…

python爬虫分析基于python图书馆书目推荐数据分析与可视化

收藏关注不迷路 文章目录 前言一、项目介绍二、开发环境三、功能介绍四、核心代码五、效果图六、文章目录 前言 随着电子技术的普及和快速发展&#xff0c;线上管理系统被广泛的使用&#xff0c;有很多商业机构都在实现电子信息化管理&#xff0c;图书推荐也不例外&#xff0c…

AI智能监控平台EasyCVR+无人机方案:实时全景无死角全方面助力山区安防系统新升级

无人机作为高速发展的高科技设备&#xff0c;技术日趋成熟&#xff0c;目前已经被广泛应用于农业、森林防护、医疗、交通物流等等场景。但随着城市化进程的加快&#xff0c;人类对自然环境日益严重的破坏&#xff0c;近十几年来&#xff0c;森林火灾的发生频率和失火严重程度一…

设计模式(12)状态模式

参考【设计模式】用Java实现状态模式_java 状态模式_卷帘的博客-CSDN博客 一、介绍&#xff1a; 1、状态模式&#xff1a;是一种行为设计模式&#xff0c;它允许对象在内部状态发生改变时改变其行为。该模式将对象的行为包装在不同的状态类中&#xff0c;使得对象的行为可以根…

Node编写重置用户密码接口

目录 前言 定义路由和处理函数 验证表单数据 实现重置密码功能 前言 接前面文章&#xff0c;本文介绍如何编写重置用户密码接口 定义路由和处理函数 路由 // 重置密码的路由 router.post(/updatepwd, userinfo_handler.updatePassword) 处理函数 exports.updatePasswo…

python造测试数据存到excel

代码&#xff1a; from ExcelHandler import ExcelHandler from faker import Faker # 导入faker库的Faker方法 # ↓默认为en_US&#xff0c;只有使用了相关语言才能生成相对应的随机数据 fkFaker(locale"zh_CN")def create_date():m int(input(请输入要造的数据条…

Zabbix“专家坐诊”第208期问答汇总

问题一 Q&#xff1a;请问大佬们&#xff0c;我的测试机部署了2个版本的zabbix服务端&#xff0c;在启动第二个的时候报这个错&#xff0c;请问这个路径能在配置文件修改吗&#xff1f; SYJKLiLB64dded94d3c0c.png A&#xff1a;报错是你的进程存在&#xff0c;无法启动。一个…

【深蓝学院】手写VIO第8章--相机与IMU时间戳同步--笔记

0. 内容 1. 时间戳同步问题及意义 时间戳同步的原因&#xff1a;如果不同步&#xff0c;由于IMU频率高&#xff0c;可能由于时间戳不同步而导致在两帧camera之间的时间内用多了或者用少了IMU的数据&#xff0c;且时间不同步会导致我们首尾camera和IMU数据时间不同&#xff0c;…

docker和K8S环境xxl-job定时任务不执行问题总结

文章目录 xxl-job 任务调度原理1 问题1 时区导致的任务没有执行的问题解决方案 2 执行器注册和下线导致的问题&#xff08;IP问题&#xff09;解决方案 3 问题3 调度成功&#xff0c;但是执行器的定时任务未执行4 问题4 数据库性能问题&#xff0c;导致查询任务和操作日志数据卡…

I/O 模型学习笔记【全面理解BIO/NIO/AIO】

文章目录 I/O 模型什么是 I/O 模型Java支持3种I/O模型BIO&#xff08;Blocking I/O&#xff09;NIO&#xff08;Non-blocking I/O&#xff09;AIO&#xff08;Asynchronous I/O&#xff09; BIO、NIO、AIO适用场景分析 java BIOJava BIO 基本介绍Java BIO 编程流程一个栗子实现…

Unity使用c#开发apk项目(十九)(Failed to find entry-points:System.Exception: )

文章目录 前言解决方案:1.报警信息如下2.选择3d urp3.引入Fusion之后选择包管理,点击Burst中的Advanced Project Settings4.勾选两个预设选项5.引入官网unity.burst6.更新后报警消失前言 制作局域网游戏,出现未找到进入点报警 Failed to find entry-points 解决方案: 1.报…

二十二、设计模式之访问者模式

目录 二十二、设计模式之访问者模式能帮我们干什么&#xff1f;主要解决什么问题&#xff1f;特点 优缺点优点缺点&#xff1a; 使用的场景角色实现访问者模式 总结 二十二、设计模式之访问者模式 所属类型定义行为型表示一个作用于某对象结构中的各元素的操作。它使你可以在不…

【学习笔记】Git开发流程

Git开发大致流程图&#xff1a; 具体流程&#xff1a; 首先一个从仓库的main分支&#xff0c;然后从main分支中拉一个功能分支feature/xxx&#xff0c;在多人开发这个功能的时候拉去自己的个人分支比如&#xff1a;xxx/xxx 。然后每天开发完个人分支后压缩commit&#xff0c;…

flask连接sqllite,并进行一些基本的增删改查操作

flask连接sqllite&#xff0c;并进行一些基本的增删改查操作 &#x1f607;博主简介&#xff1a;我是一名正在攻读研究生学位的人工智能专业学生&#xff0c;我可以为计算机、人工智能相关本科生和研究生提供排忧解惑的服务。如果您有任何问题或困惑&#xff0c;欢迎随时来交流…

docker部署prometheus+grafana服务器监控(三) - 配置grafana

查看 prometheus 访问 http://ip:9090/targets&#xff0c;效果如下&#xff0c;上面我们通过 node_exporter 收集的节点状态是 up 状态。 配置 Grafana 访问 http://ip:3000&#xff0c;登录 Grafana&#xff0c;默认的账号密码是 admin:admin&#xff0c;首次登录需要修改…

【STM32】HAL库ADC多通道精准测量(采用VREFINT内部参考电压)

【STM32】HAL库ADC多通道精准测量&#xff08;采用VREFINT内部参考电压&#xff09; 文章目录 多通道测量VREFINTADC采样周期多通道配置 附录&#xff1a;Cortex-M架构的SysTick系统定时器精准延时和MCU位带操作SysTick系统定时器精准延时延时函数阻塞延时非阻塞延时 位带操作…