If you want you can share these sketchy thresholds. I am bothering with this problem for 1 week and the first approach was this:
I couldn’t find the way to do this and trying every tool available in opencv considering switching to neural networks…
def process(self):
for i in range(len(self.images)):
print(f"Image_{i}")
img = self.images[i]
for color_name in self.colors:
color = self.colors.get(color_name)
# colors
bgr_img, c_cropped_img = self.mask_color_adjust_color(img, color[0], color[1])
# make threshold img
gr_img = cv2.cvtColor(c_cropped_img, cv2.COLOR_BGR2GRAY)
ret, threshold = cv2.threshold(gr_img, 0, 255, cv2.THRESH_BINARY)
# ============ DETECT CIRCLES =============
circles = 0
height, width = gr_img.shape
circle_mask = np.zeros((height, width), np.uint8)
circles, circle_mask = self.detect_circles(threshold, circle_mask)
threshold = cv2.bitwise_and(threshold, circle_mask)
if circles is not None:
self.objects[10] = len(circles[0, :])
circles = len(circles[0, :])
else:
self.objects[10] = 0
circles = 0
# ==========================================
countours, hierarchy = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
snake = 0
bear = 0
areas = []
# ============ DETECT BEAR/SNAKE BASED ON AREA ===============
for cnt in countours:
area = cv2.contourArea(cnt)
if area > 100:
areas.append(area)
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
(tl, tr, br, bl) = box
DimA = np.sqrt(pow(tl[0] - tr[0], 2) + pow(tl[1] - tr[1], 2))
DimB = np.sqrt(pow(tl[0] - bl[0], 2) + pow(tl[1] - bl[1], 2))
dim = [DimA, DimB]
longest = max(dim)
shortest = min(dim)
ratio = shortest / longest
max_area = max(areas) # snake max
noise_area = 0.2 * max_area # noise
if area > noise_area:
# print(ratio, area)
if ratio < 0.43:
snake += 1
# print("Waz", area)
elif ratio > 0.43:
bear += 1
# print("Mis", area)
# =========================================================
if color_name == "green":
self.objects[3] = bear
self.objects[9] = circles
self.objects[12] = snake
elif color_name == "orange":
self.objects[2] = bear
self.objects[8] = circles
self.objects[13] = snake
elif color_name == "yellow":
self.objects[4] = bear
self.objects[10] = circles
self.objects[14] = snake
elif color_name == "light_red":
self.objects[0] = bear
self.objects[6] = circles
elif color_name == "dark_red":
self.objects[1] = bear
self.objects[7] = circles
self.result[self.image_names[i]] = self.objects
def mask_color_adjust_color(image, color_low, color_high):
bgr_img = image
bgr_img = cv2.resize(bgr_img, (int(bgr_img.shape[1] / 5), int(bgr_img.shape[0] / 5)))
bgr_img = cv2.medianBlur(bgr_img, 3)
bgr_img = cv2.convertScaleAbs(bgr_img, alpha=1.2, beta=1)
hsv_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2HSV)
curr_mask = cv2.inRange(hsv_img, color_low, color_high)
g_cropped_img = cv2.bitwise_and(bgr_img, bgr_img, mask=curr_mask)
return bgr_img, g_cropped_img