This repository has been archived by the owner on Oct 29, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
/
get_new_ub.py
329 lines (233 loc) · 8.13 KB
/
get_new_ub.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# -*- coding: utf-8 -*-
import os
from pytube import YouTube
import cv2
import re
import sys
import shutil
import time as tm
from collections import deque
import mask_maker.make_model
NO_ERROR = 0
ERROR_BAD_URL = 1
ERROR_TOO_LONG = 2
ERROR_NOT_SUPPORTED = 3
ERROR_CANT_GET_MOVIE = 4
FRAME_COLS = 1280
FRAME_ROWS = 720
UB_ROI = (520, 100, 780, 130)
BACKSPACE_KEY = 8
ENTER_KEY = 13
ESC_KEY = 27
stream_dir = "movie/"
if not os.path.exists(stream_dir):
os.mkdir(stream_dir)
def main():
url_result, movie_path = get_youtube_movie()
check_youtube_movie(url_result)
analyze_result, master_frame = analyze_movie(movie_path)
if analyze_result is not True:
print("対象フレームが見つかりませんでした。終了します")
return -1
character_name = get_character_name()
save_learning_data(character_name, master_frame)
mask_maker.make_model.main()
print("画像の保存が完了しました。終了します")
return 0
def get_youtube_movie():
"""get youtube movie from user input
check user input url and check movie error
Args:
Returns:
int: url error type
str: movie path form user input url
"""
print("\nYouTube URL を入力して下さい")
input_url = input(">> ")
work_id = re.findall(".*watch(.{14})", input_url)
if not work_id:
work_id = re.findall(".youtu.be/(.{11})", input_url)
if not work_id:
return ERROR_BAD_URL, None
work_id[0] = "?v=" + work_id[0]
youtube_url = "https://www.youtube.com/watch" + work_id[0]
try:
yt = YouTube(youtube_url)
except:
return ERROR_CANT_GET_MOVIE, None
movie_length = yt.length
if int(movie_length) > 480:
return ERROR_TOO_LONG, None
stream = yt.streams.get_by_itag("22")
if stream is None:
return ERROR_NOT_SUPPORTED, None
movie_name = tm.time()
movie_path = stream.download(stream_dir, str(movie_name))
return NO_ERROR, movie_path
def check_youtube_movie(url_result):
"""check youtube movie from user input
if movie has error, exit program
Args:
url_result (str): movie error type
Returns:
"""
if url_result is ERROR_BAD_URL:
print("\nURLはhttps://www.youtube.com/watch?v=...の形式でお願いします")
sys.exit()
elif url_result is ERROR_TOO_LONG:
print("\n動画時間が長すぎるため、解析に対応しておりません")
sys.exit()
elif url_result is ERROR_NOT_SUPPORTED:
print("\n非対応の動画です。「720p 1280x720」の一部の動画に対応しております")
sys.exit()
elif url_result is ERROR_CANT_GET_MOVIE:
print("\n動画の取得に失敗しました。もう一度入力をお願いします")
sys.exit()
return
def analyze_movie(movie_path):
"""analyze movie for user select ub Mat
Args:
movie_path (str): movie path form user input url
Returns:
Bool: analyze result
Mat: user select image
"""
video = cv2.VideoCapture(movie_path)
frame_que = deque([], 10)
frame_count = int(video.get(7)) # フレーム数を取得
frame_rate = int(video.get(5)) # フレームレート(1フレームの時間単位はミリ秒)の取得
frame_width = int(video.get(3)) # フレームの幅
frame_height = int(video.get(4)) # フレームの高さ
if frame_width != int(FRAME_COLS) or frame_height != int(FRAME_ROWS):
video.release()
os.remove(movie_path)
return False, None
while True:
print("\n解析開始時刻(秒)を入力して下さい")
input_sec = input(">> ")
skip_frame = int(int(input_sec) * frame_rate)
if skip_frame > frame_count:
over_time = (skip_frame - frame_count) / frame_rate
print("動画時間を超えています 超過 : " + str(over_time) + " 秒)")
else:
break
print("\n操作方法")
print("BackSpace : 前のフレーム / Enter : 次のフレーム / Esc : 確定\n")
for i in range(frame_count): # 動画の秒数を取得し、回す
ret = video.grab()
if ret is False:
break
if i > skip_frame:
ret, work_frame = video.read()
if ret is False:
break
work_frame = edit_frame(work_frame)
frame_que.appendleft(work_frame)
check_result, master_frame = image_check(frame_que)
if check_result is True:
video.release()
os.remove(movie_path)
return True, master_frame
video.release()
os.remove(movie_path)
return False, None
def edit_frame(frame):
"""edit movie frame to ub name ROI
Args:
frame (str): capture frame
Returns:
Mat: edited image as ub name
"""
work_frame = frame
work_frame = work_frame[UB_ROI[1]:UB_ROI[3], UB_ROI[0]:UB_ROI[2]]
return work_frame
def image_check(frame_que):
"""check movie for found ub master frame
check frame que from [0] to last (Max 10 frame)
user able to search frame with keyboard
BackSpace: show previous frame
Enter: show following frame, if this key push with latest frame, then read next frame
Esc: select master frame
Args:
frame_que (deque): ub name que
Returns:
BOOL: image found (True) or not found (False)
Mat: master_frame
"""
frame_num = len(frame_que)
frame_max = frame_num - 1
que_index = 0
while True:
cv2.namedWindow('window')
cv2.imshow('window', frame_que[que_index])
key = cv2.waitKey(0) & 0xFF
if key == BACKSPACE_KEY:
if que_index < frame_max:
# check continue to previous frame
que_index += 1
cv2.destroyAllWindows()
elif key == ESC_KEY:
# check finish confirm
print("この画像で確定しますか?")
print("BackSpace : 戻る / Enter : 確定\n")
while True:
confirm_key = cv2.waitKey(0) & 0xFF
if confirm_key == BACKSPACE_KEY:
# check continue
cv2.destroyAllWindows()
break
elif confirm_key == ENTER_KEY:
# check finish with find master frame
print("画像を確定しました\n")
return True, frame_que[que_index]
elif key == ENTER_KEY:
if que_index <= 0:
# check finish with all frame has checked
cv2.destroyAllWindows()
break
else:
# check continue to following frame
que_index -= 1
cv2.destroyAllWindows()
return False, None
def get_character_name():
"""get character name
Args:
Returns:
str: character_name
"""
while True:
print("キャラクター名を入力して下さい")
character_name = input(">> ")
print("\n"+character_name + " でよろしいでしょうか?")
print("BackSpace : 戻る / Enter : 確定\n")
while True:
key = cv2.waitKey(0) & 0xFF
if key == BACKSPACE_KEY:
break
elif key == ENTER_KEY:
cv2.destroyAllWindows()
print("名前を確定しました\n")
return character_name
def save_learning_data(character_name, master_frame):
"""save learning data as image
Args:
character_name (str): image name
master_frame (mat): master_frame
Returns:
"""
learning_dir = "learning_data/"
if not os.path.exists(learning_dir):
os.mkdir(learning_dir)
image_dir = learning_dir + character_name + "/"
if not os.path.exists(image_dir):
os.mkdir(image_dir)
tmp_dir = learning_dir + "tmp/"
if not os.path.exists(tmp_dir):
os.mkdir(tmp_dir)
tmp_image_dir = tmp_dir + "1" + ".png"
cv2.imwrite(tmp_image_dir, master_frame)
shutil.move(tmp_image_dir, image_dir)
return
if __name__ == "__main__":
main()