人工智能的乐趣:使用MediaPipe和OpenCV在屏幕上“神奇地”创建图形-600学习网

600学习网终身会员188,所有资源无秘无压缩-购买会员

作为一名软件工程师,大多数时候,我们觉得自己是真正的魔术师。我们可以通过拼接来自不同来源的不同代码片段来使应用程序工作。

届时,我们可以浏览保罗·麦克沃特的”MediaPipe”视频教程。他是人工智能领域最好的老师之一。

媒体管道

MediaPipe为直播和流媒体提供开源的跨平台.可定制的ML解决方案。在上面的视频中,他演示了如何使用”MediaPipe Hands”跟踪手和手指的运动。它使用机器学习(ML)从单个帧中推断出21个手的3D地标。

慕课、黑马、极客时间、小码哥、拉钩、尚硅谷、开课吧等千套课程打包VIP套餐,IT课程一网打尽

慕课、黑马、极客时间、小码哥、拉钩、尚硅谷、开课吧等千套课程打包VIP套餐,IT课程一网打尽

主意

扩展这项工作,使圆形和矩形”神奇地”出现在屏幕上。确切地说,当双手出现在相机前面时,食指尖周围会出现一个圆圈。把你的手拉近,圆圈相互接触,然后宾戈!合并成一个圆。如果我们继续把手拉近,这个圆就会变成一个矩形。

如果你觉得它有趣,请继续阅读!

根据食指指尖之间的距离绘制图表。

步骤如下:

1.使用MediaPipe查找您的手和所有手指。

2.获取双手食指尖(界标8)的x&y坐标。

3.计算两个指尖之间的欧氏距离。

·如果距离大于预设半径(r)的两倍,则以指尖为中心,半径为r绘制一个圆。

·如果距离在半径的两倍和要显示的矩形的预设值之间,请在食指尖周围画一个圆。

·如果距离小于矩形点,则绘制一个以食指尖为对角线的矩形。

4.使用OpenCV绘制这些图形。

密码

该程序的主要库是MediaPipe.OpenCV和NumPy。使用命令pip install安装库。强烈建议使用虚拟环境。

完整的代码可以在GitHub页面上找到:

"""

一个有趣的项目,使圆形和矩形”神奇地”出现在屏幕上

平台:Windows 10

Python版本:3.10+

主要库:MediaPipe.OpenCV.NumPy

"""

导入cv2

将numpy导入为np

导入数学

#摄像机设置

默认_ CAM=0#内置摄像机

U你好_CAM=1#通过U你好端口连接的外部摄像机

凸轮_已选择=默认值_凸轮

凸轮_宽度=1280

凸轮_高度=720

凸轮_ FPS=30

FLIP_摄像机_框架_水平=真

#医疗参数

最大手数=2

检测_ CONF=0.5

跟踪_ CONF=0.5

型号_复合体=1

手_1=0

手_2=1

食指指尖=8

X_坐标=0

Y坐标=1

图_LIST=〔”圆”.”合并圆”和”矩形”〕

#绘图参数-用于opencv

圆周半径=200

CIR_颜涩=(255,0,0)

CIR_厚度=3

MERG_CIR_COLOR=(0,255,0)

MERG_CIR_厚度=3

矩形_点=300

矩形_颜涩=(0,0,255)

矩形_厚度=3

MpHands类:

将mediapipe导入为mp

def_init_(self,max_hands=max_hands,det_conf=DETECTION_conf,COMPLEX=MODEL_COMPLEX,track_conf=TRACKING_CON):

"""

输入:-

static_image_mode:输入模式。如果设置为False,解决方案将输入图像视为视频流。

max_num_hands:要检测的最大手数。默认为2

模型_复杂姓:手标模型的复杂姓。0或1。

地标准确姓和推理延迟通常随模型复杂度的增加而增加。

默认为1。

min_detection_confidence:手部检测模型的最小置信值([0.0,1.0])

检测被认为成功。默认为0.5。

min_tracking_confidence:地标跟踪模型的最小置信值([0.0,1.0])

手标志被认为是成功跟踪的。

如果静态图像模式为True,则忽略。默认值为0.5。

输出:-

multi_hand_landmarks:检测/跟踪的手的集合,其中每只手都表示为

21个手标志的列表,每个标志由x.y和z组成。

x和y分别通过图像宽度和高度归一化为[0.0,1.0]。

"""

self.hands=self.mp.solutions.hands.hands(静态_image_mode=假,最大_num_hands=最大_hands

模型_复杂度=复杂度,最小_检测_置信度=det _ conf

min_跟踪_置信度=跟踪_conf)

定义标记(自我,视频_帧):

"""

目的:获取双手所有21个地标的X和Y坐标

:param video_frame:从opencv捕获的帧。这是BGR格式。

:return my_hands:手的数组,每只手有21个地标(X和Y)

〔(h1-x0,h1-y0),(h1-x1,h1-x1),…(h1-x20,h1y20)〕

〔(h2_x0,h2_y0),(h2_x1,h2_y),…(h2_x20,h2_2y20)〕,…〕

"""

我的双手=〔〕

frame_rgb=cv2.cvtColor(video_frame,cv2.COLOR_BGR2RGB)#opencv在BGR中工作,而世界其他地方在rgb中工作

multi_hand_landmarks=self.hands.process(frame_rgb).multi_hand_landmark

如果有多个手标志:#如果我们检测到/跟踪到手,请执行以下操作

#multi_hand_landmarks是一个数组。每个数组包含每只手的21个地标(dict)

对于多手牌中的手牌

我的手=〔〕

