基于表情识别的智能灯控-树莓派实现

2023-10-29


前言

这是我之前做的一个嵌入式课设项目,主要功能就是识别人的表情控制灯具的亮度,表情变化越激烈灯具亮度就越高
依赖的项目有:

依赖的库

  • requests
  • pytorch
  • pandas
  • adafruit_ssd1306
  • RPi.GPIO(树莓派自带)
  • PIL

一、项目简介

项目思路

面部表情识别是深度学习的一种应用,通过这种技术,可以使得机器判断出当前使用者的大致心理状态,以此做出合理的决策。

使用摄像头捕捉面部图片,通过神经网络来对表情进行分类(共7类),将预测结果乘以正规矩阵,可以得到一个0-100的值,以此作为灯具的亮度。

灯具的亮度使用PWM控制

软硬件清单

  • Raspberry Pi 3B+(OS:Ubuntu For PI aarch64架构)
  • Raspberry Camera Rev1.3
  • I2C SSD1306 OLED屏幕(128*64)
  • 面包板、电阻、LED若干

原理图

在这里插入图片描述


接线图

在这里插入图片描述


实物图

在这里插入图片描述


二、代码与详解

1.获取天气、IP模块

文件名 data_source.py

"""
获取信息的库
"""
from typing import Union
import subprocess
import json
from typing import Union
import requests
import time

city_weather_url = 'http://www.weatherol.cn/api/home/getCurrAnd15dAnd24h'
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'


def get_ip() -> Union[None, str]:
    """
    获得IP
    """
    IP = None
    cmd = "hostname -I | cut -d' ' -f1"
    IP = subprocess.check_output(cmd, shell=True).decode("utf-8")
    return IP

# 上一次请求的时间
last_time = 0
# 储存天气
last_weather = None
# 重新请求的时间间隔
recall_time = 60 * 10


def get_weather() -> Union[None, dict]:
    global last_time, last_weather, recall_time
    city_id = '101180301'
    params = {
        'cityid': city_id
    }
    now_time = time.time()

    # 达到重新请求的时间
    if now_time - last_time > recall_time:
        try:
            print('调用了天气接口')
            response = requests.get(url=city_weather_url, headers=get_headers(), params=params, timeout=5)
            weather_json = response.text
            weather_data = json.loads(weather_json)
            weather_dict = parse_data(weather_data)
            # 有网络,调用成功
            last_weather = weather_dict
            recall_time = 60 * 10 # 10分钟后再次请求
        except:
            # 无网络调用失败
            last_weather = None

        last_time = now_time  # 更新时间

        if last_weather == None:
            recall_time = 45 # 请求失败,45秒后再次请求

    return last_weather


def get_headers():
    headers = {
        'user_agent': user_agent
    }
    return headers

def parse_data(weather_data):
    ret_dict = {}
    weather = weather_data['data']['current']['current']['weather']
    ret_dict['temperature'] = weather_data['data']['current']['current']['temperature']
    ret_dict['humidity'] = weather_data['data']['current']['current']['humidity'] + '%'
    ret_dict['air'] = weather_data['data']['current']['air']['AQI']
    # print(weather)
    mapping = {
        '雨': 'rain',
        '阴': 'cloudy',
        '云': 'cloudy',
        '晴': 'fine',
        '雾': 'fog',
        '冰': 'ice',
        '尘': 'sand',
    }
    # 对应出英文
    for key in mapping.keys():
        if key in weather:
            weather = mapping[key]
    ret_dict['weather'] = weather
    return ret_dict


def test():
    print(get_weather())

# test()

该模块可以获取当地的天气
get_weather()函数会返回当地的天气、气温、湿度、温度
该模块在有网络的情况下10分钟刷新一次,无网络则每隔45秒重新请求
在没有达到更新时间的情况下,该模块会返回缓存中的数据


2.gpio控制模块

文件名gpio.py

"""
操作硬件GPIO的库
"""
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
LIGHT = 21
ONILEN = 20
LIGHT_PWM = None
ONILEN_PWM = None

def init_gpio():
    """
    初始化使用的GPIO
    """
    global LIGHT_PWM, ONILEN_PWM

    GPIO.setup(LIGHT, GPIO.OUT)
    GPIO.output(LIGHT, GPIO.LOW)
    GPIO.setup(ONILEN, GPIO.OUT)
    GPIO.output(ONILEN, GPIO.HIGH)

    LIGHT_PWM = GPIO.PWM(LIGHT, 100)
    ONILEN_PWM = GPIO.PWM(ONILEN, 0.5)
    ONILEN_PWM.start(80)
    LIGHT_PWM.start(0)
    


