[Python] Finding largest contour python CV

Discussão em 'Python' iniciado por Stack, Fevereiro 16, 2025.

  1. Stack

    Stack Membro Participativo

    I'm struggling to get the bounding box for an identified area in an image. The following code results in this image: https://i.sstatic.net/6HX4dNrB.png. However, as might be obvious from the picture, I'd like to bounding box to enclose the (black) identified large area instead. Any suggestions on how to accomplish that?

    import numpy as np
    import cv2

    # Load the image
    image = cv2.imread("image.png") # Update with your image path
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

    # Define refined HSV ranges for sandy ground (light brown, beige, gray)
    lower_sand = np.array([10, 20, 100]) # Lower bound for sand-like colors
    upper_sand = np.array([30, 100, 255]) # Upper bound for sand-like colors

    # Create a mask for the sandy competition ground
    mask_sand = cv2.inRange(hsv, lower_sand, upper_sand)

    # Apply morphological operations to reduce noise
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7))
    mask_sand = cv2.morphologyEx(mask_sand, cv2.MORPH_CLOSE, kernel) # Close gaps
    mask_sand = cv2.morphologyEx(mask_sand, cv2.MORPH_OPEN, kernel) # Remove small noise

    # Invert the mask (to highlight everything except the competition area)
    mask = cv2.bitwise_not(mask_sand)

    # Apply the inverted mask to the original image
    output = cv2.bitwise_and(image, image, mask=mask)

    # Ensure the mask is properly binarized for contour detection
    ret, thresh = cv2.threshold(mask, 50, 255, cv2.THRESH_BINARY)

    # Find contours
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    if contours:
    # Find the largest contour by area
    largest_contour = max(contours, key=cv2.contourArea)

    # Approximate the contour to a quadrilateral
    epsilon = 0.02 * cv2.arcLength(largest_contour, True)
    approx = cv2.approxPolyDP(largest_contour, epsilon, True)

    # If the approximation has 4 points, use it; otherwise, use convex hull
    if len(approx) == 4:
    quadrilateral = approx
    else:
    quadrilateral = cv2.convexHull(largest_contour)

    # Draw the quadrilateral in green
    cv2.polylines(output, [quadrilateral], isClosed=True, color=(0, 255, 0), thickness=3)

    # Draw all detected contours in blue
    cv2.drawContours(output, contours, -1, (255, 0, 0), 2)


    # Show and save the output
    cv2.imshow("Result", np.hstack([image, output]))
    cv2.imwrite("output_image.png", output)

    cv2.waitKey(0)
    cv2.destroyAllWindows()

    Continue reading...

Compartilhe esta Página