From 8ac6e71d481ef881ec0fcdfcec5c3db4fcd553af Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Fri, 17 Nov 2023 00:42:19 +1100 Subject: [PATCH] bus_analyzer: Normalize brightness across all digits, not one by one --- bus_analyzer/bus_analyzer/extract.py | 18 ++++++++++-------- bus_analyzer/bus_analyzer/main.py | 25 ++++++++++++++++--------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/bus_analyzer/bus_analyzer/extract.py b/bus_analyzer/bus_analyzer/extract.py index e221791..d060032 100644 --- a/bus_analyzer/bus_analyzer/extract.py +++ b/bus_analyzer/bus_analyzer/extract.py @@ -99,32 +99,34 @@ def extract_digits(image, type): for dx in range(DIGIT_WIDTH) ] main_digits = get_brightest_region(image, digit_xs, DIGIT_HEIGHT) + main_digits = normalize(main_digits) digits = [] for i, x in enumerate(main_digit_coords): digit = main_digits.crop((x, 0, x + DIGIT_WIDTH, main_digits.height)) - digits.append(normalize_digit(digit)) + digits.append(digit) if type == "odo": x = DIGIT_X_COORDS["odo"][-1] last_digit = get_brightest_region(image, range(x, x + DIGIT_WIDTH), LAST_DIGIT_HEIGHT) last_digit = last_digit.crop((x, 0, x + DIGIT_WIDTH, last_digit.height)) - digits.append(normalize_digit(last_digit)) + last_digit = normalize(last_digit) + digits.append(last_digit) return digits -def normalize_digit(digit): +def normalize(image): # Expand the range of the image so that the darkest pixel becomes black # and the lightest becomes white - _min, _max = digit.getextrema() + _min, _max = image.getextrema() _range = _max - _min if _range == 0: - digit = digit.point(lambda v: 128) + image = image.point(lambda v: 128) else: - digit = digit.point(lambda v: 255 * (v - _min) / _range) + image = image.point(lambda v: 255 * (v - _min) / _range) - return digit + return image def recognize_digit(prototypes, image, blank_is_zero=False): @@ -181,7 +183,7 @@ def read_digit(digit, prototypes_path="./prototypes", verbose=False): guess, score, all_scores = recognize_digit(prototypes["odo-digits"], digit) print("Digit = {} with score {}".format(guess, score)) if verbose: - all_scores.sort(key=lambda x: x[1]) + all_scores.sort(key=lambda x: -1 if x[1] is None else x[1]) for s, n in all_scores: print("{}: {}".format(n, s)) diff --git a/bus_analyzer/bus_analyzer/main.py b/bus_analyzer/bus_analyzer/main.py index 1124bc2..c83a20a 100644 --- a/bus_analyzer/bus_analyzer/main.py +++ b/bus_analyzer/bus_analyzer/main.py @@ -48,7 +48,7 @@ def compare_segments(dbconnect, base_dir='.', prototypes_path="./prototypes", si where = ["true"] where = " AND ".join(where) result = database.query(conn, f""" - SELECT odometer, segment + SELECT odometer, clock, timeofday, segment FROM bus_data WHERE segment IS NOT NULL AND {where} @@ -57,7 +57,7 @@ def compare_segments(dbconnect, base_dir='.', prototypes_path="./prototypes", si # To get a wider range of tests, pick at random from all unique odo readings available = {} for row in result.fetchall(): - available.setdefault(row.odometer, []).append(row.segment) + available.setdefault(row.odometer, []).append((row.segment, row.clock, row.timeofday)) selected = [] while available and len(selected) < num: @@ -72,18 +72,25 @@ def compare_segments(dbconnect, base_dir='.', prototypes_path="./prototypes", si del available[odometer] results = [] - for old_odometer, segment in selected: + for old_odometer, (segment, old_clock, old_tod) in selected: path = os.path.join(base_dir, segment) segment_info = parse_segment_path(path) odometer, clock, tod = extract_segment(prototypes, segment_info) - results.append((segment, old_odometer, odometer)) + results.append((segment, { + "odo": (old_odometer, odometer), + "clock": (old_clock, clock), + "tod": (old_tod, tod), + })) matching = 0 - for segment, old_odometer, odometer in sorted(results, key=lambda t: t[0]): - match = old_odometer == odometer - if verbose or not match: - print(f"{segment}: {old_odometer} | {odometer}") - if match: + for segment, data in sorted(results, key=lambda t: t[0]): + matched = True + for k, (old, new) in data.items(): + match = old == new + if verbose or not match: + print(f"{segment} {k}: {old} | {new}") + matched &= match + if matched: matching += 1 print("{}/{} matched".format(matching, len(selected)))