-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhantei.py
128 lines (86 loc) · 3.57 KB
/
hantei.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import cv2
import numpy as np
from skimage.feature import hog
from sklearn.neighbors import NearestNeighbors
cap = cv2.VideoCapture(0)
# 特徴量の読み込み
features = np.load("./data/features.npy")
labels = np.load("./data/labels.npy")
# 最近傍探索のモデルを定義
model = NearestNeighbors(n_neighbors=1).fit(features)
# スクショしたかどうかを保存する変数 (まだ撮っていないのでFalse)
screenshot = False
# スクショを保存する変数
photo = None
# ノイズ除去のためのカーネルの定義
kernel = np.ones((5, 5), np.uint8)
# 画面に表示する文字列
display_str = "Please Janken."
# クラス名とIDの組み合わせ
class_name = None
LABEL2CLS = {0: "rock", 1: "scissors", 2: "paper"}
# 実行
while True:
# Webカメラのフレーム取得
ret, frame = cap.read()
src = frame.copy()
# 今映っている人のクラスを表示
# putText(描画画像、 書き込む文字列、 書き込む座標、 フォント、 サイズ、 色、 太さ)
if class_name is not None:
display_str = f"class: {class_name}"
cv2.putText(
src, display_str, (30, 30), cv2.FONT_HERSHEY_PLAIN, 2, (0, 0, 0), 1,
)
cv2.imshow("camera", src)
# キーボードの入力の受付
k = cv2.waitKey(1)
frame = np.clip(1.0 * frame + 50.0, 0, 255).astype(np.uint8)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# HSVによる上限、下限の設定 ([Hue, Saturation, Value])
hsvLower = np.array([-10, 60, 60]) # 下限
hsvUpper = np.array([40, 255, 255]) # 上限
# HSVからマスクを作成
hsv_mask = cv2.inRange(hsv, hsvLower, hsvUpper)
# 白色領域のノイズを除去する
hsv_mask = cv2.erode(hsv_mask, kernel) # 収縮処理
hsv_mask = cv2.dilate(hsv_mask, kernel) # 膨張処理
nlabels, labels2, stats, centroids = cv2.connectedComponentsWithStats(hsv_mask)
if nlabels >= 3:
# 面積でソート(今回は面積が上位2つの領域を利用)
top_idx = stats[:, 4].argsort()[-2:-1]
# 各領域において...
for i in top_idx:
# ターミナル上に詳細表示
print(
"[x0: {}, y0: {}, x幅: {}, y幅: {}, 面積: {}]".format(
stats[i, 0], stats[i, 1], stats[i, 2], stats[i, 3], stats[i, 4]
)
)
# 領域の外接矩形の角座標を入手
x0 = stats[i, 0]
y0 = stats[i, 1]
x1 = x0 + stats[i, 2]
y1 = y0 + stats[i, 3]
# 長方形描画 (引数 : 描画画像、 長方形の左上角、 長方形の右下角、 色(BGR)、 線の太さ)
# grayscaleに変換
gray = cv2.cvtColor(
src[y0 : y1 + 1, x0 : x1 + 1], cv2.COLOR_BGR2GRAY
)
# リサイズ (H, W) = (56, 56) ※要調整
gray = cv2.resize(gray, (56, 84))
cv2.imshow("gray", gray)
# HOGによって特徴抽出
feat = hog(gray)
# 配列の形を変更 (56*56,) => (1, 56*56)
# feat = feat.reshape(1, 56 * 56) と同じ
feat = feat.reshape(1, -1)
# 最近傍探索. 二重のリストで結果が返ってくる.
distances, indices = model.kneighbors(feat)
# 近かった特徴量のインデックス(indicies)をクラスのラベルに変換
label = labels[indices[0][0]]
class_name = LABEL2CLS[label]
# 終了
if k == ord("q"):
break
cap.release()
cv2.destroyAllWindows()