我们中的许多人大部分时间都在办公桌前弯腰驼背,身体前倾看着电脑屏幕,或者瘫坐在椅子上。如果你像我一样,只有当你的脖子或肩膀在数小时后受伤,或者你有偏头痛时,你才会想起你的不良姿势。如果有人可以提醒您坐直不是很好吗?
好消息是你可以提醒自己!在本教程中,我们将使用 alwaysAI 提供的姿势估计模型构建一个姿势校正器应用程序。
要完成本教程,您必须具备:
alwaysAI 账户。
alwaysAI 在本机的配置。
诸如 sublime 之类的文本编辑器。
诸如 PyCharm 之类的 IDE。
拥有账户并设置开发人员环境后,下载入门应用程序。在继续本教程的其余部分之前,请使用此链接执行此操作。我们将通过修改 realtime_pose_detector 入门应用来构建姿势校正器。您可能希望将内容复制到一个新目录中,以便保留原始代码。
本教程将分为三个主要部分:
配置文件
主要应用
用于检测不良姿势的实用程序类
配置文件的创建
对于这个示例应用程序,我们需要一个配置变量(如果需要,可以添加更多):scale。它是一个整数,将用于调整姿势功能的灵敏度。
应用程序的创建
将以下代码添加到您的 app.py 文件的顶部:
import os
import json
from posture import CheckPosture
我们需要 json 库来解析配置文件,而 CheckPosture 是我们将在本教程后面定义的用于检测不良姿势的实用程序库。
注意:您可以根据您的部署环境更改在此应用程序中使用的加速器。由于我是在 Mac 上开发的,所以我选择引擎为“DNN”,因此我将参数更改为 edgeiq.Engine.DNN。我还将加速器更改为“CPU”。您可以在 alwaysAI 的文档中阅读有关加速器和引擎选项的更多信息。
接下来,从 app.py 中删除以下代码:
text.append("Key Points:")
for key_point in pose.key_points:
text.append(str(key_point))
添加以下代码以替换您刚刚删除的代码(在 text.append 语句的正下方):
# update the instance key_points to check the posture
posture.set_key_points(pose.key_points)
# play a reminder if you are not sitting up straight
correct_posture = posture.correct_posture()
if not correct_posture:
text.append(posture.build_message())
# make a sound to alert the user to improper posture
print("\a")
我们在使用了一个未知的对象类型,并调用了一些我们尚未定义的函数。我们将在最后一节中做到这一点!
将以下几行移动到上面代码的末尾(紧接在 for 循环之后和 finally 之前):
streamer.send_data(results.draw_poses(frame), text)
fps.update()
if streamer.check_exit():
break
创建姿势实用程序类
创建一个名为 posture.py 的新文件。使用以下代码定义类:
class CheckPosture
为类创建构造函数。我们将拥有三个实例变量:key_points、scale 和 message。
def __init__(self, scale=1, key_points={}):
self.key_points = key_points
self.scale = scale
self.message = ""
我们为 scale 和 key_points 使用默认值,以防用户不提供它们。我们只是将变量 message 初始化为一个空字符串,但这将存储用户可以用来纠正其姿势的反馈。您已经看到在 app.py 部分设置了 key_points 变量。此变量允许 posture.py 中的函数确定用户的姿势。最后,scale 只是简单地使在 posture.py 中执行的计算在它减少或增加时变得更敏感或更不敏感。
现在我们需要为 posture.py 编写一些函数。
为 key_points、message 和 scale 变量创建一个 getter 和 setter:
def set_key_points(self, key_points):
self.key_points = key_points
def get_key_points(self):
return self.key_points
def set_message(self, message):
self.message = message
def get_message(self):
return self.message
def set_scale(self, scale):
self.scale = scale
def get_scale(self):
return self.scale
现在我们需要定义一个函数来实际检查姿势。我的不良姿势习惯包括身体前倾朝向电脑屏幕、懒洋洋地坐在椅子上以及低头看笔记,因此我定义了检测这几种用例的方法。如果愿意,您可以使用相同的坐标比较原则来定义自己的自定义方法。
首先,我们将定义检测前倾的方法,如下图所示。此方法通过比较身体同一侧的耳朵和肩膀来工作。所以首先它会检测耳朵和肩膀是否在左侧或右侧都可见(即我们要使用的坐标不是 -1),然后它会检查肩膀的 x 坐标是否大于耳朵的 x坐标。
def check_lean_forward(self):
if self.key_points['Left Shoulder'].x != -1 and self.key_points['Left Ear'].x != -1 \
and self.key_points['Left Shoulder'].x >= (self.key_points['Left Ear'].x + \
(self.scale * 150)):
return False
if self.key_points['Right Shoulder'].x != -1 and self.key_points['Right Ear'].x != -1 \
and self.key_points['Right Shoulder'].x >= (self.key_points['Right Ear'].x + \
self.scale * 160)):
return False
return True
注意:alwaysai/human-pose 的坐标是左上角的 0,0。此外,帧大小会根据您是否使用流媒体输入视频或图像而有所不同,这也会影响坐标。我使用 Streamer 对象进行开发,帧大小为 (720, 1280)。对于所有这些功能,您很可能需要调整坐标差异或修改比例,因为每个人都有不同的姿势基线。然而,坐标算法的原理将保持不变,并且可用于更改其他姿势估计用例中的应用程序行为!您还可以使用角度或百分比进行衡量,以免被绝对值所束缚。
接下来,我们将定义在椅子上懒洋洋地坐着的函数,如下图所示:
在这个函数中,我们将使用 y 坐标的颈部和鼻子关键点来检测鼻子何时太靠近颈部,这发生在某人的背部弯腰坐在椅子上时。对我来说,大约 150 代表了我想要允许的最大距离。如果我的鼻子距离我的脖子不到 150 点,我想得到通知。同样,这些设定的固定值可以使用 scale 参数进行缩放,或者按照上面提示中的建议进行修改。
def check_slump(self):
if self.key_points['Neck'].y != -1 and self.key_points['Nose'].y != -1 \
and (self.key_points['Nose'].y >= self.key_points['Neck'].y - (self.scale * 150)):
return False
return True
现在,我们将定义检测头部何时向下倾斜的函数,如下图所示。此函数将使用耳朵和眼睛关键点来检测给定眼睛的 y 坐标何时比身体同一侧的耳朵更靠近图像底部。
def check_head_drop(self):
if self.key_points['Left Eye'].y != -1 and self.key_points['Left Ear'].y != -1 \
and self.key_points['Left Eye'].y > (self.key_points['Left Ear'].y + (self.scale * 15)):
return False
if self.key_points['Right Eye'].y != -1 and self.key_points['Right Ear'].y != -1 \
and self.key_points['Right Eye'].y > (self.key_points['Right Ear'].y + (self.scale * 15)) :
return False
return True
现在,我们只创建一个检查所有姿势方法的函数。此方法通过使用 Python 的 all 函数来工作,该函数仅在列表中的所有可迭代对象都返回 True 时才返回 True。如果检测到不良姿势,我们定义的所有姿势方法都会返回 False,如果其中任何一个方法返回 False,我们现在定义的方法将返回 False。
def correct_posture(self):
return all([self.check_slump(),
self.check_head_drop(),
self.check_lean_forward()])
最后,我们将构建一个返回自定义字符串的方法,告诉用户如何纠正他们的姿势。此方法在 app.py 中调用,结果显示在文本中:
def build_message(self):
current_message = ""
if not self.check_head_drop():
current_message += "Lift up your head!\n"
if not self.check_lean_forward():
current_message += "Lean back!\n"
if not self.check_slump():
current_message += "Sit up in your chair, you're slumping!\n"
self.message = current_message
return current_message
至此!现在您有了一个工作姿势矫正应用程序。您可以通过创建自己的姿势检测方法、使用不同的关键点坐标、使 build_message 返回不同的提示以及创建您自己的自定义音频文件来代替 print(“\a”) 来自定义此应用程序。您还可以更改应用程序以向您发送短信而不是输出至控制台。
· END ·