Now use a sky pixel and a dashboard pixel to determine time-of-day

Can now also identify the score screen

Colours and pixel localtions have been updated for this years stream in
720p but changing to 1080p is a trivial change
pull/471/head
Christopher Usher 2 weeks ago committed by Mike Lang
parent 2fcbff3b44
commit b792b1b555

@ -295,26 +295,51 @@ def compare_colors(color_a, color_b):
def recognize_time_of_day(frame): def recognize_time_of_day(frame):
"""Returns time of day, score, all scores.""" """Determine time-of-day from a sky pixel and a dashboard pixel
COLORS = {
"day": (89, 236, 239), Uses the colour of a pixel in the sky and of a pixel on the dashboard to determine time-of-day
"dusk": (199, 162, 205), or whether the game is on the score screen."""
"night": (1, 1, 1), sky_colours = {
"dawn": (51, 59, 142), 'score': (119, 119, 119),
'day': (82, 218, 217),
'dusk': (225, 152, 184), # estimated from previous years
'night': (0, 0, 0), # estimated from previous years
'dawn': (56, 53, 125), # estimated from previous years
} }
sample = frame.getpixel((177, 255)) dash_colours = {
scores = [ 'score': (181, 181, 150),
(tod, compare_colors(sample, color)) 'day': (147, 0, 2),
for tod, color in COLORS.items() 'dusk': (118, 0, 0), # estimated from previous years
] 'night': (68, 0, 0), # estimated from previous years
best, score = max(scores, key=lambda t: t[1]) 'dawn': (118, 0, 0), # estimated from previous years
return best, score, scores }
threshold = 20 # use stronger constraint once we have dusk, night and dawn footage
# these are for 720p; will need to multiple by 3/2 for 1080p
sky_pixel = frame.getpixel((1076, 128))
dash_pixel = frame.getpixel((630, 576))
MAX_DIST = 6**0.5 * 255
sky_distances = []
dash_distances = []
matches = [(None, MAX_DIST)]
for time in sky_colours:
sky_distance = sum((a - b)**2 for a, b in zip(sky_pixel, sky_colours[time]))**0.5
sky_distances.append(sky_distance)
dash_distance = sum((a - b)**2 for a, b in zip(dash_pixel, dash_colours[time]))**0.5
dash_distances.append(dash_distance)
if sky_distance < threshold and dash_distance < threshold:
matches.append((time, (sky_distance**2 + dash_distance**2)**0.5))
best, distance = min(matches, key=lambda m: m[1])
return best, distance
def extract_segment(prototypes, segment): def extract_segment(prototypes, segment):
ODO_SCORE_THRESHOLD = 0.01 ODO_SCORE_THRESHOLD = 0.01
CLOCK_SCORE_THRESHOLD = 0.01 CLOCK_SCORE_THRESHOLD = 0.01
TOD_SCORE_THRESHOLD = 0.9
frame_data = b"".join(extract_frame([segment], segment.start)) frame_data = b"".join(extract_frame([segment], segment.start))
frame = Image.open(BytesIO(frame_data)) frame = Image.open(BytesIO(frame_data))
odometer, score, _ = recognize_odometer(prototypes, frame) odometer, score, _ = recognize_odometer(prototypes, frame)
@ -323,9 +348,7 @@ def extract_segment(prototypes, segment):
clock, score, _ = recognize_clock(prototypes, frame) clock, score, _ = recognize_clock(prototypes, frame)
if score < CLOCK_SCORE_THRESHOLD: if score < CLOCK_SCORE_THRESHOLD:
clock = None clock = None
tod, score, _ = recognize_time_of_day(frame) tod, distance = recognize_time_of_day(frame)
if score < TOD_SCORE_THRESHOLD:
tod = None
return odometer, clock, tod return odometer, clock, tod

Loading…
Cancel
Save