변수와의 관계를 분석하고 값을 예측하는 방법

일단 이 행동을 하려면 그래프를 그려서 어떤 경향이 있긴 한 건지 확인하고
지금 같은 그래프에선 양의 상관관계가 있으니 저렇게 선을 그어 경향을 확인할 수 있습니다.
식은 뭐 이렇습니다.

그리고 실젯값과 예측값을 비슷하게 하는 과정에서 최소제곱법이 나옵니다. 거기서 나온 걸 Cost라고 하겠죠. 그걸 줄이고 줄여서 최소로 만드는 게 목표입니다.

뭐 이런 거고요. 사람이 직접 한다면 이 식에다 직접 대입해야 해서 번거롭지만

잉공지능은 알잘딱하고 빠르게 작업해 줍니다.
최소한의 전처리(가공)를 하도록 하는 머신러닝의 종류
정말 쉽게 설명하자면 보이는 것만 분석하면 너무 비효율적입니다. 그런 방식은 모든 종류의 개와 그 개의 각도 그런 걸 다 분석해야 한다고 보면 됩니다.

그래서 차라리 숫자로 간략하게 표현해서 분석하는 합성곱 신경망(CNN)을 쓰면 되겠네 한 거죠.

뭐 당연히 너무 적은 자료로는 효율적으로 사용할 수 없고 어느 정도 있으면 분석 결과가 아주 보기 좋게 된다 보시면 됩니다.
CNN 종류로는 Convolutional Layer, Pooling Layer, Fully Connected Layer가 있습니다.
Convolutional Layer는 뭐 이런 거고요. 행렬 제곱으로 특징이 비슷한지 하는 걸 확인할 수 있고요.

Pooling Layer는 뭐 이런 겁니다. 흠 뭐 최댓값, 평균, 최솟값을 이용해서 간략하게 표현하는 방법이 있다 정도로 보시면 되겠네요.

Fully Connected Layer는 뭐 뉴런 생각하시면 되는데 그것마냥 Convolutional Layer 에서 나온 데이터를 1차원으로 펴서 효과적으로 학습한다 보면 되네요.
아주 큰 데이터셋에 훈련된 가중치를 들고 와서 보정해 사용하는 것
음, 한마디로 우리 같이 돈 없는 사람이 다른 사람이 학습한 모델을 갖다가 좀 바꿔서 하는 학습이라 보면 되겠네요.

(출처: Flaticon - Eucalyp)
하 원래 가운데 손가락 안 올리는데... 어쩔 수 없네요.
import cv2
import mediapipe as mp
import numpy as np
max_num_hands = 5
gesture = {
0: 'fist', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five',
6: 'six', 7: 'rock', 8: 'spiderman', 9: 'yeah', 10: 'ok', 11: 'fy'
}
mp_hands = mp.solutions.hands
mp_drawing = mp.solutions.drawing_utils
hands = mp_hands.Hands(
max_num_hands = max_num_hands,
min_detection_confidence = 0.5,
min_tracking_confidence = 0.5
)
file = np.genfromtxt('data/gesture_train_fy.csv', delimiter=',')
angle = file[:,:-1].astype(np.float32)
label = file[:, -1].astype(np.float32)
knn = cv2.ml.KNearest_create()
knn.train(angle, cv2.ml.ROW_SAMPLE, label)
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, img = cap.read()
if not ret:
continue
img = cv2.flip(img, 1)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
result = hands.process(img)
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
if result.multi_hand_landmarks is not None:
for res in result.multi_hand_landmarks:
joint = np.zeros((21, 3))
for j, lm in enumerate(res.landmark):
joint[j] = [lm.x, lm.y, lm.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]
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], :]))
angle = np.degrees(angle)
ret, results, neighbours, dist = knn.findNearest(data, 3)
idx = int(results[0][0])
if idx == 11:
x1, y1 = tuple((joint.min(axis=0)[:2] * [img.shape[1], img.shape[0]] * 0.95).astype(int))
x2, y2 = tuple((joint.max(axis=0)[:2] * [img.shape[1], img.shape[0]] * 1.05).astype(int))
fy_img = img[y1:y2, x1:x2].copy()
fy_img = cv2.resize(fy_img, dsize=None, fx=0.05, fy=0.05, interpolation=cv2.INTER_NEAREST)
fy_img = cv2.resize(fy_img, dsize=(x2 - x1, y2 - y1), interpolation=cv2.INTER_NEAREST)
img[y1:y2, x1:x2] = fy_img
# mp_drawing.draw_landmarks(img, res, mp_hands.HAND_CONNECTIONS)
cv2.imshow('Filter', img)
if cv2.waitKey(1) == ord('q'):
break
