Python实现AI视频识别——手势控制[通俗易懂]

Python实现AI视频识别——手势控制[通俗易懂]用opencv识别手势实现原理代码importcv2importmediapipeasmpclasshandDetector():#经典OOP#设置初始条件def__init__(self,mode=False,maxHands=2,detectionCon=0.5,trackCon=0.5):self.mode=modeself.maxHands=maxHands#最多同时出现几只手

大家好,又见面了,我是你们的朋友全栈君。

用opencv识别手势

实现原理

用opencv库拍摄一帧图片,用mediapipe库识别人手和标识点,然后用opencv在视频上添加标识的信息,最后用opencv合成一个动态视频输出

代码

import cv2
import mediapipe as mp
class handDetector():  # 经典OOP
# 设置初始条件
def __init__(self, mode=False, maxHands=2, detectionCon=0.5, trackCon=0.5):
self.mode = mode
self.maxHands = maxHands  # 最多同时出现几只手
self.detectionCon = detectionCon  # 检测可信度
self.trackCon = trackCon  # 跟踪可信度
self.mpHands = mp.solutions.hands  # 用mediapipe找手
self.hands = self.mpHands.Hands(self.mode, self.maxHands,
self.detectionCon, self.trackCon)
self.mpDraw = mp.solutions.drawing_utils
# 在图片里里找到手并返回这一帧图片
def findHands(self, img, draw=True):
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 数字化视频输入
self.results = self.hands.process(imgRGB)  # 处理视频找手
if self.results.multi_hand_landmarks:  # 如果找到了手上的标识点
for handLms in self.results.multi_hand_landmarks:
if draw:  # 在识别出的手上把标记点画出来
self.mpDraw.draw_landmarks(img, handLms, self.mpHands.HAND_CONNECTIONS)
return img
# 找到手之后把手的关节位置投射上去并且记录数据
def findPosition(self, img, handNo=0, draw=True):
lmList = []  # 记录手上标识点
if self.results.multi_hand_landmarks:
myHand = self.results.multi_hand_landmarks[handNo]
# 遍历识别数据,处理后输出
for idNum, lm in enumerate(myHand.landmark):
h, w, c = img.shape  # 高度,深度,通道数
cx, cy = int(lm.x * w), int(lm.y * h)  # 坐标位置
lmList.append([idNum, cx, cy])  # 可以在这里print一下看看长什么样
if draw:  # 在识别出的点位置画个蓝点
cv2.circle(img, (cx, cy), 15, (0, 0, 255), cv2.FILLED)
return lmList
def main():
wCam, hCam = 640, 480  # 摄像头拍摄大小
cap = cv2.VideoCapture(0)  # 创建类用来拍摄
cap.set(3, wCam)  # 比例设置
cap.set(4, hCam)
detector = handDetector(detectionCon=0.8)  # 最低准确度
tipIds = [4, 8, 12, 16, 20]  # 指头的序号
while True:
success, img = cap.read()  # 获取一帧
img = detector.findHands(img)  # 找手并返回标记好的图片
lmList = detector.findPosition(img, draw=False)  # 标点然后返回数据
if len(lmList) != 0:  # 如果找到了手且上面有标记好的点
fingers = []
# 大拇指的弯曲角度
# 如果大拇指的第4个标记点像素位置低于第3个标记点,那它就是弯的
if lmList[tipIds[0]][1] > lmList[tipIds[0] - 1][1]:
fingers.append(1)
else:
fingers.append(0)
# 其它四个指头角度判定
for idNum in range(1, 5):
if lmList[tipIds[idNum]][2] < lmList[tipIds[idNum] - 2][2]:
fingers.append(1)
else:
fingers.append(0)
print(fingers)
# 简单的手指二进制,用五根指头代表五位长的二进制数
output = 0
if fingers[0] == 1:  # 拇指竖起来
output += 1
if fingers[1] == 1:  # 食指竖起来
output += 2
if fingers[2] == 1:  # 中指竖起来
output += 4
if fingers[3] == 1:  # 无名指竖起来
output += 8
if fingers[4] == 1:  # 小指竖起来
output += 16
# 处理视频,画个方框,上面写识别到的数字
cv2.rectangle(img, (20, 225), (250, 425), (0, 0, 0), cv2.FILLED)
cv2.putText(img, str(output), (45, 375), cv2.FONT_HERSHEY_PLAIN,
10, (255, 255, 255), 25)
cv2.imshow("Image", img)  # 显示处理好的一帧图片
cv2.waitKey(1)  # 相当于帧数了,这个是1ms一帧,1s60帧
if __name__ == "__main__":  # 这样就不会导入这个文件时直接跑程序啦
main()

