[Python] smooth edge of piece

Discussão em 'Python' iniciado por Stack, Junho 5, 2025.

  1. Stack

    Stack Membro Participativo

    This is the code where I perform thresholding on an image to detect the piece and I would like to be able to smooth the edge even more.

    I've never worked with Python, but I'd be interested in doing this project to find a solution to a puzzle. Therefore, I need the edges of the piece to be as smooth as possible.

    from PIL import Image, ExifTags, ImageFilter

    EXPECTED_PHOTO_ORIENTATION = 1 # Horizontal (normal)

    def get_photo_orientation(img):
    exif = img._getexif()
    if exif:
    for tag, value in exif.items():
    if tag in ExifTags.TAGS:
    if ExifTags.TAGS[tag] == 'Orientation':
    return value
    return None


    def binary_pixel_data_for_photo(path, threshold, max_width=None, crop=None):
    """
    Given a bitmap image path, returns a 2D array of 1s and 0s
    crop is either None or (top, right, bottom, left) in pixels
    """
    with Image.open(path) as img:
    if (orientation := get_photo_orientation(img)) is not None and orientation != EXPECTED_PHOTO_ORIENTATION:
    raise Exception(f"Image {path} is not oriented correctly: {orientation}")

    w, h = img.size

    if max_width is not None and img.size[0] > max_width:
    scale_factor = max_width / img.size[0]
    try:
    img = img.resize((max_width, int(img.size[1] * scale_factor)), resample=Image.NEAREST)
    except Exception as e:
    print(f"Error resizing {path}")
    raise e
    else:
    scale_factor = 1.0

    if crop:
    w, h = img.size
    img = img.crop((crop[3], crop[0], w - crop[1], h - crop[2]))


    data, out_w, out_h = threshold_pixels(img, threshold)
    return data, out_w, out_h, scale_factor


    def threshold_pixels(img, threshold):
    # Convert image to grayscale numpy array
    grayscale = img.convert('L')
    data = np.array(grayscale)

    # Aplicar convolución
    filtered = cv2.GaussianBlur(data, (9, 9), sigmaX=0)

    # Apply threshold to get binary representation
    binary_data = np.where(filtered <= threshold, 0, 1).astype(np.int8)
    return binary_data, binary_data.shape[1], binary_data.shape[0]


    binary_data, out_w, out_h, scale_factor = binary_pixel_data_for_photo("ejemplo.jpeg", 100)

    binary_uint8 = binary_data.astype(np.uint8) * 255

    contours, _ = cv2.findContours(binary_uint8, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    if contours:
    largest = max(contours, key=cv2.contourArea)
    contour_img = np.zeros_like(binary_uint8)
    cv2.drawContours(contour_img, [largest], 0, 255, -1)

    # Mostrar resultado
    plt.imshow(cv2.imread("ejemplo.jpeg"))
    plt.title("Imagen original")
    plt.axis("off")
    plt.show()

    plt.figure(figsize=(6, 8))
    plt.imshow(contour_img)
    plt.title("Contorno de la pieza")
    plt.axis("off")
    plt.show()


    [​IMG]

    [​IMG]

    [​IMG]

    Continue reading...

Compartilhe esta Página