detector.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import argparse
  2. import json
  3. from detection.utils import *
  4. def main():
  5. ap = argparse.ArgumentParser()
  6. ap.add_argument("-i", "--input", default='data/_MG_0207.JPG', help="input image")
  7. ap.add_argument("-s", "--scale", type=float, default=0.1, help="based on the image shapes, scale the results by this factor")
  8. ap.add_argument("-f", "--file", type=str, default="setup.json", help="name file to load setup")
  9. args = vars(ap.parse_args())
  10. with open(args["file"], 'r') as file:
  11. setup = json.load(file)
  12. img = cv2.imread(args["input"])
  13. height, width, _ = img.shape
  14. global scale
  15. scale = args["scale"]
  16. limits = np.array(setup['Limits'])
  17. M = cv2.getPerspectiveTransform(np.float32(limits), np.float32(
  18. [[0, 0], [width, 0], [width, height], [0, height]]))
  19. img = cv2.warpPerspective(img, M, (width, height))
  20. upper_mask = cv2.rectangle(np.zeros(img.shape[0:2], np.uint8), (0, 0), (width, int(height/2)), 255)
  21. lower_mask = cv2.rectangle(np.zeros(img.shape[0:2], np.uint8), (0, int(height / 2)), (width, height), 255)
  22. show_img("Original", img)
  23. blob = blob_finder(img, 70, upper_mask, lower_mask, middle=[(0, int(height / 2)), (width, int(height/2))])
  24. foods = food_finder(img, setup['Low Food Color'], setup['High Food Color'])
  25. num_blob, num_food = numerize_blob(blob, foods, 100, 40)
  26. write_board(num_blob, num_food)
  27. cv2.waitKey(0)
  28. def write_board(numerized_blob, numerized_food):
  29. height, width, _ = numerized_blob.shape
  30. gray = cv2.cvtColor(numerized_blob, cv2.COLOR_BGR2GRAY)
  31. output = ''
  32. for x in range(height):
  33. for y in range(width):
  34. output += format(gray[x, y] != 0, 'd') + "," + format((y, x) in numerized_food, 'd') \
  35. + "," + str(gray[x, y]) + " "
  36. output = output[:-1]
  37. output += "\n"
  38. print(output)
  39. known_food = []
  40. for food in numerized_food:
  41. if gray[food[1], food[0]] != 0:
  42. known_food.append([food[0], food[1]])
  43. print(known_food)
  44. print(len(known_food))
  45. def show_img(name, img):
  46. cv2.imshow(name, cv2.resize(img, (0,0), fx=scale, fy=scale))
  47. def food_finder(img, low, high):
  48. foods, mask, food_img = find_food(img, 100, low, high)
  49. for food in foods:
  50. print(food)
  51. print("Food discovered: " + str(len(foods)))
  52. filled_mask = cv2.bitwise_and(img, img, mask=mask)
  53. show_img("Foods Mask", filled_mask)
  54. show_img("Foods", food_img)
  55. return foods
  56. def blob_finder(img, board_ratio, upper_mask, lower_mask, limits=None, middle=None):
  57. sat = saturation(img)
  58. # sum = mean_image([satA, satB])
  59. mask = find_blob(sat)
  60. blob = cv2.bitwise_and(img, img, mask=mask)
  61. cover = mean_percent_value(mask)
  62. print("Blob covering:")
  63. print("--- {:.2f}% of the image.".format(cover))
  64. print("--- {:.2f}% of the board.".format(cover / board_ratio * 100))
  65. upper_cover = mean_percent_value(cv2.bitwise_and(mask, mask, mask=upper_mask)) / mean_percent_value(upper_mask) * 100
  66. lower_cover = mean_percent_value(cv2.bitwise_and(mask, mask, mask=lower_mask)) / mean_percent_value(lower_mask) * 100
  67. print("--- {:.2f}% of the upper board.".format(upper_cover))
  68. print("--- {:.2f}% of the lower board.".format(lower_cover))
  69. blob_grid = blob.copy()
  70. if limits is not None:
  71. for i, limit in enumerate(limits):
  72. cv2.line(blob_grid, tuple(limits[i-1]), tuple(limit), (0, 0, 255), thickness=5)
  73. if middle is not None:
  74. cv2.line(blob_grid, tuple(middle[0]), tuple(middle[1]), (0, 255, 0), thickness=5)
  75. show_img("Blob Mask", mask)
  76. show_img("Blob", blob_grid)
  77. return blob
  78. def numerize_blob(img, foods, width, height):
  79. img_height, img_width, _ = img.shape
  80. numerized_blob = cv2.resize(img, (width, height), interpolation=cv2.INTER_NEAREST)
  81. numerized_food = []
  82. scaled = cv2.resize(numerized_blob, (0, 0), fx=10, fy=10, interpolation=cv2.INTER_NEAREST)
  83. for food in foods:
  84. x = int((food[0] + food[2]/2) / img_width * width)
  85. y = int((food[1] + food[3]/2) / img_height * height)
  86. numerized_food.append((x,y))
  87. cv2.drawMarker(scaled, (x *10 + 5, y * 10 + 5), (0, 0, 255), thickness=1)
  88. cv2.imshow("Test", scaled)
  89. return numerized_blob, numerized_food
  90. if __name__ == "__main__":
  91. main()