运行结果

笔者直接在Python3自带的IDLE里跑这个程序的时候,会出现奇怪的闪退。以下运行结果是在PyCharm里跑的:
31
28

功能拓展

在手指本身的十进制基础上,笔者把手指计数变成了二进制,能表示32个数字。如果用两只手来计数的话可以表示1024个数字。
手指计数的判定比较简单,是直接比较x坐标的高低而不是其之间的夹角。这个也许可以用三角函数和向量乘积来计算并更加精确地判定角度。
手指除了用来表示数字还可以用来做手语。如果有一个手语动作库,那么本程序可以很好地被用来帮助不会手语的人理解手语。
用手指表示数字还有别的待开发用途,比如用手势来控制音量和屏幕亮度等等。
感兴趣的同学可以尝试实现以上功能。有任何问题和想法欢迎私信和评论区留言!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/141675.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 手把手教你使用YOLOV5训练自己的目标检测模型-口罩检测-视频教程

    手把手教你使用YOLOV5训练自己的目标检测模型大家好,这里是肆十二(dejahu),好几个月没有更新了,这两天看了一下关注量,突然多了1k多个朋友关注,想必都是大作业系列教程来的小伙伴。既然有这么多朋友关注这个大作业系列,并且也差不多到了毕设开题和大作业提交的时间了,那我直接就是一波更新。这期的内容相对于上期的果蔬分类和垃圾识别无论是在内容还是新意上我们都进行了船新的升级,我们这次要使用YOLOV5来训练一个口罩检测模型,比较契合当下的疫情,并且目标检测涉及到的知识点也比较多,这次的内容除了可以作为大家

  • SpringBoot +DynamicDataSource切换多数据源记录方法

    SpringBoot +DynamicDataSource切换多数据源记录方法

  • 高达起源the origin_idea找不到tomcat

    高达起源the origin_idea找不到tomcat“Theoriginserverdidnotfindacurrentrepresentationforthetargetresourceorisnotwillingtodisclosethatoneexists.”,在web开发的过程中,看到这一段错误提示,不管是在入门阶段还是已经是web老手都会感到很头痛。我也是在使用JSTL库的过程中,出现了这

    2022年10月14日
  • WDM 驱动程序开发[通俗易懂]

    WDM 驱动程序开发[通俗易懂]1.概述 引入了全新的WDM(Win32DriverModel)的驱动程序架构,说是新技术,其实早在1997年Microsoft就提出了该项技术并在Windows98中得到了充分的应用,换句话说,Windows98也支持WDM。这样WDM就成为了一个跨平台的驱动程序模型不仅如此WDM驱动程序还可以在不修改源代码的情况下经过重新编译后在非Intel平台上运行。2.WDM设备驱动程序的特

    2022年10月21日
  • XGBoost原理介绍

    XGBoost原理介绍 1.Introduction在这篇文章中,我将介绍XGBoost(eXtremeGradientBoosting),一种treeboosting的可扩展机器学习系统。这个系统可以作为开源的软件包使用。该系统的影响已经在大量的机器学习和数据挖掘挑战中被广泛地认可。这些获胜解决方案包括:商店销售预测;高能物理事件分类;网络文本分类;顾客行为预测;运动检测;广告点击率预测;…

  • SAP Transaction Code

    SAP Transaction Code[@more@]F-01EnterSampleDocumentF-02EnterG/LAccountPostingF-03ClearG/LAccountF-04PostwithClearingF…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号