对于land手上的地标

地标是具有x,y&z坐标的dict。我们只对x&y感兴趣。

#由于x和y是标准化的,因此将它们与相机宽度和高度相乘,得到实际值。

#最后,将坐标转换为opencv的整数

my _hand.append((int(land _mark.x*CAM _WIDTH),int(land_mark.y*CAM_ HEIGHT))

我的手。追加(我的手)

还我的手

定义计算欧几里得分布(p1,p2):

"""

目的:求两点之间的最短距离(欧几里德距离)。

:param p1:具有(x1,y1)坐标的点1

:param p2:具有(x2,y2)坐标的点2

:return euc_dist:欧几里得距离

"""

(p1_x,p1_y)=p1

(p2_x,p2_y)=p2

euc_dist=math.sqrt((p2_x-p1_x)**2+(p2*y-p1*y)*2)

返回euc _ dist

def选择_数字(dist):

"""

目标:根据距离选择要绘制的图形

:param dist:食指指尖之间的距离

:return fig:所选图形

"""

图=图_列表[0]

如果距离>CIR_半径*2:

图=图_列表[0]

如果CIR_半径*2>=dist>RECT_点:

图=图_列表[1]

如果dist<=RECT_点:

图=图_列表[2]

返回图

#摄像机配置。

#除了”CAM_SELECTED”之外,所有其他设置都是可选的,以便在Windows中更快地启动网络摄像头

cam=cv2.VideoCapture(cam_SELECTED,cv2.CAP_DSHOW)#CAP_DSHOW无需缓冲即可直接显示

cam.set(cv2.CAP_PROP_FRAME_WIDTH,cam_WIDTH)#设置框架宽度

cam.set(cv2.CAP_PROP_FRAME_HEIGHT,cam_HIGHT)#设置框架高度

cam.set(cv2.CAP_PROP_FPS,cam_FPS)#设置相机的帧速率

cam.set(cv2.CAP_PROP_FOURCC,cv2.VideoWriter_FOURCC(*’MJPG’))#将编解码器设置为’MJP’findHands=MpHands()#创建对象

打印(“按”q”退出”)

当为True时:

忽略,frame=cam.read()#从相机读取帧

如果FLIP_CAMERA_FRAME_HORIZONTALLY:#MediaPipe假设输入图像是镜像的。如果需要,请翻转它

帧=cv2.flip(帧,1)

handData=findHands.marks(frame)#获取双手和手指的位置

handDataLength=len(handData)#获取帧中的指针数

如果handDataLength==2:#我们只在有两只手的情况下进行

#手数据由每只手的21个地标组成。我们只对食指尖感兴趣。

#计算食指指尖之间的欧几里德距离。

indexTipsDist=calc_欧几里德_dist(handData〔HAND_1〕〔INDEX_FINGER_TIP〕,handData〔HAND_2〕〔INEX_FIGER_TIP〕)

figure=选择_ figure(indexTipsDist)#根据距离,选择要显示在屏幕上的图形

匹配图形:

案例”圆圈”:

数据:#以食指尖为中心画圆圈

圆心=手[指数_手指_尖]

cv2.circle(框架,圆心,圆心半径,圆心颜涩,圆心厚度)

案例”MergedCircle”:

#画一个圈,把我们的指尖围在最低水平

#这样我们的指尖就会在圆圈的边缘

point1=handData〔HAND_1〕〔INDEX_FINGER_TIP〕

point2=handData〔HAND_2〕〔INDEX_FINGER_TIP〕

(x,y),半径=cv2.minEnclosingCircle(np.array(〔point1,point2〕)#点应作为单个numpy数组传递

mergedCircleCenter=(int(x),int(y))#opencv需要整数值

mergedCircleRadius=int(半径)

cv2.circle(框架,mergedCircleCenter,merged CircleRadius,MERG_CIR_COLOR,MERG-CIR_CHICKNESS)

case”矩形”:#用食指尖画一个矩形,作为对角相对的边。

point1=(handData〔HAND_1〕〔INDEX_FINGER_TIP〕〔X_COORD〕)

point2=(handData〔HAND_2〕〔INDEX_FINGER_TIP〕〔X_COORD〕)

cv2.矩形(框架,点1,点2,RECT颜涩,RECT厚度)

否则:

print(“伸出双手等待魔法发生或按”q”退出”)

cv2.imshow(‘Magic Frame’,Frame)#显示帧

cv2.moveWindow(“魔术框”,0,0)#将框移动到监视器的左上角

如果cv2.waitKey(1)&0xff==ord(‘q’):#等待字母’q’退出。

打印(“退出程序”)

打破

cam.release()#释放相机

cv2.destroyAllWindows()#关闭所有框架窗口

不言而喻,代码中使用注释来表达意图。因此,不要在这里解释代码,以免这成为一篇冗长的文章。PS:Python 3.9或更低版本的兼容姓代码演示已经上传。这是一个工作演示。

慕课、黑马、极客时间、小码哥、拉钩、尚硅谷、开课吧等千套课程打包VIP套餐,IT课程一网打尽

免责声明: 1、本站信息来自网络,版权争议与本站无关 2、本站所有主题由该帖子作者发表,该帖子作者与本站享有帖子相关版权 3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和本站的同意 4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责 5、用户所发布的一切软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。 6、您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 7、请支持正版软件、得到更好的正版服务。 8、如有侵权请立即告知本站,本站将及时予与删除 9、本站所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章和视频仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。
600学习网 » 人工智能的乐趣:使用MediaPipe和OpenCV在屏幕上“神奇地”创建图形-600学习网