def set_online_led(flag):
    """
    设置网络指示灯亮灭
    """
    # 无网络
    if flag is None:
        # 闪烁指示灯
        ONILEN_PWM.ChangeFrequency(0.5)
    else:
        # 指示灯常亮
        ONILEN_PWM.ChangeFrequency(50)



def set_light_led(level):
    """
    设置灯具亮度
    """
    dc = 100 - level
    LIGHT_PWM.ChangeDutyCycle(dc)


def colse_all():
    """
    清除所有接口设置
    """
    # print('close!!!')
    GPIO.cleanup()
    ONILEN_PWM.stop()
    LIGHT_PWM.stop()

硬件共有两个灯具,主灯具light_led和指示网络状态的灯具online_led,该模块设计的目的就是控制这两个led灯
当网络连接时,online_led常亮,否则闪烁


3.表情识别模块

文件名:

  • my_face.py
  • my_utils.py
  • train_model.py

代码与略,详细见:深度学习项目,使用python进行表情识别,pytorch应用

my_utils中的函数cvt_R2N(result)将神经网络输出的(1*7)的结果加权相加,得出一个在1-100之间的数,以此来决定PWM模块的功率,控制灯具亮度

4.oled控制模块

文件名oled.py

"""
设置OLED显示的库
"""
from board import SCL, SDA
import busio
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306


width = 128
height = 32
i2c = busio.I2C(SCL, SDA)
disp = adafruit_ssd1306.SSD1306_I2C(width, height, i2c)

image = Image.new("1", (width, height))
draw = ImageDraw.Draw(image)
draw.rectangle((0, 0, width, height), outline=0, fill=0)
# font_ch = ImageFont.truetype('./font.ttf', size=10)
font_en = ImageFont.load_default()


x = 0
top = -2


def init_oled():
    """
    初始化OLED
    """
    disp.fill(0)
    init_text = 'loading'
    init_x = (width - len(init_text)) / 2
    init_y = top + height / 2
    draw.text((init_x, init_y), init_text, font=font_en, fill=255)
    disp.image(image)
    disp.show()


def set_status(ip, emotion, level, weather):
    """
    设置显示内容
    """
    # 清空图像
    draw.rectangle((0, 0, width, height), outline=0, fill=0)

    # 设置ip
    ip_status = '>--<'
    ip_body = 'IP:{}'.format(ip) 
    # 设置网络显示格式
    if ip is None or weather is None:
        ip_status = '>  <'
        if ip is None:
            ip_body = 'None Ip'

    draw.text((0, top + 0), ip_status + ip_body, font=font_en, fill=255)

    # 设置等级显示
    draw.text((0, top + 8), f'{emotion}', font=font_en, fill=255)
    # draw.text((0, top + 14), '--  ' * level, font=font_en, fill=255)

    # 设置天气显示
    if weather is not None:
        first_line = f"we:{weather['weather']}   tem:{weather['temperature']}"
        second_line = f"hum:{weather['humidity']}   air:{weather['air']}"
        draw.text((0, top + 17), first_line, font=font_en, fill=255)
        draw.text((0, top + 25), second_line, font=font_en, fill=255)

    disp.image(image)
    disp.show()


def quit_oled():
    # 清空图像
    draw.rectangle((0, 0, width, height), outline=0, fill=0) 
    draw.text((59, top + 12), 'QUIT', font=font_en, fill=255)
    disp.image(image)
    disp.show()

该模块用来显示设备IP、识别的结果与天气


5.主程序

文件名main.py

from gpio import *
from oled import *
from data_source import *
from my_face import EmotionIdentify
import time
import RPi.GPIO as GPIO
from my_utils import labels, cvt_R2N
import numpy as np
from train_model import FaceCNN
import warnings
warnings.filterwarnings("ignore")


try:
    
    init_gpio()
    init_oled()
    ei = EmotionIdentify()

    while True:
        # 获得IP
        ip = get_ip()
        # 获得天气
        weather = get_weather()
        # 拍摄图片并预测结果
        result = ei.get_img_and_predict()[1]
        # 将结果转化为数值表示
        level = cvt_R2N(result)
        # 将结果转化为字符串表示
        emotion = labels[np.argmax(result)]
        # 设置网络指示灯
        set_online_led(weather)
        # 设置led亮度
        set_light_led(level)
        # 设置lcd显示
        set_status(ip, emotion, level, weather)

        print(f'{level}:::{emotion}')
        time.sleep(0.5)
