4 Star 3 Fork 3

小脚丫 / 虚拟主播-vtuber-python

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
hand_landmark.py 10.44 KB
一键复制 编辑 原始数据 按行查看 历史
import cv2 as cv
import numpy as np
import mediapipe as mp
import math
class HandDetector:
def __init__(self):
self.mp_drawing = mp.solutions.drawing_utils
self.drawing_spec = self.mp_drawing.DrawingSpec(thickness=1, circle_radius=1)
def findHands(self,image,hand_landmarks,draw=True):
# 検出実施 ############################################################
# image = cv.cvtColor(image, cv.COLOR_BGR2RGB)
self.hand=[]
# 描画 ################################################################
if hand_landmarks is not None:
if draw:
self.mp_drawing.draw_landmarks(
image = image,
landmark_list = hand_landmarks,
# connections = self.mp_face_mesh.FACEMESH_TES
landmark_drawing_spec = self.drawing_spec,
connection_drawing_spec = self.drawing_spec)
# 手の平重心計算
# cx, cy = self.calc_palm_moment(image, hand_landmarks)
# # 外接矩形の計算
# brect = self.calc_bounding_rect(image, hand_landmarks)
# # 描画
# image = self.draw_landmarks(image, cx, cy,
# hand_landmarks)
# image = self.draw_bounding_rect(image, brect)
for id, lmk in enumerate(hand_landmarks.landmark):
x, y, z = float(lmk.x), float(lmk.y), float(lmk.z)
self.hand.append([x, y, z])
return image,self.hand
def hand_filter(self,hand,width,height,filters):
self.steady_hand=[]
for i in range(0, 21):
prediction = filters[i].filter.predict()
measurement = np.array([np.float32(hand[i][0]), np.float32(hand[i][1]), np.float32(hand[i][2])])
# print(measurement)
filters[i].filter.correct(measurement)
# state = filters[i].filter.predict()
state = filters[i].filter.statePost
# print(prediction[0])
# w h w
self.steady_hand.append([state[0][0] * width, state[1][0] * height, state[2][0] * width])
return self.steady_hand
def keypoint_cal(self,hand,coff):
x1, y1 = hand[5][:2]
x2, y2 = hand[17][:2]
distance = int(math.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2))
A, B, C = coff
distanceCM = A * distance ** 2 + B * distance + C
return distanceCM
def calc_palm_moment(image, landmarks):
image_width, image_height = image.shape[1], image.shape[0]
palm_array = np.empty((0, 2), int)
for index, landmark in enumerate(landmarks.landmark):
landmark_x = min(int(landmark.x * image_width), image_width - 1)
landmark_y = min(int(landmark.y * image_height), image_height - 1)
landmark_point = [np.array((landmark_x, landmark_y))]
if index == 0: # 手首1
palm_array = np.append(palm_array, landmark_point, axis=0)
if index == 1: # 手首2
palm_array = np.append(palm_array, landmark_point, axis=0)
if index == 5: # 人差指:付け根
palm_array = np.append(palm_array, landmark_point, axis=0)
if index == 9: # 中指:付け根
palm_array = np.append(palm_array, landmark_point, axis=0)
if index == 13: # 薬指:付け根
palm_array = np.append(palm_array, landmark_point, axis=0)
if index == 17: # 小指:付け根
palm_array = np.append(palm_array, landmark_point, axis=0)
M = cv.moments(palm_array)
cx, cy = 0, 0
if M['m00'] != 0:
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])
return cx, cy
def calc_bounding_rect(image, landmarks):
image_width, image_height = image.shape[1], image.shape[0]
landmark_array = np.empty((0, 2), int)
for _, landmark in enumerate(landmarks.landmark):
landmark_x = min(int(landmark.x * image_width), image_width - 1)
landmark_y = min(int(landmark.y * image_height), image_height - 1)
landmark_point = [np.array((landmark_x, landmark_y))]
landmark_array = np.append(landmark_array, landmark_point, axis=0)
x, y, w, h = cv.boundingRect(landmark_array)
return [x, y, x + w, y + h]
def draw_landmarks(image, cx, cy, landmarks, handedness_str):
image_width, image_height = image.shape[1], image.shape[0]
landmark_point = []
# キーポイント
for index, landmark in enumerate(landmarks.landmark):
if landmark.visibility < 0 or landmark.presence < 0:
continue
landmark_x = min(int(landmark.x * image_width), image_width - 1)
landmark_y = min(int(landmark.y * image_height), image_height - 1)
# landmark_z = landmark.z
landmark_point.append((landmark_x, landmark_y))
if index == 0: # 手首1
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 1: # 手首2
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 2: # 親指:付け根
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 3: # 親指:第1関節
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 4: # 親指:指先
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
cv.circle(image, (landmark_x, landmark_y), 12, (0, 255, 0), 2)
if index == 5: # 人差指:付け根
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 6: # 人差指:第2関節
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 7: # 人差指:第1関節
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 8: # 人差指:指先
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
cv.circle(image, (landmark_x, landmark_y), 12, (0, 255, 0), 2)
if index == 9: # 中指:付け根
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 10: # 中指:第2関節
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 11: # 中指:第1関節
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 12: # 中指:指先
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
cv.circle(image, (landmark_x, landmark_y), 12, (0, 255, 0), 2)
if index == 13: # 薬指:付け根
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 14: # 薬指:第2関節
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 15: # 薬指:第1関節
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 16: # 薬指:指先
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
cv.circle(image, (landmark_x, landmark_y), 12, (0, 255, 0), 2)
if index == 17: # 小指:付け根
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 18: # 小指:第2関節
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 19: # 小指:第1関節
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
if index == 20: # 小指:指先
cv.circle(image, (landmark_x, landmark_y), 5, (0, 255, 0), 2)
cv.circle(image, (landmark_x, landmark_y), 12, (0, 255, 0), 2)
# 接続線
if len(landmark_point) > 0:
# 親指
cv.line(image, landmark_point[2], landmark_point[3], (0, 255, 0), 2)
cv.line(image, landmark_point[3], landmark_point[4], (0, 255, 0), 2)
# 人差指
cv.line(image, landmark_point[5], landmark_point[6], (0, 255, 0), 2)
cv.line(image, landmark_point[6], landmark_point[7], (0, 255, 0), 2)
cv.line(image, landmark_point[7], landmark_point[8], (0, 255, 0), 2)
# 中指
cv.line(image, landmark_point[9], landmark_point[10], (0, 255, 0), 2)
cv.line(image, landmark_point[10], landmark_point[11], (0, 255, 0), 2)
cv.line(image, landmark_point[11], landmark_point[12], (0, 255, 0), 2)
# 薬指
cv.line(image, landmark_point[13], landmark_point[14], (0, 255, 0), 2)
cv.line(image, landmark_point[14], landmark_point[15], (0, 255, 0), 2)
cv.line(image, landmark_point[15], landmark_point[16], (0, 255, 0), 2)
# 小指
cv.line(image, landmark_point[17], landmark_point[18], (0, 255, 0), 2)
cv.line(image, landmark_point[18], landmark_point[19], (0, 255, 0), 2)
cv.line(image, landmark_point[19], landmark_point[20], (0, 255, 0), 2)
# 手の平
cv.line(image, landmark_point[0], landmark_point[1], (0, 255, 0), 2)
cv.line(image, landmark_point[1], landmark_point[2], (0, 255, 0), 2)
cv.line(image, landmark_point[2], landmark_point[5], (0, 255, 0), 2)
cv.line(image, landmark_point[5], landmark_point[9], (0, 255, 0), 2)
cv.line(image, landmark_point[9], landmark_point[13], (0, 255, 0), 2)
cv.line(image, landmark_point[13], landmark_point[17], (0, 255, 0), 2)
cv.line(image, landmark_point[17], landmark_point[0], (0, 255, 0), 2)
# 重心 + 左右
if len(landmark_point) > 0:
# handedness.classification[0].index
# handedness.classification[0].score
cv.circle(image, (cx, cy), 12, (0, 255, 0), 2)
cv.putText(image, handedness_str,
(cx - 6, cy + 6), cv.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0),
2, cv.LINE_AA) # label[0]:一文字目だけ
return image
def draw_bounding_rect(image, brect):
# 外接矩形
cv.rectangle(image, (brect[0], brect[1]), (brect[2], brect[3]),
(0, 255, 0), 2)
return image
Python
1
https://gitee.com/little-feet/vtuber.git
git@gitee.com:little-feet/vtuber.git
little-feet
vtuber
虚拟主播-vtuber-python
master

搜索帮助