import cv2 import json import datetime import time from shutil import copyfile from os import path, makedirs from detection.limits_maker import LimitsMaker from detection.food_limits import FoodLimits from detection.food_colors import FoodColors def setup(setup_img, config_filename, scale=1.0, bkp_path="detection/bkp/"): img = cv2.imread(setup_img) height, width, _ = img.shape window_name = "Setup" cv2.namedWindow(window_name) cv2.imshow(window_name, cv2.resize(img, (0, 0), fx=scale, fy=scale)) cv2.setMouseCallback(window_name, null_callback) food_color = FoodColors(img, scale, window_name) board_setup = LimitsMaker(img, scale, window_name, "Board Setup") food_limits = FoodLimits(img, scale, window_name) setup_vars = {'Aspect Ratio': 1.0, 'Discrete Height': 100, 'Discrete Width': 100} if path.exists(config_filename): with open(config_filename, "r") as file: config = json.load(file) setup_vars['Aspect Ratio'] = config['Aspect Ratio'] setup_vars['Discrete Height'] = config['Discrete Height'] setup_vars['Discrete Width'] = config['Discrete Width'] board_setup.limits = [tuple(x) for x in config['Limits']] food_color.colors.append(tuple(config["High Food Color"])) food_color.colors.append(tuple(config["Low Food Color"])) food_color.show_selected() food_limits.min_dist = config["Min Food Size"] def show_menu(): print("\nCommands: ") print("\tEnter '1' to setup board limits") low, high = food_color.compute() print("\tEnter '2' to setup food color. (Current from {} to {})".format(low, high)) print("\tEnter '3' to insert image aspect ratio. (Current: {})".format(setup_vars['Aspect Ratio'])) print("\tEnter '4' to insert discrete image width and height. (Current: {}x{})" .format(setup_vars['Discrete Width'], setup_vars['Discrete Height'])) print("\tEnter '5' to setup food limits. (Current min food size: {})".format(food_limits.min_dist)) print("\tEnter 's' to save & quit") print("\tEnter 'q' to quit without saving") show_menu() done = False state = 0 while not done: cv2.waitKey(10) if state == 0: cv2.imshow(window_name, cv2.resize(img, (0, 0), fx=scale, fy=scale)) cv2.setMouseCallback(window_name, null_callback) key = input("Enter command: ") if key == "q": done = True elif key == "1": state = 1 # board_setup.clear() board_setup.help() cv2.setMouseCallback(window_name, board_setup.on_mouse) elif key == "2": state = 2 # food_color.clear() food_color.help() cv2.setMouseCallback(window_name, food_color.on_mouse) elif key == "3": setup_vars['Aspect Ratio'] = -1 while setup_vars['Aspect Ratio'] <= 0: try: setup_vars['Aspect Ratio'] = float(input("Insert image height by width ratio here: ")) except ValueError: setup_vars['Aspect Ratio'] = -1 if setup_vars['Aspect Ratio'] <= 0: print("Insert only a floating number with dot as separator.") show_menu() elif key == "4": setup_vars['Discrete Width'] = -1 while setup_vars['Discrete Width'] <= 0: try: setup_vars['Discrete Width'] = int(input("Insert width discrete resolution: ")) except ValueError: setup_vars['Discrete Width'] = -1 if setup_vars['Discrete Width'] <= 0: print("Insert only round numbers.") setup_vars['Discrete Height'] = -1 while setup_vars['Discrete Height'] <= 0: try: setup_vars['Discrete Height'] = int(input("Insert height discrete resolution: ")) except ValueError: setup_vars['Discrete Height'] = -1 if setup_vars['Discrete Height'] <= 0: print("Insert only round numbers.") show_menu() elif key == "5": state = 3 food_limits.clear() food_limits.help() cv2.setMouseCallback(window_name, food_limits.on_mouse) elif key == "s": ts = datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d_%H.%M.%S-') if path.exists(config_filename): if not path.exists(bkp_path): makedirs(bkp_path) copyfile(config_filename, bkp_path + ts + path.basename(config_filename)) with open(config_filename, "w") as file: json.dump({**setup_vars, **board_setup.toJSON(), **food_color.toJSON(), **food_limits.toJSON()}, file, indent=4, sort_keys=True) done = True else: print("Error: Unrecognised Command.") show_menu() elif state == 1: board_setup.draw() if board_setup.done: state = 0 show_menu() elif state == 2: food_color.draw() if food_color.done: state = 0 show_menu() elif state == 3: food_limits.draw() if food_limits.done: state = 0 show_menu() def null_callback(event, x, y, flags, param): return