手勢,是人與人訊息傳達時最自然的肢體語言之一。當這些動作能被電腦正確解讀,就能開啟更多元的互動形式,例如虛擬手語翻譯、非接觸式控制、甚至是情緒與意圖識別。
本篇文章將從資料的角度出發,說明如何準備一套適合訓練手勢識別模型的資料。搭配 MediaPipe 提取關鍵點座標、OpenCV 進行視覺化,我們將一步步完成從影像到訓練數據的轉換。
我們使用的資料集來自 Kaggle 的 Sign Language MNIST,其特點如下:
雖然該資料集來源為靜態圖片,但它非常適合用來做為 CNN 模型的入門資料。若日後要擴展到動態識別(J和Z)或即時鏡頭互動,亦可搭配 MediaPipe 建立自有資料集。
本次任務包含以下步驟:
資料集包含兩個 CSV 檔案:
sign_mnist_train.csv
:訓練資料sign_mnist_test.csv
:測試資料import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 讀取資料
df = pd.read_csv("sign_mnist_train.csv")
labels = df['label'].values
images = df.drop('label', axis=1).values.reshape(-1, 28, 28)
# 顯示前 10 個標籤影像
plt.figure(figsize=(10, 2))
for i in range(10):
plt.subplot(1, 10, i+1)
plt.imshow(images[i], cmap='gray')
plt.title(chr(labels[i] + 65)) # 轉換為英文字母
plt.axis('off')
plt.suptitle("Sign Language MNIST Samples")
plt.show()
CNN 通常需要這段格式:(Channel, Height, Width),所以我們加入 channel 維度,並將畫素值標準化為 0~1:
import torch
from torch.utils.data import TensorDataset, DataLoader
# Normalize and reshape
images = images / 255.0
images = images[:, np.newaxis, :, :] # 加上 Channel 維度
# 轉為 PyTorch tensor
X = torch.tensor(images, dtype=torch.float32)
y = torch.tensor(labels, dtype=torch.long)
# 建立 DataLoader
dataset = TensorDataset(X, y)
train_loader = DataLoader(dataset, batch_size=64, shuffle=True)
看看每個類別的標籤分佈,了解是否均衡:
import seaborn as sns
plt.figure(figsize=(10, 4))
sns.countplot(x=labels)
plt.title("Class Distribution")
plt.xlabel("Class (A-Z, excluding J)")
plt.ylabel("Sample Count")
plt.show()
雖然這個資料集是靜態圖片,但如果想把模型應用到鏡頭輸入中,我們可以使用 MediaPipe Hands 即時偵測手部關鍵點,再透過 OpenCV 擷取手勢圖像進行視覺化與分類。
後續篇章將介紹:
資料是訓練模型的根基,而手勢識別的第一步,就是對資料的理解與整理。無論是使用公開資料集,還是日後搭配鏡頭收集自有資料,這一篇希望能幫助你打好資料準備的基礎功。