[项目分享]AI互动屏 精华

3837浏览
查看: 3837|回复: 1

[项目分享] AI互动屏

[复制链接]
本帖最后由 云天 于 2023-4-10 15:08 编辑

AI互动屏图1


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


AI互动屏图3

【姿态识别】
MediaPipe 是一款由 Google Research 开发并开源的多媒体机器学习模型应用框架。在谷歌,一系列重要产品,如 YouTube、Google Lens、ARCore、Google Home 以及 Nest,都已深度整合了 MediaPipe。


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()
复制代码


【演示视频】

rzegkly  版主

发表于 2023-4-8 22:29:36

云天老师的作品很棒,学习了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail