Skip to content

Commit 078fbca

Browse files
committed
stock & HERO
1 parent fc81d07 commit 078fbca

7 files changed

+259
-22
lines changed

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ python3 SSBUFrameAnalyzer.py DIGIT_DICTIONARY_FILE CHARA_DICTIONARY_FILE SCREENS
99

1010
1280x720のカラー画像のみ受け付けます(mainの場合内部で自動リサイズします)。
1111

12-
`DIGIT_DICTIONALY_FILE``CHARA_DICTIONARY_FILE`はそれぞれ、ダメージ値の数値画像から計算したHOG特徴量、対戦中のキャラ顔画像から計算したHOG特徴量を格納したjsonです(Releasesに添付)。あんまり検証してません。
12+
`DIGIT_DICTIONALY_FILE``CHARA_DICTIONARY_FILE``STOCK_DICTIONARY_FILE`はそれぞれ、ダメージ値の数値画像から計算したHOG特徴量、対戦中のキャラ顔画像から計算したHOG特徴量、対戦中のキャラストック画像から計算したHOG特徴量を格納したjsonです(Releasesに添付)。(精度は)あんまり検証してません。
1313

1414
いまのところ、2人、3人、4人対戦のみです。
1515

@@ -23,3 +23,6 @@ python3 SSBUFrameAnalyzer.py DIGIT_DICTIONARY_FILE CHARA_DICTIONARY_FILE SCREENS
2323
- numpy
2424
- scikit-image
2525

26+
## 対応キャラクター(仮)
27+
28+
勇者までの全キャラクター(DLC: パックンフラワー、ジョーカー、勇者含む)

calc_chara_hog.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import argparse
2+
from skimage.feature import hog
3+
import numpy as np
4+
import os
5+
import cv2
6+
import json
7+
8+
parser = argparse.ArgumentParser()
9+
parser.add_argument('in_dir', type=str)
10+
parser.add_argument('out_file', type=str)
11+
12+
args = parser.parse_args()
13+
14+
data = {}
15+
for cat_name in sorted(os.listdir(args.in_dir)):
16+
cat_path = os.path.join(args.in_dir, cat_name)
17+
if not os.path.isdir(cat_path):
18+
continue
19+
20+
data_chara = []
21+
for in_file in sorted(os.listdir(cat_path)):
22+
in_path = os.path.join(cat_path, in_file)
23+
img = cv2.imread(in_path, 0) # grayscale
24+
# img = cv2.resize(img, (110, 110))
25+
ft = hog(img)
26+
data_chara.append(ft.tolist())
27+
28+
data[cat_name] = data_chara
29+
30+
os.makedirs(os.path.dirname(args.out_file), exist_ok=True)
31+
with open(args.out_file, 'w') as fp:
32+
json.dump(data, fp)

calc_damage_hog.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import argparse
2+
from skimage.feature import hog
3+
import numpy as np
4+
import os
5+
import cv2
6+
import json
7+
8+
parser = argparse.ArgumentParser()
9+
parser.add_argument('in_dir', type=str)
10+
parser.add_argument('out_file', type=str)
11+
12+
args = parser.parse_args()
13+
14+
data = {}
15+
for cat_name in sorted(os.listdir(args.in_dir)):
16+
cat_path = os.path.join(args.in_dir, cat_name)
17+
if not os.path.isdir(cat_path):
18+
continue
19+
20+
digit = int(cat_name)
21+
print(digit)
22+
23+
data_digit = []
24+
for in_file in sorted(os.listdir(cat_path)):
25+
in_path = os.path.join(cat_path, in_file)
26+
img = cv2.imread(in_path, 0) # grayscale
27+
img = cv2.resize(img, (35, 55))
28+
ft = hog(img)
29+
data_digit.append(ft.tolist())
30+
31+
data[digit] = data_digit
32+
33+
os.makedirs(os.path.dirname(args.out_file), exist_ok=True)
34+
with open(args.out_file, 'w') as fp:
35+
json.dump(data, fp)

calc_stock_hog.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import argparse
2+
from skimage.feature import hog
3+
import numpy as np
4+
import os
5+
import cv2
6+
import json
7+
8+
parser = argparse.ArgumentParser()
9+
parser.add_argument('in_dir', type=str)
10+
parser.add_argument('out_file', type=str)
11+
12+
args = parser.parse_args()
13+
14+
data = {}
15+
for cat_name in sorted(os.listdir(args.in_dir)):
16+
cat_path = os.path.join(args.in_dir, cat_name)
17+
if not os.path.isdir(cat_path):
18+
continue
19+
20+
data_chara = []
21+
for in_file in sorted(os.listdir(cat_path)):
22+
in_path = os.path.join(cat_path, in_file)
23+
img = cv2.imread(in_path, 0) # grayscale
24+
img = cv2.resize(img, (30, 30))
25+
ft = hog(img)
26+
data_chara.append(ft.tolist())
27+
28+
data[cat_name] = data_chara
29+
30+
os.makedirs(os.path.dirname(args.out_file), exist_ok=True)
31+
with open(args.out_file, 'w') as fp:
32+
json.dump(data, fp)

get_chara_shots.py

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import cv2
2+
import argparse
3+
from PIL import Image
4+
import os
5+
import numpy as np
6+
import SSBUBoundingBoxUtil
7+
8+
parser = argparse.ArgumentParser()
9+
parser.add_argument('in_file', type=str)
10+
parser.add_argument('out_dir', type=str)
11+
parser.add_argument('fighter_num', type=int)
12+
args = parser.parse_args()
13+
14+
15+
os.makedirs(args.out_dir, exist_ok=True)
16+
17+
frame_files = None
18+
cap = None
19+
if os.path.isdir(args.in_file):
20+
frame_files = [ os.path.join(args.in_file, file) for file in os.listdir(args.in_file) ]
21+
else:
22+
cap = cv2.VideoCapture(args.in_file)
23+
24+
frame_idx = 0
25+
def next_frame():
26+
global frame_idx
27+
28+
if frame_files is not None:
29+
if len(frame_files) <= frame_idx:
30+
return None
31+
frame = cv2.imread(frame_files[frame_idx])
32+
else:
33+
ret, frame = cap.read()
34+
35+
frame_idx += 1
36+
return frame
37+
38+
in_file = os.path.basename(args.in_file)
39+
40+
while True:
41+
img = next_frame()
42+
if img is None:
43+
break
44+
45+
bboxes = SSBUBoundingBoxUtil.fighters_chara_bbox(args.fighter_num)
46+
for fighter_idx in range(len(bboxes)):
47+
# if fighter_idx != 3:
48+
# continue
49+
bbox = bboxes[fighter_idx]
50+
chara = img[bbox[1]:bbox[1]+bbox[3], bbox[0]:bbox[0]+bbox[2]]
51+
52+
file = '%s-f%d-%d.png' % (in_file, fighter_idx, frame_idx, )
53+
path = os.path.join(args.out_dir, file)
54+
cv2.imwrite(path, chara)
55+
56+
print(frame_idx, fighter_idx)

get_stock_shots.py

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import cv2
2+
import argparse
3+
from PIL import Image
4+
import os
5+
import numpy as np
6+
import SSBUBoundingBoxUtil
7+
8+
parser = argparse.ArgumentParser()
9+
parser.add_argument('in_file', type=str)
10+
parser.add_argument('out_dir', type=str)
11+
parser.add_argument('fighter_num', type=int)
12+
args = parser.parse_args()
13+
14+
15+
os.makedirs(args.out_dir, exist_ok=True)
16+
17+
18+
frame_files = None
19+
cap = None
20+
if os.path.isdir(args.in_file):
21+
frame_files = [ os.path.join(args.in_file, file) for file in os.listdir(args.in_file) ]
22+
else:
23+
cap = cv2.VideoCapture(args.in_file)
24+
25+
frame_idx = 0
26+
def next_frame():
27+
global frame_idx
28+
29+
if frame_files is not None:
30+
if len(frame_files) <= frame_idx:
31+
return None
32+
frame = cv2.imread(frame_files[frame_idx])
33+
else:
34+
ret, frame = cap.read()
35+
36+
frame_idx += 1
37+
return frame
38+
39+
in_file = os.path.basename(args.in_file)
40+
41+
fighters_stock_bboxes = SSBUBoundingBoxUtil.fighters_stock_bboxes(args.fighter_num, stock_num=3)
42+
43+
while True:
44+
img = next_frame()
45+
if img is None:
46+
break
47+
48+
for fighter_idx, bboxes in enumerate(fighters_stock_bboxes):
49+
for idx in range(len(bboxes)):
50+
# if idx != 3:
51+
# continue
52+
bbox = bboxes[idx]
53+
chara = img[bbox[1]:bbox[1]+bbox[3], bbox[0]:bbox[0]+bbox[2]]
54+
55+
file = '%s-f%d-s%d-%d.png' % (in_file, fighter_idx, idx, frame_idx, )
56+
path = os.path.join(args.out_dir, file)
57+
cv2.imwrite(path, chara)
58+
59+
print(frame_idx, fighter_idx)

