def set_piece_color(df, pieces, next): piece_id = FrameProcessing.map_frame_to_piece(df, next.current_frame, pieces) binary = binary = FrameProcessing.color_to_binary( next.current_frame, df['threshold']['piece_intensity']) if piece_id != -1 and not pieces[piece_id - 1].color_defined: piece = pieces[piece_id - 1] piece.color = FrameProcessing.average_color(next.current_frame, binary) # print(piece.id, piece.color) piece.color_defined = True return True else: return False
def process_video(piece_tracking=False): folder = '/home/alexandre/Downloads/' fileName = '210629' extension = '.mp4' player_name = '' session = SessionStats() pieces_stats = [] cap = cv2.VideoCapture(folder + fileName + extension) cap_width = cap.get(3) cap_height = cap.get(4) total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT) fourcc = cv2.VideoWriter_fourcc(*'mpeg') defaults = Reader.read_yaml() scale = defaults['frame']['scale'] frame_width = int(defaults['video']['width'] * scale) frame_height = int(defaults['video']['height'] * scale) timing = TimingStats(cap.get(cv2.CAP_PROP_FPS)) out = cv2.VideoWriter('/home/alexandre/Desktop/temp/' + fileName + '.avi', fourcc, timing.fps, (frame_width, frame_height)) playfield = Playfield(defaults['playfield'], scale) hold = None nexts = None current_piece = None current_piece_id = -1 current_piece_srs_rotation = 0 current_piece_column = 0 next_piece = None next_piece_id = -1 prev_hold_id = -1 prev_hold = None prev_frame = None prev_playfield = None frame = None frame_digits = init_frame_digits(defaults['timer'], scale) pieces = [] session.timer = [] timer_prev_digits = [] first_hold = False timer_initialized = False started = False digits_read = False pieces_read = False background_top = False training_complete = False recording = False ended = False prev_hold_frame = -1 entry_frame = -1 end_count = 0 prev_squares_on_top = 0 squares_on_top = 0 piece_lines_cleared = 0 map_frame_time = {} ignore_line_clear = 0 session.piece_count = -1 colors_defined = 0 timing.start_frame = total_frames timing.end_frame = total_frames timing.fastest_time = 13 timing.slowest_time_corrected = 50 timing.slowest_time = 120 timing.total_pieces = 100 camera = False #camera = True #timing.start_frame = 116 #timing.end_frame = 1475 #final_time = [0,3,1,7,5] # pts1 = np.float32([[113, 90], [1200, 80], [116, 700], [1204, 696]]) # pts2 = np.float32([[0, 0], [960, 0], [0, 540], [960, 540]]) # pts1 = np.float32([[53, 144], [1171, 125], [152, 567], [1242, 703]]) # pts2 = np.float32([[84, 143], [892, 99], [154, 439], [960, 540]]) replay_overlay = int(timing.fps * defaults['overlay']['replay_text']) numbers = [] ignore_squares = init_ignore_squares(defaults) ignore_squares_ingame = {} ignore_next = 0 ignore_hold = 0 frame_pieces_update = -1 frame_hold_update = -1 sq_candidates = [] board_updated = 0 last_playfield = None prev_candidates = [] board_id = copy.deepcopy(playfield) board_id.height = defaults['layout']['playfield']['num_rows'] board_id.board = np.zeros((board_id.height, board_id.width)) board_diff = np.zeros_like(playfield.board) while cap.isOpened() and session.frame_count < total_frames: ret, original_frame = cap.read() session.frame_count = int(cap.get(cv2.CAP_PROP_POS_FRAMES)) if camera: matrix = cv2.getPerspectiveTransform(pts1, pts2) frame = cv2.warpPerspective(original_frame, matrix, (960, 540)) else: frame = cv2.resize(original_frame, (frame_width, frame_height)) #original_frame = cv2.resize(original_frame, (frame_width, frame_height)) original_frame = frame set_current_frames(defaults, frame, playfield, hold, nexts, frame_digits) next_changed = nexts_changed(defaults['threshold'], nexts) entry_delay = np.round(defaults['delay']['entry'] * timing.fps) if camera and not started and session.frame_count == timing.start_frame: started = True digits_read = True playfield.set_background_bottom(frame, defaults['overlay']['max_row']) hold = init_hold(defaults['hold'], scale) nexts = init_nexts(defaults, scale) hold.set_background(frame) pieces = init_pieces(defaults) for i in range(len(nexts)): nexts[i].set_background(frame) nexts[i].set_current_frame(frame) if set_piece_color(defaults, pieces, nexts[i]): print('Color set') colors_defined += 1 # cap.set(cv2.CAP_PROP_POS_FRAMES,timing.start_frame + timing.fps) # ret, frame = cap.read() # frame = cv2.resize(frame, (frame_width, frame_height)) # session.frame_count = cap.get(cv2.CAP_PROP_POS_FRAMES) # print(" Background top set", session.frame_count) # background_top = True # playfield.set_background_top(frame, defaults['overlay']['max_row']) # cap.set(cv2.CAP_PROP_POS_FRAMES,0) # training_complete = True if not camera and not timer_initialized and timer_is_zero( frame_digits, defaults['threshold']): print(' Timer initialized') timer_initialized = True playfield.set_background_bottom(frame, defaults['overlay']['max_row']) if (not started and timer_initialized and not timer_digits_match( frame_digits, defaults['threshold'])) and not pieces_read: timing.start_frame = session.frame_count - 1 started = True hold = init_hold(defaults['hold'], scale) nexts = init_nexts(defaults, scale) hold.set_background(frame) pieces = init_pieces(defaults) for i in range(len(nexts)): nexts[i].set_background(frame) nexts[i].set_current_frame(frame) if set_piece_color(defaults, pieces, nexts[i]): print('Color set') colors_defined += 1 if not background_top and next_changed and digits_read: cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count - 2) ret, frame = cap.read() frame = cv2.resize(frame, (frame_width, frame_height)) session.frame_count = cap.get(cv2.CAP_PROP_POS_FRAMES) print(" Background top set", session.frame_count) background_top = True playfield.set_background_top(frame, defaults['overlay']['max_row']) if not pieces_read and next_changed: id = len(nexts) - 1 if set_piece_color(defaults, pieces, nexts[id]): colors_defined += 1 print('Colors defined', colors_defined) if colors_defined == defaults['sprint']['num_pieces']: print('All colors defined') pieces_read = True if training_complete and session.frame_count >= timing.start_frame and not ended: if piece_tracking: if session.frame_count == timing.start_frame: next_piece = nexts[0].current_frame next_piece_id = FrameProcessing.map_frame_to_piece( defaults, next_piece, pieces) print('Setting next piece id', next_piece_id) if hold_changed(defaults['threshold'], hold, session): if prev_hold is not None: current_piece = prev_hold print('Current id was', current_piece_id, 'hold id was', prev_hold_id) current_piece_id, prev_hold_id = prev_hold_id, current_piece_id current_piece_name = defaults['pieces']['names'][ current_piece_id] current_piece_column = defaults['pieces'][ current_piece_name][ 'spawn_column'] #change current_piece update into a function later print('Current id is now', current_piece_id, 'hold id is', prev_hold_id) else: first_hold = True prev_hold_id = current_piece_id print('First Hold. Hold id is', prev_hold_id) if next_changed and not first_hold: current_piece = next_piece current_piece_id = next_piece_id current_piece_name = defaults['pieces']['names'][ current_piece_id] if session.total_lines == 40: timing.end_frame = session.frame_count - defaults['timer'][ 'end_count'] ended = True timer_prev_digits = session.timer session.timer = match_digits(frame_digits, numbers, defaults['threshold']) map_frame_time[session.frame_count] = session.timer prev_squares_on_top = squares_on_top squares_on_top = piece_on_top(defaults, playfield, ignore_squares) temp_playfield = copy.deepcopy(playfield) update_playfield(defaults, temp_playfield, pieces, []) #print(temp_playfield.board) else: if session.frame_count == timing.start_frame: next_piece = nexts[0].current_frame next_piece_id = FrameProcessing.map_frame_to_piece( defaults, next_piece, pieces) print('Setting next piece id', next_piece_id) timer_prev_digits = session.timer if camera: session.timer = Time.frames_to_time( session.frame_count - timing.start_frame, timing.fps) else: session.timer = match_digits(frame_digits, numbers, defaults['threshold']) map_frame_time[session.frame_count] = session.timer prev_squares_on_top = squares_on_top squares_on_top = piece_on_top(defaults, playfield, ignore_squares) #print('Squares on top:', prev_squares_on_top, squares_on_top) #if prev_squares_on_top > 0 and squares_on_top == 0: if ignore_line_clear > 0: ignore_line_clear -= 1 else: temp_lines = line_cleared(defaults['threshold'], playfield) if len(temp_lines) > 0: piece_lines_cleared = len(temp_lines) ignore_line_clear = 20 playfield.clear_lines(temp_lines) #board_id.clear_lines(temp_lines) board_updated = session.piece_count + 1 if len(temp_lines) == 4: min_line = min(temp_lines) board_diff = [(6, 0), (6, 1), (6, 2), (6, 3)] board_id.update_with(board_diff, session.piece_count + 1, session.total_lines) expiry = int(defaults['overlay']['tetris_animation'] * timing.fps + session.frame_count) ignore_squares_ingame = update_ignore_tetris( defaults['overlay'], ignore_squares_ingame, playfield.width, playfield.height, min_line, expiry) if ignore_next > 0: ignore_next -= 1 if ignore_hold > 0: ignore_hold -= 1 if next_changed: entry_delay = np.round(defaults['delay']['entry'] * timing.fps) if ignore_next == 0: ignore_next = entry_delay if not first_hold: #locked piece if session.piece_count >= 0: cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count - entry_delay - 1) ret, prev_frame = cap.read() if camera: matrix = cv2.getPerspectiveTransform( pts1, pts2) prev_frame = cv2.warpPerspective( prev_frame, matrix, (960, 540)) else: prev_frame = cv2.resize( prev_frame, (frame_width, frame_height)) playfield.set_current_frame(prev_frame) cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count) temp_playfield = copy.deepcopy(playfield) update_playfield(defaults, temp_playfield, pieces, ignore_squares_ingame) ignore_squares_ingame = remove_from_ignore( ignore_squares_ingame, session.frame_count) if prev_playfield is not None: temp_playfield.fill_incorrect_squares( prev_playfield) prev_playfield = copy.deepcopy(playfield) print('Session', session.piece_count, board_updated) print(temp_playfield.board) print('Prev', session.piece_count, board_updated) print(prev_playfield.board) if piece_lines_cleared == 0: board_diff = temp_playfield.board_diff( prev_playfield, defaults['sprint']['num_pieces'], ignore_squares_ingame) if len(board_diff) != 4: print('Missing square here!', len(board_diff)) print(prev_playfield.board) name = defaults['pieces']['names'][ current_piece_id] print(temp_playfield.board) if len(prev_candidates) == 0: candidates = temp_playfield.reconstruct_board( defaults['pieces'], prev_playfield, defaults['pieces'][name]) else: candidates = temp_playfield.reconstruct_board_from_candidates( defaults['pieces'], prev_playfield, prev_candidates, defaults['pieces'][name]) #Manually fix missing pieces #print('Count', session.piece_count) #if session.piece_count == 80: # candidates = [[(3, 7, 0)]] #if session.frame_count == 954: # candidates = [[(4, 6, 3)]] if len(candidates) == 1: for c in candidates[0]: print('cand', c) board_diff = update_board( defaults, c, prev_playfield) piece = defaults['pieces'][ 'names'][c[0]] print(piece) piece_state = np.array( defaults['pieces'][piece] ['rotations'][c[2]]) prev_playfield.hard_drop( piece_state, c[1], c[0]) board_updated += 1 playfield.update_with( board_diff, current_piece_id, 0) board_id.update_with( board_diff, board_updated, session.total_lines) prev_candidates = [] else: print(len(candidates), ' Found', candidates) board_diff = [] prev_candidates = candidates last_playfield = prev_playfield else: board_updated = session.piece_count + 1 playfield.update_with( board_diff, current_piece_id, 0) board_id.update_with( board_diff, board_updated, session.total_lines) #print(board_id.board) playfield.remove_effect(defaults) playfield.set_current_frame(frame) #prev_frame = frame session.piece_count += 1 if session.piece_count > 0: print('Next changed', session.frame_count, session.piece_count) hold_frame = -1 if prev_hold_frame >= entry_frame: hold_frame = prev_hold_frame session.holds += 1 time_diff = Time.frame_to_time_diff( hold_frame, entry_frame, map_frame_time, defaults['timer']) session.hold_time += time_diff if piece_lines_cleared > 0: session.update_lines( defaults['delay'], piece_lines_cleared) pc = False if session.perfect_clear(): pc = True session.perfect_clears += 1 piece_stat = PieceStats( session.piece_count, current_piece_id, entry_frame, session.frame_count, hold_frame, piece_lines_cleared, pc, current_piece, hold.current_frame, board_diff) print('Creating ', piece_stat.count, piece_stat.id) pieces_stats.append(piece_stat) entry_frame = session.frame_count else: first_hold = False frame_pieces_update = session.frame_count current_piece = next_piece current_piece_id = next_piece_id print('Current piece is now', current_piece_id) piece_lines_cleared = 0 if camera: frame_pieces_update += entry_delay if session.frame_count == frame_pieces_update: next_piece = nexts[0].current_frame next_piece_id = FrameProcessing.map_frame_to_piece( defaults, next_piece, pieces) print('Next piece is ', next_piece_id) if hold_changed(defaults['threshold'], hold, session): if ignore_hold == 0: ignore_hold = entry_delay print('Hold changed', session.frame_count) if prev_hold is not None: current_piece = prev_hold print('Current id was', current_piece_id, 'hold id was', prev_hold_id) current_piece_id, prev_hold_id = prev_hold_id, current_piece_id print('Current id is now', current_piece_id, 'hold id is', prev_hold_id) else: first_hold = True prev_hold_id = current_piece_id print('First Hold. Hold id is', prev_hold_id) prev_hold_frame = session.frame_count frame_hold_update = session.frame_count if camera: frame_hold_update += entry_delay if session.frame_count == frame_hold_update: print('Updating hold frame', session.frame_count) prev_hold = hold.current_frame if session.total_lines == 40: timing.end_frame = session.frame_count - defaults['timer'][ 'end_count'] ended = True # if np.array_equal(timer_prev_digits, session.timer) or session.frame_count >= timing.end_frame: # end_count += 1 # if camera: # session.timer = final_time # if end_count >= defaults['timer']['end_count']: # timing.end_frame = session.frame_count - defaults['timer']['end_count'] # print(" Final time:", session.timer, timing.end_frame) # ended = True # else: # end_count = 0 if session.frame_count > timing.start_frame and session.frame_count < timing.start_frame + timing.fps and not digits_read: frame_count_diff = session.frame_count - timing.start_frame div = round(timing.fps) // 10 remainder = div // 2 if frame_count_diff % div == remainder: print("Digits read", len(numbers)) numbers = store_number( numbers, frame_digits[defaults['timer']['decisecond']], defaults['threshold']['digit']) if len(numbers) == defaults['timer']['numbers']: #frame_count = advance_time(frame_count,fps,defaults['timer']['time_advance']) digits_read = True #cap.set(cv2.CAP_PROP_POS_FRAMES,frame_count) if not training_complete and background_top and digits_read and pieces_read: cap.set(cv2.CAP_PROP_POS_FRAMES, 0) training_complete = True back_diff = Draw.draw_background_diff(playfield, hold, frame) #if session.frame_count > 1: # prev_diff = Draw.draw_previous_frame_diff(playfield, hold, frame, nexts) #current = Draw.draw_current_frame(defaults, playfield, frame_digits, current_piece, next_piece, frame) last_piece_time = [] if session.piece_count > 0: entry_delay = int(defaults['delay']['entry'] * timing.fps) last_piece_frame = pieces_stats[session.piece_count - 1].end_frame - entry_delay last_piece_time = map_frame_time[last_piece_frame] if session.frame_count < timing.start_frame: session.timer = [0, 0, 0, 0, 0] elif training_complete and session.frame_count < timing.end_frame + 3 * timing.fps: print(session.frame_count, timing.fps, timing.end_frame + 2 * timing.fps) original_frame = Draw.draw_time_stats(defaults, original_frame, frame_width, frame_height, session, last_piece_time, board_id, pieces_stats, map_frame_time, timing) original_frame = Draw.draw_pieces_stats(defaults, original_frame, pieces_stats, frame_width, frame_height, map_frame_time, timing, session) original_frame = Draw.draw_lines_stats(defaults, original_frame, frame_width, frame_height, timing, session, last_piece_time) original_frame = Draw.draw_playfield(defaults, original_frame, frame_width, frame_height, board_id, pieces_stats, timing, map_frame_time) #original_frame = Draw.draw_player_info(defaults['layout']['player'], original_frame, frame_width, frame_height, player_name) #original_frame = Draw.draw_histogram(defaults, original_frame, pieces_stats, frame_width, frame_height, map_frame_time, timing, session) print("Frame", session.frame_count, "/", total_frames, session.timer) if recording: out.write(original_frame) if training_complete: recording = True cv2.imshow('frame', original_frame) #if prev_frame is not None: # cv2.imshow('timer', prev_frame) #cv2.imshow('back_diff',back_diff) #if session.frame_count > 1: # cv2.imshow('prev_diff',prev_diff) key = cv2.waitKey(1) #while key not in [ord('q'), ord('k'),ord('l')]: # key = cv2.waitKey(0) if key == ord('l'): session.frame_count -= 5 if session.frame_count < 0: session.frame_count = 0 cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count) elif key == ord('q'): break cap.release() out.release() cv2.destroyAllWindows()
def process_video(video_name, total_pieces): session = SessionStats() pieces_stats = [] parent_path = Path(os.getcwd()).parent.absolute() cap = cv2.VideoCapture(os.path.join(parent_path, 'input', video_name)) cap_width = cap.get(3) cap_height = cap.get(4) total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT) fourcc = cv2.VideoWriter_fourcc(*'mpeg') defaults = Reader.read_yaml() scale = defaults['frame']['scale'] frame_width = int(defaults['video']['width'] * scale) frame_height = int(defaults['video']['height'] * scale) timing = TimingStats(cap.get(cv2.CAP_PROP_FPS)) print(os.path.join(os.getcwd(), video_name)) out = cv2.VideoWriter(os.path.join(parent_path, 'output', video_name), fourcc, timing.fps, (frame_width, frame_height)) playfield = Playfield(defaults['playfield'], scale) hold = None nexts = None current_piece = None current_piece_id = -1 next_piece = None next_piece_id = -1 prev_hold_id = -1 prev_hold = None prev_frame = None prev_playfield = None frame = None frame_digits = init_frame_digits(defaults['timer'], scale) pieces = [] session.timer = [] timer_prev_digits = [] first_hold = False timer_initialized = False started = False digits_read = False pieces_read = False background_top = False training_complete = False recording = False ended = False prev_hold_frame = -1 entry_frame = -1 end_count = 0 prev_squares_on_top = 0 squares_on_top = 0 piece_lines_cleared = 0 map_frame_time = {} ignore_line_clear = 0 session.piece_count = -1 colors_defined = 0 timing.start_frame = total_frames timing.end_frame = total_frames timing.fastest_time = 13 timing.slowest_time_corrected = 50 timing.slowest_time = 120 timing.total_pieces = total_pieces camera = False replay_overlay = int(timing.fps * defaults['overlay']['replay_text']) numbers = [] ignore_squares = init_ignore_squares(defaults) ignore_squares_ingame = {} ignore_next = 0 ignore_hold = 0 frame_pieces_update = -1 frame_hold_update = -1 sq_candidates = [] board_updated = 0 last_playfield = None prev_candidates = [] board_id = copy.deepcopy(playfield) board_id.height = defaults['layout']['playfield']['num_rows'] board_id.board = np.zeros((board_id.height, board_id.width)) board_diff = np.zeros_like(playfield.board) while cap.isOpened() and session.frame_count < total_frames: ret, original_frame = cap.read() session.frame_count = int(cap.get(cv2.CAP_PROP_POS_FRAMES)) if camera: matrix = cv2.getPerspectiveTransform(pts1, pts2) frame = cv2.warpPerspective(original_frame, matrix, (960, 540)) else: frame = cv2.resize(original_frame, (frame_width, frame_height)) #original_frame = cv2.resize(original_frame, (frame_width, frame_height)) original_frame = frame set_current_frames(defaults, frame, playfield, hold, nexts, frame_digits) next_changed = nexts_changed(defaults['threshold'], nexts) if camera and not started and session.frame_count == timing.start_frame: started = True digits_read = True playfield.set_background_bottom(frame, defaults['overlay']['max_row']) hold = init_hold(defaults['hold'], scale) nexts = init_nexts(defaults, scale) hold.set_background(frame) pieces = init_pieces(defaults) for i in range(len(nexts)): nexts[i].set_background(frame) nexts[i].set_current_frame(frame) if set_piece_color(defaults, pieces, nexts[i]): print('Color set') colors_defined += 1 if not camera and not timer_initialized and timer_is_zero( frame_digits, defaults['threshold']): print(' Timer initialized') timer_initialized = True playfield.set_background_bottom(frame, defaults['overlay']['max_row']) if (not started and timer_initialized and not timer_digits_match( frame_digits, defaults['threshold'])) and not pieces_read: timing.start_frame = session.frame_count - 1 started = True hold = init_hold(defaults['hold'], scale) nexts = init_nexts(defaults, scale) hold.set_background(frame) pieces = init_pieces(defaults) for i in range(len(nexts)): nexts[i].set_background(frame) nexts[i].set_current_frame(frame) if set_piece_color(defaults, pieces, nexts[i]): print('Color set') colors_defined += 1 if not background_top and next_changed and digits_read: cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count - 2) ret, frame = cap.read() frame = cv2.resize(frame, (frame_width, frame_height)) session.frame_count = cap.get(cv2.CAP_PROP_POS_FRAMES) print(" Background top set", session.frame_count) background_top = True playfield.set_background_top(frame, defaults['overlay']['max_row']) if not pieces_read and next_changed: id = len(nexts) - 1 if set_piece_color(defaults, pieces, nexts[id]): colors_defined += 1 print('Colors defined', colors_defined) if colors_defined == defaults['sprint']['num_pieces']: print('All colors defined') pieces_read = True if training_complete and session.frame_count >= timing.start_frame and not ended: if session.frame_count == timing.start_frame: next_piece = nexts[0].current_frame next_piece_id = FrameProcessing.map_frame_to_piece( defaults, next_piece, pieces) print('Setting next piece id', next_piece_id) timer_prev_digits = session.timer if camera: session.timer = Time.frames_to_time( session.frame_count - timing.start_frame, timing.fps) else: session.timer = match_digits(frame_digits, numbers, defaults['threshold']) map_frame_time[session.frame_count] = session.timer prev_squares_on_top = squares_on_top squares_on_top = piece_on_top(defaults, playfield, ignore_squares) if ignore_line_clear > 0: ignore_line_clear -= 1 else: temp_lines = line_cleared(defaults['threshold'], playfield) if len(temp_lines) > 0: piece_lines_cleared = len(temp_lines) ignore_line_clear = 20 playfield.clear_lines(temp_lines) #board_id.clear_lines(temp_lines) board_updated = session.piece_count + 1 if len(temp_lines) == 4: min_line = min(temp_lines) board_diff = [(6, 0), (6, 1), (6, 2), (6, 3)] board_id.update_with(board_diff, session.piece_count + 1, session.total_lines) expiry = int(defaults['overlay']['tetris_animation'] * timing.fps + session.frame_count) ignore_squares_ingame = update_ignore_tetris( defaults['overlay'], ignore_squares_ingame, playfield.width, playfield.height, min_line, expiry) if ignore_next > 0: ignore_next -= 1 if ignore_hold > 0: ignore_hold -= 1 if next_changed: entry_delay = np.round(defaults['delay']['entry'] * timing.fps) if ignore_next == 0: ignore_next = entry_delay if not first_hold: #locked piece if session.piece_count >= 0: cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count - entry_delay - 1) ret, prev_frame = cap.read() if camera: matrix = cv2.getPerspectiveTransform( pts1, pts2) prev_frame = cv2.warpPerspective( prev_frame, matrix, (960, 540)) else: prev_frame = cv2.resize( prev_frame, (frame_width, frame_height)) playfield.set_current_frame(prev_frame) cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count) temp_playfield = copy.deepcopy(playfield) update_playfield(defaults, temp_playfield, pieces, ignore_squares_ingame) ignore_squares_ingame = remove_from_ignore( ignore_squares_ingame, session.frame_count) if prev_playfield is not None: temp_playfield.fill_incorrect_squares( prev_playfield) prev_playfield = copy.deepcopy(playfield) print('Session', session.piece_count, board_updated) print(temp_playfield.board) print('Prev', session.piece_count, board_updated) print(prev_playfield.board) if piece_lines_cleared == 0: board_diff = temp_playfield.board_diff( prev_playfield, defaults['sprint']['num_pieces'], ignore_squares_ingame) if len(board_diff) != 4: print('Missing square here!', len(board_diff)) print(prev_playfield.board) name = defaults['pieces']['names'][ current_piece_id] print(temp_playfield.board) if len(prev_candidates) == 0: candidates = temp_playfield.reconstruct_board( defaults['pieces'], prev_playfield, defaults['pieces'][name]) else: candidates = temp_playfield.reconstruct_board_from_candidates( defaults['pieces'], prev_playfield, prev_candidates, defaults['pieces'][name]) if len(candidates) == 1: for c in candidates[0]: print('cand', c) board_diff = update_board( defaults, c, prev_playfield) piece = defaults['pieces'][ 'names'][c[0]] print(piece) piece_state = np.array( defaults['pieces'][piece] ['rotations'][c[2]]) prev_playfield.hard_drop( piece_state, c[1], c[0]) board_updated += 1 playfield.update_with( board_diff, current_piece_id, 0) board_id.update_with( board_diff, board_updated, session.total_lines) prev_candidates = [] else: print(len(candidates), ' Found', candidates) board_diff = [] prev_candidates = candidates last_playfield = prev_playfield else: board_updated = session.piece_count + 1 playfield.update_with( board_diff, current_piece_id, 0) board_id.update_with( board_diff, board_updated, session.total_lines) playfield.remove_effect(defaults) playfield.set_current_frame(frame) session.piece_count += 1 if session.piece_count > 0: print('Next changed', session.frame_count, session.piece_count) hold_frame = -1 if prev_hold_frame >= entry_frame: hold_frame = prev_hold_frame session.holds += 1 time_diff = Time.frame_to_time_diff( hold_frame, entry_frame, map_frame_time, defaults['timer']) session.hold_time += time_diff if piece_lines_cleared > 0: session.update_lines(defaults['delay'], piece_lines_cleared) pc = False if session.perfect_clear(): pc = True session.perfect_clears += 1 piece_stat = PieceStats( session.piece_count, current_piece_id, entry_frame, session.frame_count, hold_frame, piece_lines_cleared, pc, current_piece, hold.current_frame, board_diff) print('Creating ', piece_stat.count, piece_stat.id) pieces_stats.append(piece_stat) entry_frame = session.frame_count else: first_hold = False frame_pieces_update = session.frame_count current_piece = next_piece current_piece_id = next_piece_id print('Current piece is now', current_piece_id) piece_lines_cleared = 0 if camera: frame_pieces_update += entry_delay if session.frame_count == frame_pieces_update: next_piece = nexts[0].current_frame next_piece_id = FrameProcessing.map_frame_to_piece( defaults, next_piece, pieces) print('Next piece is ', next_piece_id) if hold_changed(defaults['threshold'], hold, session): if ignore_hold == 0: ignore_hold = entry_delay print('Hold changed', session.frame_count) if prev_hold is not None: current_piece = prev_hold print('Current id was', current_piece_id, 'hold id was', prev_hold_id) current_piece_id, prev_hold_id = prev_hold_id, current_piece_id print('Current id is now', current_piece_id, 'hold id is', prev_hold_id) else: first_hold = True prev_hold_id = current_piece_id print('First Hold. Hold id is', prev_hold_id) prev_hold_frame = session.frame_count frame_hold_update = session.frame_count if camera: frame_hold_update += entry_delay if session.frame_count == frame_hold_update: print('Updating hold frame', session.frame_count) prev_hold = hold.current_frame if session.total_lines == 40: timing.end_frame = session.frame_count - defaults['timer'][ 'end_count'] ended = True if session.frame_count > timing.start_frame and session.frame_count < timing.start_frame + timing.fps and not digits_read: frame_count_diff = session.frame_count - timing.start_frame div = round(timing.fps) // 10 remainder = div // 2 if frame_count_diff % div == remainder: print("Digits read", len(numbers)) numbers = store_number( numbers, frame_digits[defaults['timer']['decisecond']], defaults['threshold']['digit']) if len(numbers) == defaults['timer']['numbers']: digits_read = True if not training_complete and background_top and digits_read and pieces_read: cap.set(cv2.CAP_PROP_POS_FRAMES, 0) training_complete = True back_diff = Draw.draw_background_diff(playfield, hold, frame) last_piece_time = [] if session.piece_count > 0: entry_delay = int(defaults['delay']['entry'] * timing.fps) last_piece_frame = pieces_stats[session.piece_count - 1].end_frame - entry_delay last_piece_time = map_frame_time[last_piece_frame] if session.frame_count < timing.start_frame: session.timer = [0, 0, 0, 0, 0] elif training_complete and session.frame_count < timing.end_frame + 3 * timing.fps: print(session.frame_count, timing.fps, timing.end_frame + 2 * timing.fps) original_frame = Draw.draw_time_stats(defaults, original_frame, frame_width, frame_height, session, last_piece_time, board_id, pieces_stats, map_frame_time, timing) original_frame = Draw.draw_pieces_stats(defaults, original_frame, pieces_stats, frame_width, frame_height, map_frame_time, timing, session) original_frame = Draw.draw_lines_stats(defaults, original_frame, frame_width, frame_height, timing, session, last_piece_time) original_frame = Draw.draw_playfield(defaults, original_frame, frame_width, frame_height, board_id, pieces_stats, timing, map_frame_time) print("Frame", session.frame_count, "/", total_frames, session.timer) if recording: out.write(original_frame) if training_complete: recording = True cv2.imshow('frame', original_frame) key = cv2.waitKey(1) #while key not in [ord('q'), ord('k'),ord('l')]: # key = cv2.waitKey(0) if key == ord('l'): session.frame_count -= 5 if session.frame_count < 0: session.frame_count = 0 cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count) elif key == ord('q'): break cap.release() out.release() cv2.destroyAllWindows()