bus_analyzer: Normalize brightness across all digits, not one by one

pull/370/head
Mike Lang 1 year ago
parent bd9e22bc1f
commit 8ac6e71d48

@ -99,32 +99,34 @@ def extract_digits(image, type):
for dx in range(DIGIT_WIDTH) for dx in range(DIGIT_WIDTH)
] ]
main_digits = get_brightest_region(image, digit_xs, DIGIT_HEIGHT) main_digits = get_brightest_region(image, digit_xs, DIGIT_HEIGHT)
main_digits = normalize(main_digits)
digits = [] digits = []
for i, x in enumerate(main_digit_coords): for i, x in enumerate(main_digit_coords):
digit = main_digits.crop((x, 0, x + DIGIT_WIDTH, main_digits.height)) digit = main_digits.crop((x, 0, x + DIGIT_WIDTH, main_digits.height))
digits.append(normalize_digit(digit)) digits.append(digit)
if type == "odo": if type == "odo":
x = DIGIT_X_COORDS["odo"][-1] x = DIGIT_X_COORDS["odo"][-1]
last_digit = get_brightest_region(image, range(x, x + DIGIT_WIDTH), LAST_DIGIT_HEIGHT) 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)) 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 return digits
def normalize_digit(digit): def normalize(image):
# Expand the range of the image so that the darkest pixel becomes black # Expand the range of the image so that the darkest pixel becomes black
# and the lightest becomes white # and the lightest becomes white
_min, _max = digit.getextrema() _min, _max = image.getextrema()
_range = _max - _min _range = _max - _min
if _range == 0: if _range == 0:
digit = digit.point(lambda v: 128) image = image.point(lambda v: 128)
else: 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): 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) guess, score, all_scores = recognize_digit(prototypes["odo-digits"], digit)
print("Digit = {} with score {}".format(guess, score)) print("Digit = {} with score {}".format(guess, score))
if verbose: 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: for s, n in all_scores:
print("{}: {}".format(n, s)) print("{}: {}".format(n, s))

@ -48,7 +48,7 @@ def compare_segments(dbconnect, base_dir='.', prototypes_path="./prototypes", si
where = ["true"] where = ["true"]
where = " AND ".join(where) where = " AND ".join(where)
result = database.query(conn, f""" result = database.query(conn, f"""
SELECT odometer, segment SELECT odometer, clock, timeofday, segment
FROM bus_data FROM bus_data
WHERE segment IS NOT NULL WHERE segment IS NOT NULL
AND {where} 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 # To get a wider range of tests, pick at random from all unique odo readings
available = {} available = {}
for row in result.fetchall(): for row in result.fetchall():
available.setdefault(row.odometer, []).append(row.segment) available.setdefault(row.odometer, []).append((row.segment, row.clock, row.timeofday))
selected = [] selected = []
while available and len(selected) < num: while available and len(selected) < num:
@ -72,18 +72,25 @@ def compare_segments(dbconnect, base_dir='.', prototypes_path="./prototypes", si
del available[odometer] del available[odometer]
results = [] results = []
for old_odometer, segment in selected: for old_odometer, (segment, old_clock, old_tod) in selected:
path = os.path.join(base_dir, segment) path = os.path.join(base_dir, segment)
segment_info = parse_segment_path(path) segment_info = parse_segment_path(path)
odometer, clock, tod = extract_segment(prototypes, segment_info) 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 matching = 0
for segment, old_odometer, odometer in sorted(results, key=lambda t: t[0]): for segment, data in sorted(results, key=lambda t: t[0]):
match = old_odometer == odometer matched = True
for k, (old, new) in data.items():
match = old == new
if verbose or not match: if verbose or not match:
print(f"{segment}: {old_odometer} | {odometer}") print(f"{segment} {k}: {old} | {new}")
if match: matched &= match
if matched:
matching += 1 matching += 1
print("{}/{} matched".format(matching, len(selected))) print("{}/{} matched".format(matching, len(selected)))

Loading…
Cancel
Save