I am running into a strange issue involving the use of cv2.inRange and could use some help. For context, I am trying to identify the colors of each individual circle for this board game (board). Since some of the colors look very similar, I had the idea to “tune” the colors to find the min and max HSV values for each color. To do this, I first crop the area I am interested in. def crop_circle(img, i, j): h, w = img.shape[:2] mask = np.zeros((h, w), np.uint8) # Empty black mask cv2.circle(mask, calculate_center(i, j), CIRCLE_RADIUS, CIRCLE_COLOR, -1) # Fill in white circle result = cv2.bitwise_and(img, img, mask=mask) x, y, w, h = cv2.boundingRect(mask) return result[y : y + h, x : x + w] Then I split the image and calculate those min / max HSV values. def split_image(img): v, v2, v3 = cv2.split(img) v_avg = int(cv2.mean(v)[0]) v2_avg = int(cv2.mean(v2)[0]) v3_avg = int(cv2.mean(v3)[0]) return v_avg, v2_avg, v3_avg def calculate_optimal_colors(hsv_img, colors): def _update_colors(hsv_img, letter, colors): def _helper(img, color_detection, letter, colors): v, v2, v3 = split_image(img) if len(colors[letter][color_detection.name]) == 0: colors[letter][color_detection.name] = [[v, v2, v3], [v, v2, v3]] else: values = colors[letter][color_detection.name] values[0][0] = min(values[0][0], v) values[0][1] = min(values[0][1], v2) values[0][2] = min(values[0][2], v3) values[1][0] = max(values[1][0], v) values[1][1] = max(values[1][1], v2) values[1][2] = max(values[1][2], v3) if letter not in colors: colors[letter] = { COLOR_DETECTION.HSV.name: [] } _helper(hsv_img, COLOR_DETECTION.HSV, letter, colors) Then I use those min / max HSV values in attempt to determine what the most likely color is by passing those values to cv2.inRange. I try to calculate the percentage of matching pixels that are in that range. def _calculate_letter_percentage(img, lower_range, upper_range, threshold=0.5): mask = cv2.inRange(img, np.array(lower_range), np.array(upper_range)) # Calculate the percentage of matching pixels total_pixels = mask.shape[0] * mask.shape[1] matching_pixels = np.sum(mask > 0) percentage = matching_pixels / total_pixels return percentage if percentage > threshold else 0 However, the mask ALWAYS results in being all black (see below image). The number of matching pixels is always 0 (mask). And I have confirmed that the incoming image to determine that percentage is in fact HSV (image). Any ideas what is going on here? Thanks so much! Continue reading...