[Python] cv2.inRange on HSV image always empty

Discussão em 'Python' iniciado por Stack, Agosto 9, 2025.

  1. Stack

    Stack Membro Participativo

    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...

Compartilhe esta Página