Python 如何检查我的 PNG 文件是否包含 1 个部分或多个部分

问题描述 投票:0回答:1

我正在尝试编写一些代码来检测我的 png 文件是否只是一个部分或包含多个部分(各部分之间是透明的)。

一部分png

4 部分 png

我在网上找到了一些代码,但它总是告诉我我的png有多个部分。

import numpy as np
from PIL import Image
from scipy import ndimage

def has_multiple_parts(image_path, threshold=10):
    try:
        # Open the image using Pillow
        img = Image.open(image_path)

        # Convert the image to a NumPy array
        img_array = np.array(img)

        # Convert the image to grayscale (if it's not already)
        if len(img_array.shape) == 3:
            img_gray = img.convert('L')
            img_array = np.array(img_gray)

        # Apply binary thresholding to create a mask
        mask = img_array < threshold

        # Label connected components in the mask
        labeled_regions, num_regions = ndimage.label(mask)

        # If there is only one labeled region, it's considered as one part
        return num_regions == 1
    except Exception as e:
        print(f"Error: {e}")
        return False


image_path = "c:\\Documents\\Genshin-1-part-png.png"

if has_multiple_parts(image_path):
    print(f"{image_path} has only one part.")
else:
    print(f"{image_path} has more than one part.")
python-3.x python-imaging-library png
1个回答
0
投票

我想出的最佳解决方案是使用 alpha 通道(透明通道)来计算区域。当图像透明时,该通道的值为 0;当图像不透明时,该通道的值为 255。要以 RGBA 模式打开图像,我使用 OpenCV 库,我不知道是否还有其他选项。

打开图像后,您可以将阈值应用于第四个通道(alpha)以创建蒙版,并使用 scipy 对其进行标记。

最后,使用条件

num_regions <= 2
很重要,因为 if:

  1. 所有图像都是不透明的(不是单个透明像素):那么就会有一个区域和一个部分。
  2. 图像只有一部分,但有透明像素(如示例):那么就会有两个区域,但只有一部分。

这里有完整的代码:

from scipy import ndimage
import cv2

def has_multiple_parts(image_path, threshold=1):
    try:
        # Open the image using OpenCV in RGBA mode
        img_rgba =  cv2.imread(image_path, cv2.IMREAD_UNCHANGED)

        # Take the alpha channel (transparency)
        alpha_channel = img_rgba[:,:,3]

        # Apply binary thresholding to create a mask
        mask = alpha_channel < threshold

        # Label connected components in the mask
        labeled_regions, num_regions = ndimage.label(mask)

        # If there are one or two labeled region, it means there is just one part
        return num_regions <= 2
    except Exception as e:
        print(f"Error: {e}")
        return False


image_path = "Genshin-1-part-png.png"

if has_multiple_parts(image_path):
    print(f"{image_path} has only one part.")
else:
    print(f"{image_path} has more than one part.")
© www.soinside.com 2019 - 2024. All rights reserved.