detection_setup.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import cv2
  2. import json
  3. import datetime
  4. import time
  5. from shutil import copyfile
  6. from os import path, makedirs
  7. from detection.limits_maker import LimitsMaker
  8. from detection.food_limits import FoodLimits
  9. from detection.food_colors import FoodColors
  10. def setup(setup_img, config_filename, scale=1.0, bkp_path="detection/bkp/"):
  11. img = cv2.imread(setup_img)
  12. height, width, _ = img.shape
  13. window_name = "Setup"
  14. cv2.namedWindow(window_name)
  15. cv2.imshow(window_name, cv2.resize(img, (0, 0), fx=scale, fy=scale))
  16. cv2.setMouseCallback(window_name, null_callback)
  17. food_color = FoodColors(img, scale, window_name)
  18. board_setup = LimitsMaker(img, scale, window_name, "Board Setup")
  19. food_limits = FoodLimits(img, scale, window_name)
  20. setup_vars = {'Aspect Ratio': 1.0, 'Discrete Height': 100, 'Discrete Width': 100}
  21. if path.exists(config_filename):
  22. with open(config_filename, "r") as file:
  23. config = json.load(file)
  24. setup_vars['Aspect Ratio'] = config['Aspect Ratio']
  25. setup_vars['Discrete Height'] = config['Discrete Height']
  26. setup_vars['Discrete Width'] = config['Discrete Width']
  27. board_setup.limits = [tuple(x) for x in config['Limits']]
  28. food_color.colors.append(tuple(config["High Food Color"]))
  29. food_color.colors.append(tuple(config["Low Food Color"]))
  30. food_color.show_selected()
  31. food_limits.min_dist = config["Min Food Size"]
  32. def show_menu():
  33. print("\nCommands: ")
  34. print("\tEnter '1' to setup board limits")
  35. low, high = food_color.compute()
  36. print("\tEnter '2' to setup food color. (Current from {} to {})".format(low, high))
  37. print("\tEnter '3' to insert image aspect ratio. (Current: {})".format(setup_vars['Aspect Ratio']))
  38. print("\tEnter '4' to insert discrete image width and height. (Current: {}x{})"
  39. .format(setup_vars['Discrete Width'], setup_vars['Discrete Height']))
  40. print("\tEnter '5' to setup food limits. (Current min food size: {})".format(food_limits.min_dist))
  41. print("\tEnter 's' to save & quit")
  42. print("\tEnter 'q' to quit without saving")
  43. show_menu()
  44. done = False
  45. state = 0
  46. while not done:
  47. cv2.waitKey(10)
  48. if state == 0:
  49. cv2.imshow(window_name, cv2.resize(img, (0, 0), fx=scale, fy=scale))
  50. cv2.setMouseCallback(window_name, null_callback)
  51. key = input("Enter command: ")
  52. if key == "q":
  53. done = True
  54. elif key == "1":
  55. state = 1
  56. # board_setup.clear()
  57. board_setup.help()
  58. cv2.setMouseCallback(window_name, board_setup.on_mouse)
  59. elif key == "2":
  60. state = 2
  61. # food_color.clear()
  62. food_color.help()
  63. cv2.setMouseCallback(window_name, food_color.on_mouse)
  64. elif key == "3":
  65. setup_vars['Aspect Ratio'] = -1
  66. while setup_vars['Aspect Ratio'] <= 0:
  67. try:
  68. setup_vars['Aspect Ratio'] = float(input("Insert image height by width ratio here: "))
  69. except ValueError:
  70. setup_vars['Aspect Ratio'] = -1
  71. if setup_vars['Aspect Ratio'] <= 0:
  72. print("Insert only a floating number with dot as separator.")
  73. show_menu()
  74. elif key == "4":
  75. setup_vars['Discrete Width'] = -1
  76. while setup_vars['Discrete Width'] <= 0:
  77. try:
  78. setup_vars['Discrete Width'] = int(input("Insert width discrete resolution: "))
  79. except ValueError:
  80. setup_vars['Discrete Width'] = -1
  81. if setup_vars['Discrete Width'] <= 0:
  82. print("Insert only round numbers.")
  83. setup_vars['Discrete Height'] = -1
  84. while setup_vars['Discrete Height'] <= 0:
  85. try:
  86. setup_vars['Discrete Height'] = int(input("Insert height discrete resolution: "))
  87. except ValueError:
  88. setup_vars['Discrete Height'] = -1
  89. if setup_vars['Discrete Height'] <= 0:
  90. print("Insert only round numbers.")
  91. show_menu()
  92. elif key == "5":
  93. state = 3
  94. food_limits.clear()
  95. food_limits.help()
  96. cv2.setMouseCallback(window_name, food_limits.on_mouse)
  97. elif key == "s":
  98. ts = datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d_%H.%M.%S-')
  99. if path.exists(config_filename):
  100. if not path.exists(bkp_path):
  101. makedirs(bkp_path)
  102. copyfile(config_filename, bkp_path + ts + path.basename(config_filename))
  103. with open(config_filename, "w") as file:
  104. json.dump({**setup_vars, **board_setup.toJSON(), **food_color.toJSON(), **food_limits.toJSON()},
  105. file, indent=4, sort_keys=True)
  106. done = True
  107. else:
  108. print("Error: Unrecognised Command.")
  109. show_menu()
  110. elif state == 1:
  111. board_setup.draw()
  112. if board_setup.done:
  113. state = 0
  114. show_menu()
  115. elif state == 2:
  116. food_color.draw()
  117. if food_color.done:
  118. state = 0
  119. show_menu()
  120. elif state == 3:
  121. food_limits.draw()
  122. if food_limits.done:
  123. state = 0
  124. show_menu()
  125. def null_callback(event, x, y, flags, param):
  126. return