云天 发表于 2023-4-8 18:34:01

AI互动屏

本帖最后由 云天 于 2023-4-10 15:08 编辑



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



【姿态识别】
MediaPipe 是一款由 Google Research 开发并开源的多媒体机器学习模型应用框架。在谷歌,一系列重要产品,如 YouTube、Google Lens、ARCore、Google Home 以及 Nest,都已深度整合了 MediaPipe。
https://mc.dfrobot.com.cn/forum.php?mod=attachment&aid=MTM1OTUyfDkzMDBmNTExfDE2ODA5NDg2ODF8ODI3Nzg0fDMxMTUxNw%3D%3D&noupdate=yes






import cv2
import mediapipe as mp
import numpy as np
mp_drawing = mp.solutions.drawing_utils
#mp_drawing_styles = mp.solutions.drawing_styles
mp_pose = mp.solutions.pose


# For webcam input:
cap = cv2.VideoCapture(0)
with mp_pose.Pose(
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5) as pose:
while cap.isOpened():
    success, image = cap.read()
    if not success:
      print("Ignoring empty camera frame.")
      # If loading a video, use 'break' instead of 'continue'.
      continue

    # To improve performance, optionally mark the image as not writeable to
    # pass by reference.
    image.flags.writeable = False
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    results = pose.process(image)

    # Draw the pose annotation on the image.
    image.flags.writeable = True
    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
    mp_drawing.draw_landmarks(
      image,
      results.pose_landmarks,
      mp_pose.POSE_CONNECTIONS,
      )
    # Flip the image horizontally for a selfie-view display.
    cv2.imshow('MediaPipe Pose', cv2.flip(image, 1))
    if cv2.waitKey(5) & 0xFF == 27:
      break
cap.release()

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



from cvzone.PoseModule import PoseDetector
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
detector = PoseDetector()

while True:
    success, img = cap.read()
    img = detector.findPose(img,draw=False)
    img_show = np.zeros(,np.uint8)
    lmList = []
    if detector.results.pose_landmarks:
            for id, lm in enumerate(detector.results.pose_landmarks.landmark):
                h, w, c = img.shape
                cx, cy, cz = int(lm.x * w), int(lm.y * h), int(lm.z * w)
                lmList.append()
                cv2.circle(img_show, (cx, cy), 5, (255, 0, 0), cv2.FILLED)
      
    cv2.imshow("Image", img_show)
    cv2.imshow("Image1", img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
      break
cap.release()
cv2.destroyAllWindows()

【PD算法】
第一个小球图形,坐标跟随手部坐标,如(lmList[15][1],lmList[15][2]),其它小球图形使用比例P、积分D控制进行跟随,产生弹性效果。
                  disX=MycircleR-MycircleR
                   disY=MycircleR-MycircleR
                   sumdisRX+=disX
                   sumdisRY+=disY
                   MycircleR=int(MycircleR+0.05*disX-0.001*sumdisRX)
                   MycircleR=int(MycircleR+0.05*disY+i*10-0.001*sumdisRY)
【完整程序】

from cvzone.PoseModule import PoseDetector
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
detector = PoseDetector()
MycircleL=[]
sumdisLX=[]
sumdisLY=[]
MycircleR=[]
sumdisRX=[]
sumdisRY=[]
num=10
for i in range(num):
MycircleL.append()
sumdisLX.append(0)
sumdisLY.append(0)
MycircleR.append()
sumdisRX.append(0)
sumdisRY.append(0)
PoseList=
def Myline(pose1,pose2):
    global img_show,lmList
    cv2.line(img_show,(lmList,lmList),(lmList,lmList),(0,255,255),4)
while True:
    success, img = cap.read()
    img=cv2.resize(img,(1366,768))
    img = detector.findPose(img,draw=False)
    img_show = np.zeros(,np.uint8)
    lmList = []

    if detector.results.pose_landmarks:
            for id, lm in enumerate(detector.results.pose_landmarks.landmark):
                h, w, c = img.shape
                cx, cy, cz = int(lm.x * w), int(lm.y * h), int(lm.z * w)
                lmList.append()
                cv2.circle(img_show, (cx, cy), 8, (255, 0, 0), cv2.FILLED)
            for i in range(num-1,0,-1):
                   disX=MycircleL-MycircleL
                   disY=MycircleL-MycircleL
                   sumdisLX+=disX
                   sumdisLY+=disY
                   MycircleL=int(MycircleL+0.05*disX-0.001*sumdisLX)
                   MycircleL=int(MycircleL+0.05*disY+i*10-0.001*sumdisLY)
            MycircleL=lmList
            MycircleL=lmList
            for i in range(num-1,0,-1):
                   disX=MycircleR-MycircleR
                   disY=MycircleR-MycircleR
                   sumdisRX+=disX
                   sumdisRY+=disY
                   MycircleR=int(MycircleR+0.05*disX-0.001*sumdisRX)
                   MycircleR=int(MycircleR+0.05*disY+i*10-0.001*sumdisRY)
            MycircleR=lmList
            MycircleR=lmList
            
            for i in range(0,len(PoseList)-1,2):
                  print(i)
                  Myline(PoseList,PoseList)
            for i in range(num):
                cv2.circle(img_show, (MycircleL, MycircleL), 8, (0, 0, 255), cv2.FILLED)
                cv2.circle(img_show, (MycircleR, MycircleR), 8, (0, 0, 255), cv2.FILLED)
            
    cv2.imshow("Image", img_show)
    cv2.imshow("Image1", img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
      break
cap.release()
cv2.destroyAllWindows()


【演示视频】
https://www.bilibili.com/video/BV1bm4y1B7tE/?share_source=copy_web&vd_source=98855d5b99ff76982639c5ca6ff6f528

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

云天老师的作品很棒,学习了
页: [1]
查看完整版本: AI互动屏