AI互动屏

2023-04-081.8万
精华项目
AI 快速预览详细 收起
本项目使用Mediapipe姿态识别和比例积分算法,结合熊猫板和电视机,实现手部控制小球图形的互动效果。适用于商场、展览等场景,提供良好的交互体验。硬件清单包括熊猫板和电视机,最终效果是手部控制小球图形的互动效果。难度等级适中,适合有一定编程基础的用户。


AI互动屏图1


【项目背景】
最近在某商场见到一种互动屏,人们可以进行体感互动,脚底生花,人走过去就会根据人走的轨迹自然开花,和鱼水互动,人走在水里面鱼会跟着人的脚步游动。产生令人瞩目的效果,为受众提供良好的交互体验感。
【项目设计】
本项目,使用Mediapipe姿态识别,结合比例(P)、积分(I)算法,实现手部对一串小球图形进行运行控制,产生互动效果。硬件使用熊猫板加电视机。
AI互动屏图2


AI互动屏图3

【姿态识别】
MediaPipe 是一款由 Google Research 开发并开源的多媒体机器学习模型应用框架。在谷歌,一系列重要产品,如 YouTube、Google Lens、ARCore、Google Home 以及 Nest,都已深度整合了 MediaPipe。
AI互动屏 · 熊猫板+电视机实现体感互动_image_1.webp


AI互动屏图4


AI互动屏图5


  1. import cv2
  2. import mediapipe as mp
  3. import numpy as np
  4. mp_drawing = mp.solutions.drawing_utils
  5. #mp_drawing_styles = mp.solutions.drawing_styles
  6. mp_pose = mp.solutions.pose
  7. # For webcam input:
  8. cap = cv2.VideoCapture(0)
  9. with mp_pose.Pose(
  10.     min_detection_confidence=0.5,
  11.     min_tracking_confidence=0.5) as pose:
  12.   while cap.isOpened():
  13.     success, image = cap.read()
  14.     if not success:
  15.       print("Ignoring empty camera frame.")
  16.       # If loading a video, use 'break' instead of 'continue'.
  17.       continue
  18.     # To improve performance, optionally mark the image as not writeable to
  19.     # pass by reference.
  20.     image.flags.writeable = False
  21.     image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  22.     results = pose.process(image)
  23.     # Draw the pose annotation on the image.
  24.     image.flags.writeable = True
  25.     image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
  26.     mp_drawing.draw_landmarks(
  27.         image,
  28.         results.pose_landmarks,
  29.         mp_pose.POSE_CONNECTIONS,
  30.         )
  31.     # Flip the image horizontally for a selfie-view display.
  32.     cv2.imshow('MediaPipe Pose', cv2.flip(image, 1))
  33.     if cv2.waitKey(5) & 0xFF == 27:
  34.       break
  35. cap.release()
复制代码

【提取关键点坐标】
cvzone是一个计算机视觉工具包,可方便的图像处理和实现视觉AI功能。核心是使用OpenCV和Mediapipe库。
AI互动屏图6


  1. from cvzone.PoseModule import PoseDetector
  2. import cv2
  3. import numpy as np
  4. cap = cv2.VideoCapture(0)
  5. detector = PoseDetector()
  6. while True:
  7.     success, img = cap.read()
  8.     img = detector.findPose(img,draw=False)
  9.     img_show = np.zeros([480,640,3],np.uint8)
  10.     lmList = []
  11.     if detector.results.pose_landmarks:
  12.             for id, lm in enumerate(detector.results.pose_landmarks.landmark):
  13.                 h, w, c = img.shape
  14.                 cx, cy, cz = int(lm.x * w), int(lm.y * h), int(lm.z * w)
  15.                 lmList.append([id, cx, cy, cz])
  16.                 cv2.circle(img_show, (cx, cy), 5, (255, 0, 0), cv2.FILLED)
  17.       
  18.     cv2.imshow("Image", img_show)
  19.     cv2.imshow("Image1", img)
  20.     if cv2.waitKey(1) & 0xFF == ord('q'):
  21.         break
  22. cap.release()
  23. cv2.destroyAllWindows()
复制代码

【PD算法】
第一个小球图形,坐标跟随手部坐标,如(lmList[15][1],lmList[15][2]),其它小球图形使用比例P、积分D控制进行跟随,产生弹性效果。
  1.                   disX=MycircleR[i][0]-MycircleR[i-1][0]
  2.                    disY=MycircleR[i][1]-MycircleR[i-1][1]
  3.                    sumdisRX[i]+=disX
  4.                    sumdisRY[i]+=disY
  5.                    MycircleR[i][0]=int(MycircleR[i-1][0]+0.05*disX-0.001*sumdisRX[i])
  6.                    MycircleR[i][1]=int(MycircleR[i-1][1]+0.05*disY+i*10-0.001*sumdisRY[i])
复制代码
AI互动屏图7

【完整程序】
  1. from cvzone.PoseModule import PoseDetector
  2. import cv2
  3. import numpy as np
  4. cap = cv2.VideoCapture(0)
  5. detector = PoseDetector()
  6. MycircleL=[]
  7. sumdisLX=[]
  8. sumdisLY=[]
  9. MycircleR=[]
  10. sumdisRX=[]
  11. sumdisRY=[]
  12. num=10
  13. for i in range(num):
  14. MycircleL.append([0,0])
  15. sumdisLX.append(0)
  16. sumdisLY.append(0)
  17. MycircleR.append([0,0])
  18. sumdisRX.append(0)
  19. sumdisRY.append(0)
  20. PoseList=[8,6,6,5,5,4,4,0,0,1,1,2,2,3,3,7,10,9,18,20,18,16,20,16,22,16,16,14,14,12,12,11,12,24,24,23,24,26,26,28,28,32,32,30,28,30,11,13,13,15,15,21,15,17,17,19,19,15,11,23,23,25,25,27,27,29,29,31,31,27]
  21. def Myline(pose1,pose2):
  22.     global img_show,lmList
  23.     cv2.line(img_show,(lmList[pose1][1],lmList[pose1][2]),(lmList[pose2][1],lmList[pose2][2]),(0,255,255),4)
  24. while True:
  25.     success, img = cap.read()
  26.     img=cv2.resize(img,(1366,768))
  27.     img = detector.findPose(img,draw=False)
  28.     img_show = np.zeros([768,1366,3],np.uint8)
  29.     lmList = []
  30.     if detector.results.pose_landmarks:
  31.             for id, lm in enumerate(detector.results.pose_landmarks.landmark):
  32.                 h, w, c = img.shape
  33.                 cx, cy, cz = int(lm.x * w), int(lm.y * h), int(lm.z * w)
  34.                 lmList.append([id, cx, cy, cz])
  35.                 cv2.circle(img_show, (cx, cy), 8, (255, 0, 0), cv2.FILLED)
  36.             for i in range(num-1,0,-1):
  37.                    disX=MycircleL[i][0]-MycircleL[i-1][0]
  38.                    disY=MycircleL[i][1]-MycircleL[i-1][1]
  39.                    sumdisLX[i]+=disX
  40.                    sumdisLY[i]+=disY
  41.                    MycircleL[i][0]=int(MycircleL[i-1][0]+0.05*disX-0.001*sumdisLX[i])
  42.                    MycircleL[i][1]=int(MycircleL[i-1][1]+0.05*disY+i*10-0.001*sumdisLY[i])
  43.             MycircleL[0][0]=lmList[15][1]
  44.             MycircleL[0][1]=lmList[15][2]
  45.             for i in range(num-1,0,-1):
  46.                    disX=MycircleR[i][0]-MycircleR[i-1][0]
  47.                    disY=MycircleR[i][1]-MycircleR[i-1][1]
  48.                    sumdisRX[i]+=disX
  49.                    sumdisRY[i]+=disY
  50.                    MycircleR[i][0]=int(MycircleR[i-1][0]+0.05*disX-0.001*sumdisRX[i])
  51.                    MycircleR[i][1]=int(MycircleR[i-1][1]+0.05*disY+i*10-0.001*sumdisRY[i])
  52.             MycircleR[0][0]=lmList[16][1]
  53.             MycircleR[0][1]=lmList[16][2]
  54.             
  55.             for i in range(0,len(PoseList)-1,2):
  56.                   print(i)
  57.                   Myline(PoseList[i],PoseList[i+1])
  58.             for i in range(num):
  59.                 cv2.circle(img_show, (MycircleL[i][0], MycircleL[i][1]), 8, (0, 0, 255), cv2.FILLED)
  60.                 cv2.circle(img_show, (MycircleR[i][0], MycircleR[i][1]), 8, (0, 0, 255), cv2.FILLED)
  61.             
  62.     cv2.imshow("Image", img_show)
  63.     cv2.imshow("Image1", img)
  64.     if cv2.waitKey(1) & 0xFF == ord('q'):
  65.         break
  66. cap.release()
  67. cv2.destroyAllWindows()
复制代码


【演示视频】

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(1)
rzegkly
rzegkly
云天老师的作品很棒,学习了
- 没有更多了 -