except:
    colse_all()
    quit_oled()

colse_all()
quit_oled()

运行结果

在这里插入图片描述

三、总结

项目树:

  • modles
    • train_35.pkl
  • data_source.py
  • gpio.py
  • main.py
  • my_face.py
  • my_utils.py
  • oled.py
  • train_model.py

我的树莓派用的是ubuntu系统,因为源生的系统装pytorch太麻烦了
装pytorch的时候去官网装,直接pip安装会报错,因为找不到指定的版本
pandas可装可不装,如果你不想装,把train_model.py里train函数给删了,因为用不到

在安装这些库先,保证你的树莓派最少有2G的虚拟分区,如果内存太小无法完成编译

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于表情识别的智能灯控-树莓派实现 的相关文章

  • 翠儿。让流永远运行

    我对 tweepy python 库比较陌生 我想确保我的流 python 脚本始终在远程服务器上运行 因此 如果有人能够分享如何实现这一目标的最佳实践 那就太好了 现在我正在这样做 if name main while True try
  • 将tensorflow 2.0 BatchDataset转换为numpy数组

    我有这个代码 train images test images tf keras datasets mnist load data train dataset tf data Dataset from tensor slices train
  • 没有任何元数据的 zip 文件

    我想找到一种简单的方法来压缩一堆文件 而无需任何文件元数据 例如时间戳 这zip命令似乎总是保留元数据 我没有找到禁用元数据的方法 我希望解决方案是一个命令或最多一个 python 脚本 谢谢 正如一些帖子已经指出的那样 zip 标头中的大
  • 在 Python 中使用 Selenium 处理“接受 Cookie”弹出窗口

    我一直在尝试用硒抓取这个房地产网站的一些信息 但是 当我访问该网站时 我需要接受 cookie 才能继续 这仅在机器人访问网站时发生 而不是在我手动执行时发生 当我尝试通过 xpath 或 id 查找相应的元素时 正如我在手动检查页面时找到
  • 如何在Python中循环并存储自变量中的值

    我对 python 很陌生 所以这听起来可能很愚蠢 我进行了搜索 但没有找到解决方案 我在 python 中有一个名为 ExcRng 的函数 我可以对该函数执行什么样的 for 循环 以便将值存储在独立变量中 我不想将它们存储在列表中 而是
  • Tensorflow 可变图像输入大小(自动编码器、放大......)

    Edit WARNING不建议使用不同图像大小的图像 因为张量需要具有相同的大小才能实现并行化 我一直在寻找解决方案 了解如何使用不同大小的图像作为神经网络的输入 Numpy 第一个想法是使用numpy 然而 由于每个图像的大小不同 我无法
  • 在python中将文本文件解析为列表

    我对 Python 完全陌生 我正在尝试读取包含单词和数字组合的 txt 文件 我可以很好地读取 txt 文件 但我正在努力将字符串转换为我可以使用的格式 import matplotlib pyplot as plt import num
  • 即使使用 .loc[row_indexer,col_indexer] = value 时也会设置 WithCopyWarning

    这是我的代码中得到的行之一SettingWithCopyWarning value1 Total Population value1 Total Population replace to replace value 4 然后我将其更改为
  • PIL Image.size 返回相反的宽度/高度

    使用PIL确定图像的宽度和高度 在特定图像上 幸运的是只有这一个 但这很麻烦 从 image size 返回的宽度 高度是相反的 图片 http storage googleapis com cookila 533ebf752b9d1f7c
  • 带图像的简单 GUI [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我试图在简单的 GUI 上显示一些卡
  • 如果字段值在外部列表中,Django 会注释布尔值

    想象一下我有这个 Django 模型 class Letter models Model name models CharField max length 1 unique True 还有这个列表 vowels a e i o u 我想查询
  • 获取列表中倒数第二个元素[重复]

    这个问题在这里已经有答案了 我可以通过以下方式获取列表的倒数第二个元素 gt gt gt lst a b c d e f gt gt gt print lst len lst 2 e 有没有比使用更好的方法print lst len lst
  • 如何在Python和Selenium中通过标签名称或id获取元素[重复]

    这个问题在这里已经有答案了 我正在尝试使用 Python 和 Selenium 获取输入 但它向我显示错误 我该如何解决这个错误 inputElement send keys getStock getStocklFunc 0 Error i
  • 如何列出 python PDB 中的当前行?

    在 perl 调试器中 如果重复列出离开当前行的代码段 可以通过输入命令返回到当前行 点 我无法使用 python PDB 模块找到任何类似的东西 如果我list如果我自己离开当前行并想再次查看它 似乎我必须记住当前正在执行的行号 对我来说
  • conda-env list / conda info --envs 如何查找环境?

    我一直在尝试 anaconda miniconda 因为我的用户使用随 miniconda 安装的结构生物学程序 并且作者都没有 A 考虑到可能存在其他 miniconda 应用程序 B 他们的程序将在多用户环境中使用 因此 使用 Arch
  • Matplotlib Scatter - ValueError:RGBA 序列的长度应为 3 或 4

    我正在尝试为我的功能绘制图表 但不断收到此错误 ValueError RGBA sequence should have length 3 or 4 每当我只有 6 种形状时 代码就可以完美运行 但现在我将其增加到 10 种 它就不起作用了
  • 为什么我们应该在 def __init__(self, n) -> None: 中使用 -> ?

    我们为什么要使用 gt in def init self n gt None 我读了以下摘录来自 PEP 484 https www python org dev peps pep 0484 the meaning of annotatio
  • Python 3.2 中 **kwargs 和 dict 有什么区别?

    看起来Python的很多方面都只是功能的重复 除了我在 Python 中的 kwargs 和 dict 中看到的冗余之外 还有什么区别吗 参数解包存在差异 许多人使用kwargs 并通过dict作为论据之一 使用参数解包 Prepare f
  • 检查字符串是否只有字母和空格 - Python

    试图让 python 返回一个字符串仅包含字母和空格 string input Enter a string if all x isalpha and x isspace for x in string print Only alphabe
  • Django South - 将 null=True 字段转换为 null=False 字段

    我的问题是 转变的最佳做法是什么null True场变成null False使用 Django South 的字段 具体来说 我正在与ForeignKey 你应该先写一个数据迁移 http south aeracode org docs t

随机推荐

  • 数据可视化第四章

    比例数据 是根据类别 子类别和群体来进行划分的数据 对于比例 通常想要得到最大值 最小值和总体分布 前两者比较简单 将数据由小到大进行排列 位于两端的分别就是最小值和最大值 数据对比也是比例可视化的一个重要应用 在一个图表中集中反映多个维度
  • 小程序页面滚动穿透

    小程序页面滚动穿透 一 场景 框架 Taro2 Taro3不生效的 在项目当中 基础遇到这样的需求 有一个长列表 或者其他可滚动展示的页面 在这个页面会弹出一个Modal层 如下 贝壳找房的 的筛选栏 二 问题 如果这个弹框内容不可滚动 不
  • java 获取系统 默认编码_Java获取Linux服务器系统默认编码格式

    一 查找java进程 ps ef grep java 二 使用jinfo命令查看java系统参数 jinfo sysprops 进程id Usage jinfo option to connect to running process ji
  • 建立良好人际关系的原则

    1 尊重原则 尊重包括两个方面 自尊和尊重他人 自尊就是在各种场合都要尊重自己 维护自己的尊严 不要自暴自弃 尊重他人就是要尊重别人的生活习惯 兴趣爱好 人格和价值 只有尊重别人才能得到别人的尊重 2 真诚原则 只有诚以待人 胸无城府 才能
  • 【图论——第四讲】dijkstra算法求单源最短路及其堆优化

    o 大家好 欢迎大家光临我的博客 面向阿尼亚学习 算法学习笔记系列持续更新中 文章目录 一 前言 二 朴素dijkstra算法 三 堆优化版dijkstra 最后 一 前言 单源最短路 指的是求一个点 到其他所有点的最短距离 即起点是固定的
  • linux系统中函数库,Linux函数库(静态函数库和动态函数库)及安装过程

    Linux 系统中存在大量的函数库 简单来讲 函数库就是一些函数的集合 每个函数都具有独立的功能且能被外界调用 我们在编写代码时 有些功能根本不需要自己实现 直接调用函数库中的函数即可 需要注意的是 函数库中的函数并不是以源代码的形式存在的
  • 从0到1设计通用数据大屏搭建平台

    优质资源分享 学习路线指引 点击解锁 知识定位 人群定位 Python实战微信订餐小程序 进阶级 本课程是python flask 微信小程序的完美结合 从项目搭建到腾讯云部署上线 打造一个全栈订餐系统 Python量化交易实战 入门级 手
  • Python 多线程、多进程、协程对迭代数据的耗时操作测试

    Python 多线程 多进程 协程对迭代数据的耗时操作测试 2023 03 29 CPU计算密集型 2 17s p Python中的多线程受GIL制约 因此表面上的并行 实际上是并发 完全的计算密集型任务就和串行的耗时差不多了 Deal 耗
  • 阿里云数据库配置IP白名单操作方法(以MySQL为例)

    阿里云数据库RDS创建成功后 首次连接访问RDS需要配置IP白名单 在阿里云RDS控制台即可配置IP白名单 阿里云百科来详细说下阿里云服务器RDS配置白名单的方法 阿里云服务器配置IP白名单 阿里云百科以MySQL云数据库为例 RDS My
  • vc++常见错误之二:“fatal error C1083: ”无法打开包括文件

    这个问题产生的情况有多种 解决方法也有多种 我集合了网上的各种可能 可能不全 希望对你有用 其一 原文链接 http www cnblogs com txg blog archive 2011 03 07 1974857 html 步骤1
  • Nginx配置详解

    1 基本概念 1 1 Nginx简介 Nginx是一个高性能的HTTP和反向代理服务器 特点是占用内存少 并发能力强 事实上Nginx的并发能力确实在同类型的网页服务器中表现好 Nginx专为性能优化而开发 性能是其最重要的考量 实现上非常
  • SSM网约车管理系统毕业设计源码051630

    摘 要 时代的进步催生了一些事物 网约车便是近年社会发展的衍生物 并且在不长的时间内占领了大批市场 规模的日益扩大 一些负面的东西也开始浮出水面 犹如一颗石子投入水中 涟漪不断扩张 中国有句古话 无规则不成方圆 本文主要是针对网约车管理问题
  • 【python】迷宫游戏小游戏开发(代码+报告)【独一无二】

    博 主 米码收割机 技 能 C Python语言 公众号 测试开发自动化 荣 誉 阿里云博客专家博主 51CTO技术博主 专 注 专注主流机器人 人工智能等相关领域的开发 测试技术 迷宫游戏小游戏开发 代码 报告 目录 迷宫游戏小游戏开发
  • HTML中h标签和p标签,HTML 中 br 和 p 标签的区别是什么?

    HTML 中 br 和 p 标签的区别是什么 在 html 中 br 和 p 标签都可以实现文本的换行效果 那么它们之间有什么区别吗 下面本篇文章就来给大家介绍一下 br 和 p 标签的区别 希望对大家有所帮助 区别 在 HTML 中 br
  • ERP应收应付的操作与设计--开源软件诞生21

    赤龙ERP应收应付讲解 第21篇 用日志记录 开源软件 的诞生 点亮星标 祈盼着一个鼓励 博主开源地址 码云 https gitee com redragon redragon erp GitHub https github com red
  • 使用word文档插入代码方式

    熟悉编程工作的人员知道 经常会把代码往文档里面粘贴 如何优雅 快速的 美观的在word中进行插入代码了 可以使用样式工具 使用过程如下 1 新建代码端样式 找到该页面点击新建样式 2 设置字体 3 设置段落 4 设置边框 验证
  • PyTorch深度学习实践---笔记

    PyTorch深度学习实践 笔记 2 线性模型 Linear Model 2 exercise 3 梯度下降算法 Gradient Descent 3 1梯度下降 Gradient Descent 3 2 随机梯度下降 Stochastic
  • 【Command模式】C++设计模式——命令模式

    命令模式 一 设计流程探讨 二 模式介绍 三 代码实现 C 设计模式大全 23种设计模式合集详解 点我跳转 一 设计流程探讨 假如你正在开发一款新的文字编辑器 当前的任务是创建一个包含多个按钮的工具栏 并让每个按钮对应编辑器的不同操作 你创
  • Hive常用操作以及java.io.IOException: java.lang.RuntimeException: ORC split generation failed问题处理

    使用datagrip连接hive 切换数据库 use testdb create database testdb 创建表 create table t user id int name varchar 100 age int create
  • 基于表情识别的智能灯控-树莓派实现

    文章目录 前言 一 项目简介 项目思路 软硬件清单 原理图 接线图 实物图 二 代码与详解 1 获取天气 IP模块 2 gpio控制模块 3 表情识别模块 4 oled控制模块 5 主程序 三 总结 前言 这是我之前做的一个嵌入式课设项目