当前位置: 首页 > 后端技术 > Python

Python玩人工智能:你的俯卧撑做对了吗?

时间:2023-03-25 21:24:24 Python

我们已经有《Python玩人工智能:你能做几个引体向上?》和《Python玩人工智能:你的仰卧起坐达标了吗?》了,今天来做俯卧撑吧!一、准备工作1.1安装Python3.8.x1.2安装PyCharmCommunityEdition1.3创建工程1.4安装工程工具包1.1下载安装Python3.8.x版本首先我们需要在自己的电脑上安装Python3.8.x。Python3.8.x:https://www.python.org/downlo...1.2下载并安装PyCharmCommunityEditionPyCharm:https://www.jetbrains.com/pyc...当然你也可以使用你的最喜欢的IDE。1.3创建Python项目安装好Python和PyCharm后,我们就可以启动PyCharm,创建一个新的Python项目。选择项目的存储位置。在创建项目时,可以请PyCharm帮助创建虚拟环境(virtualenv)。虚拟环境可以理解为本项目的专属编程环境,不会影响其他项目。1.4安装项目使用的工具包项目创建完成后,我们打开PyCharm的Terminal窗口,我们可以在其中输入以下命令安装本项目需要的工具包:opencv-pythonmediapipenumpypyautogui。以下命令将从Internet下载该工具包并进行安装。如果最后看到“Successfullyinstalled...”,则表示安装成功。pipinstallopencv-pythonmediapipenumpy也可以点击PyCharm的设置,查看项目的Python环境中是否有以上工具包。如果有,说明安装成功。2.编写程序2.1创建poseutil.py模块2.2编写pushup.py2.3测试运行2.1创建poseutil.py模块新建一个Python文件命名为poseutil.py,这个就是我们创建的姿态识别模块,在里面有一个PoseDetector本模块中的姿势识别器类,可用于识别人体姿势,获取人体姿势数据,计算人体姿势相关点的角度。importcv2importmediapipeasmpimportmathclassPoseDetector():'''人体姿势检测类'''def__init__(self,static_image_mode=False,upper_body_only=False,smooth_landmarks=True,min_detection_confidence=0.5,min_tracking_confidence='0'5)初始化:paramstatic_image_mode:是否为静态图片,默认为No:paramupper_body_only:是否为上半身,默认为No:paramsmooth_landmarks:设置为True,减少抖动:parammin_detection_confidence:的最小置信度值行人检测模型,默认为0.5:parammin_tracking_confidence:姿态可信标记的最小置信度值,默认为0.5'''self.static_image_mode=static_image_modeself.upper_body_only=upper_body_onlyself.smooth_landmarks=smooth_landmarksself.min_detection_confidenceselfdetection=min_detection.min_tracking_confidence=min_tracking_confidence#创建一个姿势对象用于检测人体姿势self.pose=mp.solutions.pose.Pose(self.static_image_mode,self.upper_body_only,self.smooth_landmarks,self.min_detection_confidence,self.min_tracking_confidence)deffind_pose(self,img,draw=True):'''姿态检测方法:paramimg:一帧图像:paramdraw:是否绘制人体姿态节点和连接图:return:processedimage'''imgRGB=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)#pose.process(imgRGB)会识别出这一帧图片中的人体姿态数据并保存到self.self.resultsinresults=self.pose.process(imgRGB)ifself.results.pose_landmarks:ifdraw:mp.solutions.drawing_utils.draw_landmarks(img,self.results.pose_landmarks,mp.solutions.pose.POSE_CONNECTIONS)返回imgdeffind_positions(self,img):'''获取人体姿态数据:paramimg:一帧图像:paramdraw:是否绘制人体姿态节点和连接图:return:人体姿态数据列表'''#人体姿态数据列表,每个成员由3个数字组成:id,x,y#id代表人体的一个关节点,x和y表示坐标位置数据self.lmslist=[]ifself.results.pose_landmarks:forid,lminenumerate(self.results.pose_landmarks.landmark):h,w,c=img.shapecx,cy=int(lm.x*w),int(lm.y*h)self.lmslist.append([id,cx,cy])返回self.lmslistdeffind_angle(self,img,p1,p2,p3,draw=True):'''获取人体姿势p1-p2-p3三个点的角度:paramimg:一帧图像:paramp1:第一个点:paramp2:第二个点:paramp3:第三个point:paramdraw:是否绘制3个点的连接图:return:angle'''x1,y1=self.lmslist[p1][1],self.lmslist[p1][2]x2,y2=self.lmslist[p2][1],self.lmslist[p2][2]x3,y3=self.lmslist[p3][1],self.lmslist[p3][2]#使用三角函数得到3个点p1-p2-p3,以p2为角度的角度值,在0-180度之间angle=int(math.degrees(math.atan2(y1-y2,x1-x2)-math.atan2(y3-y2,x3-x2)))如果角度<0:角度=角度+360如果角度>180:angle=360-绘制时的角度:cv2.圆(img,(x1,y1),20,(0、255、255),cv2。填充)cv2。圆(img,(x2,y2),30,(255,0,255),cv2。填充)cv2。圆(img,(x3,y3),20,(0、255、255),cv2。填充)cv2。线(img,(x1,y1),(x2,y2),(255,255,255,3))cv2.line(img,(x2,y2),(x3,y3),(255,255,255,3))cv2.putText(img,str(angle),(x2-50,y2+50),cv2.FONT_HERSHEY_SIMPLEX,2,(0,255,255),2)returnangle2.2写pushup.py写的下面代码,调用poseutil模块,获取人体pose数据,计算人体的肩部、臀部、膝肩部、肘部、手腕所形成的角度,并通过这两个角度来判断是否push-ups是标准的#importopencvtoolkitimportcv2#importnumpyimportnumpyasnp#importposerecognizerfromposeutilimportPoseDetector#打开视频文件cap=cv2.VideoCapture('videos/pushup.mp4')#poserecognizerdetector=PoseDetector()#方向和数量dir=0#0向下,1向上count=0#videowidthwidth=int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))height=int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))#recordingVideosettingfourcc=cv2.VideoWriter_fourcc(*'mp4v')out=cv2.VideoWriter('videos/pushupoutput.mp4',fourcc,30.0,(width,height))whileTrue:#读取摄像头,img为每一帧成功的图片,img=cap.read()ifsuccess:h,w,c=img.shape#识别姿势img=detector.find_pose(img,draw=True)#获取姿势数据positions=detector.find_positions(img)ifpositions:#Get俯卧撑的角度angle1=detector.find_angle(img,12,24,26)angle2=detector.find_angle(img,12,14,16)#进度条的长度bar=np.interp(angle2,(45,150),(w//2-100,w//2+100))cv2.rectangle(img,(w//2-100,h-150),(int(bar),h-100),(0,255,0),cv2.FILLED)#如果angle2<=50andangle1>=则认为支持小于50度的角度165andangle1<=175:ifdir==0:count=count+0.5dir=1#大于125度的角度被认为是被支撑的ifangle2>=125andangle1>=165andangle1<=175:ifdir==1:count=count+0.5dir=0cv2.putText(img,str(int(count)),(w//2,h//2),cv2.FONT_HERSHEY_SIMPLEX,10,(255,255,255),20,cv2.LINE_AA)#打开一个图像窗口显示视频图像cv2.imshow('Image',img)#录制视频out.write(img)else:#视频结束退出break#如果按下q键,程序退出key=cv2.waitKey(1)ifkey==ord('q'):break#关闭视频保护器out.release()#关闭摄像头cap.release()#关闭程序窗口cv2.destroyAllWindows()2.3测试运行时测试实际跑起来,我们设置的俯卧撑角度在50度到125度之间,可以根据投篮角度进行调整。另外,我们要求臀角在165度到175度之间,也是可以调整的建议拍摄视频或使用相机时多放在人体一侧,这样检测会更准确。