### 동영상과 mediapipe-hand 를 연결하기
import cv2
import mediapipe as mp
# 손을 찾는 기능 불러오기
mp_hands = mp.solutions.hands
# 특징점 그리기 설정
mp_drawing = mp.solutions.drawing_utils
# 손 특징점 찾기 관련 설정
hands = mp_hands.Hands(
max_num_hands = 2,
min_detection_confidence = 0.5, # 손 검출 확률(자체판단) 50%이상인 것들만 출력하기
min_tracking_confidence = 0.5 # 특징점 검출 확률(자체 판단) 50%이상인 것들만 출력하기
)
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, img = cap.read()
img = cv2.flip(img, 1)
if not ret:
break
# 이미지에서 원하는 대상(손) 찾기
result = hands.process(img)
# 손을 검출했다면 표현하기(21개의 특징점을 찾음)
if result.multi_hand_landmarks is not None:
# 21개 특징점을 하나씩 그려주기
for res in result.multi_hand_landmarks:
mp_drawing.draw_landmarks(img, res, mp_hands.HAND_CONNECTIONS)
cv2.imshow('video',img)
if cv2.waitKey(33) == 49:
break
cap.release()
cv2.destroyAllWindows()
- 손에서 특징점 21개 찾기 완료
- 특징점들을 연결해서 뼈 만들기
- 뼈와 뼈 사이의 각도 구하기
- 동작에 따라 각도의 변화가 많은 15개의 각도 사용
- KNN에 예측시켜서 어떤 동작인지 구분하기
In [2]:
### 동영상과 mediapipe-hand 를 연결하기
## 한 손의 동작 인식하기
import cv2
import mediapipe as mp
gesture = {
0:'fist', 1:'one', 2:'two', 3:'three', 4:'four', 5:'five',
6:'six', 7:'rock', 8:'spiderman', 9:'yeah', 10:'ok',
}
# gesture_train을 머신러닝 모델에 학습
import numpy as np
file = np.genfromtxt('images/gesture_train.csv', delimiter = ",")
angle = file[:, :-1].astype(np.float32) # 문제데이터
label = file[:, -1].astype(np.float32) # 정답데이터
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors = 3)
knn.fit(angle, label)
# 손을 찾는 기능 불러오기
mp_hands = mp.solutions.hands
# 특징점 그리기 설정
mp_drawing = mp.solutions.drawing_utils
# 손 특징점 찾기 관련 설정
hands = mp_hands.Hands(
max_num_hands = 1,
min_detection_confidence = 0.5, # 손 검출 확률(자체판단) 50%이상인 것들만 출력하기
min_tracking_confidence = 0.5 # 특징점 검출 확률(자체 판단) 50%이상인 것들만 출력하기
)
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, img = cap.read()
img = cv2.flip(img, 1)
if not ret:
break
# 이미지에서 원하는 대상(손) 찾기
result = hands.process(img)
# 손을 검출했다면 표현하기(21개의 특징점을 찾음)
if result.multi_hand_landmarks is not None:
# 21개 특징점을 하나씩 그려주기
for res in result.multi_hand_landmarks:
# 21개의 특징점 위치 저장할 용도(x,y,z)
joint = np.zeros((21,3))
# 21개의 특징점 저장
# enumerate : 반복문의 순서를 알려줌, 추가적인 변수 하나가 더 필요
for j, lm in enumerate(res.landmark):
joint[j] = [lm.x, lm.y, lm.z]
# 특징점을 연결해서 뼈의 값 구하기(좌표값 기반-x,y,z)
v1 = joint[[0,1,2,3,0,5,6,7,0,9,10,11,0,13,14,15,0,17,18,19],:]
v2 = joint[[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],:]
v = v2 - v1 # [20,3]
# 뼈의 직선 구하기
v = v / np.linalg.norm(v, axis=1)[:, np.newaxis]
# 뼈의 직선을 통해서 각도 구하기(각도의 변화가 큰 15개만 사)
angle = np.arccos(np.einsum('nt,nt->n',
v[[0,1,2,4,5,6,8,9,10,12,13,14,16,17,18],:],
v[[1,2,3,5,6,7,9,10,11,13,14,15,17,18,19],:]))
# radian 각도를 degree 각도로 변경하기
angle = np.degrees(angle)
# 학습된 KNN 모델에 동작 예측시키기
# 예측시킬 데이터 전처리하기
data = np.array([angle], dtype=np.float32)
# 예측하기
results = knn.predict(data)
idx = int(results)
# cv2.putText : 이미지 위에 글씨 쓰기
# 사용할 이미지, 쓸 글씨(영어), 글씨 위치, 폰트, 글씨 크기, 글씨 색깔, 글씨 두께
cv2.putText(img, text=gesture[idx].upper(), org=(int(res.landmark[0].x * img.shape[1]), int(res.landmark[0].y * img.shape[0] + 20)), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=(255, 255, 255), thickness=2)
mp_drawing.draw_landmarks(img, res, mp_hands.HAND_CONNECTIONS)
cv2.imshow('video',img)
if cv2.waitKey(33) == 49:
break
cap.release()
cv2.destroyAllWindows()
In [3]:
rsp_result
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[3], line 1
----> 1 rsp_result
NameError: name 'rsp_result' is not defined
In [ ]:
### 동영상과 mediapipe-hand 를 연결하기
## 한 손의 동작 인식하기
import cv2
import mediapipe as mp
gesture = {
0:'fist', 1:'one', 2:'two', 3:'three', 4:'four', 5:'five',
6:'six', 7:'rock', 8:'spiderman', 9:'yeah', 10:'ok',
}
rsp_gesture = {
0:'rock', 9:'scissors', 5:'paper'
}
# gesture_train을 머신러닝 모델에 학습
import numpy as np
file = np.genfromtxt('images/gesture_train.csv', delimiter = ",")
angle = file[:, :-1].astype(np.float32) # 문제데이터
label = file[:, -1].astype(np.float32) # 정답데이터
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors = 3)
knn.fit(angle, label)
# 손을 찾는 기능 불러오기
mp_hands = mp.solutions.hands
# 특징점 그리기 설정
mp_drawing = mp.solutions.drawing_utils
# 손 특징점 찾기 관련 설정
hands = mp_hands.Hands(
max_num_hands = 2,
min_detection_confidence = 0.5, # 손 검출 확률(자체판단) 50%이상인 것들만 출력하기
min_tracking_confidence = 0.5 # 특징점 검출 확률(자체 판단) 50%이상인 것들만 출력하기
)
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, img = cap.read()
img = cv2.flip(img, 1)
if not ret:
break
# 이미지에서 원하는 대상(손) 찾기
result = hands.process(img)
# 손을 검출했다면 표현하기(21개의 특징점을 찾음)
if result.multi_hand_landmarks is not None:
# 가위바위보 결과 저장할 변
rsp_result = []
# 21개 특징점을 하나씩 그려주기
for res in result.multi_hand_landmarks:
# 21개의 특징점 위치 저장할 용도(x,y,z)
joint = np.zeros((21,3))
# 21개의 특징점 저장
# enumerate : 반복문의 순서를 알려줌, 추가적인 변수 하나가 더 필요
for j, lm in enumerate(res.landmark):
joint[j] = [lm.x, lm.y, lm.z]
# 특징점을 연결해서 뼈의 값 구하기(좌표값 기반-x,y,z)
v1 = joint[[0,1,2,3,0,5,6,7,0,9,10,11,0,13,14,15,0,17,18,19],:]
v2 = joint[[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],:]
v = v2 - v1 # [20,3]
# 뼈의 직선 구하기
v = v / np.linalg.norm(v, axis=1)[:, np.newaxis]
# 뼈의 직선을 통해서 각도 구하기(각도의 변화가 큰 15개만 사)
angle = np.arccos(np.einsum('nt,nt->n',
v[[0,1,2,4,5,6,8,9,10,12,13,14,16,17,18],:],
v[[1,2,3,5,6,7,9,10,11,13,14,15,17,18,19],:]))
# radian 각도를 degree 각도로 변경하기
angle = np.degrees(angle)
# 학습된 KNN 모델에 동작 예측시키기
# 예측시킬 데이터 전처리하기
data = np.array([angle], dtype=np.float32)
# 예측하기
results = knn.predict(data)
idx = int(results)
# cv2.putText : 이미지 위에 글씨 쓰기
# 사용할 이미지, 쓸 글씨(영어), 글씨 위치, 폰트, 글씨 크기, 글씨 색깔, 글씨 두께
# 동작이 주먹, 가위, 보 일때만 실행
if idx in rsp_gesture.keys():
# 주먹, 가위, 보의 동작만 글씨 쓰기
org = (int(res.landmark[0].x * img.shape[1]), int(res.landmark[0].y * img.shape[0]))
cv2.putText(img, text=rsp_gesture[idx].upper(), org=(org[0], org[1] + 20), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=(255, 255, 255), thickness=2)
# 주먹, 가위, 보의 동작값 저장하기
rsp_result.append({
'rsp' : rsp_gesture[idx],
'org' : org
})
mp_drawing.draw_landmarks(img, res, mp_hands.HAND_CONNECTIONS)
# 누가 이겼나?
# 두 개의 결과값이 저장이 되어야 실행
if len(rsp_result) == 2:
winner = None # 누가 이겼는지 저장할 변수
text = '' # 어떤 동작이 이겼는지 저장 or 비김
if rsp_result[0]['rsp'] == 'rock':
if rsp_result[1]['rsp'] == 'rock': text = 'Tie'
elif rsp_result[1]['rsp'] == 'paper': text = 'Paper Win'; winner = 1
elif rsp_result[1]['rsp'] == 'scissors' : text = 'Rock Win'; winner = 0
elif rsp_result[0]['rsp'] == 'paper':
if rsp_result[1]['rsp'] == 'rock': text = 'Paper Win'; winner = 0
elif rsp_result[1]['rsp'] == 'paper': text = 'Tie'
elif rsp_result[1]['rsp'] == 'scissors' : text = 'Scissors Win'; winner = 1
elif rsp_result[0]['rsp'] == 'scissors':
if rsp_result[1]['rsp'] == 'rock': text = 'Rock Win'; winner = 1
elif rsp_result[1]['rsp'] == 'paper': text = 'Scissors Win'; winner = 0
elif rsp_result[1]['rsp'] == 'scissors' : text = 'Tie'
# 이긴 사람 표시하기
if winner is not None:
cv2.putText(img, text='Winner', org=(rsp_result[winner]['org'][0], rsp_result[winner]['org'][1] + 70), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=2, color=(0, 255, 0), thickness=3)
cv2.putText(img, text=text, org=(int(img.shape[1] / 3), 100), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=2, color=(0, 0, 255), thickness=3)
cv2.imshow('video',img)
if cv2.waitKey(33) == 49:
break
cap.release()
cv2.destroyAllWindows()
'Study > Python' 카테고리의 다른 글
[Python]OpenCV - 10 Mediapipe-hand-face (1) | 2023.11.02 |
---|---|
[Python] OpenCV - 8 Mediapipe 사용하기 (0) | 2023.10.30 |
[Python] OpenCV - 7 이미지 합성하기 (0) | 2023.10.27 |
[Python] OpenCV - 6 템플릿 매칭 (0) | 2023.10.26 |
[Python]OpenCV - 5 이미지 처리 (0) | 2023.10.25 |