def manual_review( response_bounding_box: BoundingBox, page: Image, circled_responses: List[ResponseCode], voter_id, response_codes: List[ResponseCode]) -> Tuple[bool, List[ResponseCode]]: user_verdict = None top_margin = 50 # init response_image responses_image = page.get_roi(response_bounding_box).add_border( top=top_margin) # get list of responses response_pairs = [] if circled_responses: for resp in circled_responses: response_pairs.append('Q{}: {}'.format(resp.question_number, resp.value)) # add dots in the center of each highlighted response code cv2.circle(responses_image.raw_image, (resp.coords.x, resp.coords.y + top_margin), 6, (0, 0, 255), -1) # convert to a string response_string = ", ".join(response_pairs) else: response_string = 'None' # annotate the response image responses_question = "Responses: {}. Is this correct? (y|n|c|m|h|g|l)".format( response_string) # keep looping until the y or n key is pressed while True: # display the image and wait for a keypress key = responses_image.show(title="manual review", message=responses_question, resize=False) # if the 'y' key is pressed, user approves if key == ord("y"): user_verdict = True print('{}: Correct scan!'.format(voter_id)) break # if the 'n' key is pressed, user rejects elif key == ord("n"): user_verdict = False print('{}: Incorrect scan :('.format(voter_id)) circled_responses = get_correct_responses(response_codes) break # if the 'c' key is pressed, user rejects, correct answer is none elif key == ord("c"): user_verdict = False print('{}: Incorrect scan :('.format(voter_id)) circled_responses = get_correct_responses(response_codes, 'c') break # if the 'm' key is pressed, user rejects, correct answer is MAT elif key == ord("m"): user_verdict = False print('{}: Incorrect scan :('.format(voter_id)) circled_responses = get_correct_responses(response_codes, 'm') break # if the 'h' key is pressed, user rejects, correct answer is NH elif key == ord("h"): user_verdict = False print('{}: Incorrect scan :('.format(voter_id)) circled_responses = get_correct_responses(response_codes, 'h') break # if the 'g' key is pressed, user rejects, correct answer is GTD elif key == ord("g"): user_verdict = False print('{}: Incorrect scan :('.format(voter_id)) circled_responses = get_correct_responses(response_codes, 'g') break # if the 'l' key is pressed, user rejects, correct answer is MAT + NH elif key == ord("l"): user_verdict = False print('{}: Incorrect scan :('.format(voter_id)) circled_responses = get_correct_responses(response_codes, 'l') break # close window cv2.destroyAllWindows() # create empty list if None if circled_responses is None: circled_responses = [] print('correct_responses:') print([code.value for code in circled_responses]) return user_verdict, circled_responses