main_camera.py

+41-21
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,19 @@
1010
import threading
1111

1212
parser = argparse.ArgumentParser()
13-
parser.add_argument('outdir', type=str)
14-
parser.add_argument('-d', '--digit_dictionary', type=str, default='../digit_dictionary.json')
15-
parser.add_argument('-c', '--chara_dictionary', type=str, default='../chara_dictionary.json')
16-
parser.add_argument('-s', '--stock_dictionary', type=str, default='../stock_dictionary.json')
13+
parser.add_argument('-d', '--digit_dictionary', type=str, default='../digit_dictionary_v1.json')
14+
parser.add_argument('-c', '--chara_dictionary', type=str, default='../chara_dictionary_v3.json')
15+
parser.add_argument('-s', '--stock_dictionary', type=str, default='../stock_dictionary_v3.json')
1716
parser.add_argument('-f', '--fighter_num', type=int, default=2) # TODO: predict
18-
parser.add_argument('-p', '--capture_index', type=int, default=2)
17+
parser.add_argument('-p', '--capture_device', type=int, default=None)
18+
parser.add_argument('-i', '--video', type=str, default=None)
19+
parser.add_argument('--dump', action='store_true')
20+
parser.add_argument('-o', '--outdir', type=str, default='./')
21+
parser.add_argument('--sync', action='store_true')
1922
args = parser.parse_args()
2023

24+
assert (args.capture_device is not None) ^ (args.video is not None)
25+
2126
os.makedirs(args.outdir, exist_ok=True)
2227

2328

@@ -40,18 +45,26 @@
4045
analyzer = SSBUFrameAnalyzer(digit_classifier=digit_classifier, name_recognizer=name_recognizer, chara_classifier=chara_classifier, stock_classifier=stock_classifier)
4146

4247

43-
fps = 30
48+
if args.capture_device:
49+
fps = 30
50+
51+
cap = cv2.VideoCapture(args.capture_device)
52+
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
53+
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
54+
cap.set(cv2.CAP_PROP_FPS, fps)
55+
else:
56+
cap = cv2.VideoCapture(args.video)
4457

45-
cap = cv2.VideoCapture(args.capture_index)
46-
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
47-
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
48-
cap.set(cv2.CAP_PROP_FPS, fps)
58+
if args.dump:
59+
outfile = '%f.avi' % time.time()
60+
outpath = os.path.join(args.outdir, outfile)
4961

50-
outfile = '%f.avi' % time.time()
51-
outpath = os.path.join(args.outdir, outfile)
62+
fourcc = cv2.VideoWriter_fourcc(*'XVID')
63+
out = cv2.VideoWriter(outpath, fourcc, fps, (1280, 720))
5264

53-
fourcc = cv2.VideoWriter_fourcc(*'XVID')
54-
out = cv2.VideoWriter(outpath, fourcc, fps, (1280, 720))
65+
print('Dump mode: %s' % outpath)
66+
else:
67+
print('No Dump mode')
5568

5669
task = None
5770
def do_task():
@@ -64,26 +77,33 @@ def do_task():
6477

6578
print('-' * 40)
6679
print(ret)
67-
print('FPS: %f (%f s)' % (1/elapsed, elapsed, ))
80+
print('Task FPS: %f (%f s)' % (1/elapsed, elapsed, ))
6881

6982
task = None
7083

7184
while True:
85+
ts = time.time()
7286
ret, frame = cap.read()
7387

74-
out.write(frame)
75-
76-
# print(frame.shape)
77-
cv2.imshow('img', frame)
78-
7988
if task is None:
8089
task = threading.Thread(target=do_task)
8190
task.start()
91+
if args.sync:
92+
task.join()
93+
94+
if args.dump:
95+
out.write(frame)
96+
97+
# print(frame.shape)
98+
cv2.imshow('img', frame)
99+
elapsed = time.time() - ts
100+
print('Camera FPS: %f (%f s)' % (1/elapsed, elapsed, ))
82101

83102
c = cv2.waitKey(1)
84103
if c & 0xFF == ord('q'):
85104
break
86105

87106
cap.release()
88-
out.release()
107+
if args.dump:
108+
out.release()
89109
cv2.destroyAllWindows()

0 commit comments

Comments
 (0)