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
云天老师的作品很棒,学习了
页:
[1]