计算语义分割图像中 类 的数量

Count number of classes in a semantic segmented image

我有一张图像是语义分割算法的输出,例如这张

我在网上查看并尝试了很多代码,但 none 到目前为止对我有用。

人眼很清楚这张图片有5种不同的颜色:蓝、黑、红、白。

我正在尝试在 python 中编写一个脚本来分析图像和 return 图像中存在的颜色数量,但到目前为止它还没有用。图像中有许多像素包含上述颜色的混合值。

我使用的代码如下,但我想了解您是否认为有更简单的方法来实现这个目标。

我认为我需要实施某种具有以下逻辑的阈值:

from PIL import Image
 
imgPath = "image.jpg"
 
img = Image.open(imgPath)
uniqueColors = set()
 
w, h = img.size
for x in range(w):
    for y in range(h):
        pixel = img.getpixel((x, y))
        uniqueColors.add(pixel)
 
totalUniqueColors = len(uniqueColors)

print(totalUniqueColors)

print(uniqueColors)

提前致谢!

出了点问题 - 您的图片有 1277 种独特的颜色,而不是您建议的 5 种颜色。

对于分类图像,您可能 saved/shared 有损 JPEG 而不是无损 PNG 更喜欢吗?

我解决了我的问题,现在我可以计算来自语义分割数据集的图像中的颜色(图像必须为 .png,因为它是无损格式)。

下面我尝试解释我在解决方案的过程中发现了什么以及我使用的代码应该可以使用(你只需要改变你想要分析的图像的路径)。

我有两个主要问题。

颜色计数的第一个问题是图像的格式。我正在使用(用于某些测试)压缩图像的 .jpeg 图像。

因此从这样的事情

如果我放大玻璃杯的左上角(标记为绿色),我会看到类似这样的东西

这显然不好,因为它会引入比“人眼可见”更多的颜色

相反,对于我带注释的图像,我有如下内容

如果我放大自行车的鞍座(标记为绿色),我会看到类似这样的东西

第二个问题是我没有将图像转换为 RGB 图像。

这在以下行的代码中得到了注意:

img = Image.open(filename).convert('RGB')

代码如下。当然它不是最有效的,但对我来说它完成了工作。感谢任何改进其性能的建议

import numpy as np
from PIL import Image
import argparse
import os

debug = False

def main(data_dir):
    print("This small script allows you to count the number of different colors in an image")
    print("This code has been written to count the number of classes in images from a semantic segmentation dataset")
    print("Therefore, it is highly recommended to run this code on lossless images (such as .png ones)")
    print("Images are being loaded from: {}".format(data_dir))

    directory = os.fsencode(data_dir)
    interesting_image_format = ".png"
    
    # I will put in the variable filenames all the paths to the images to be analyzed
    filenames = []
    for file in os.listdir(directory):
        filename = os.fsdecode(file)
        if filename.endswith(interesting_image_format): 
            if debug:
                print(os.path.join(directory, filename))
                print("Analyzing image: {}".format(filename))
            filenames.append(os.path.join(data_dir, filename))
        else:
            if debug:
                print("I am not doing much here...")
            continue
    # Sort the filenames in an alphabetical order
    filenames.sort()

    # Analyze the images (i.e., count the different number of colors in the images)
    number_of_colors_in_images = []
    for filename in filenames:
        img = Image.open(filename).convert('RGB')
        if debug: 
            print(img.format)
            print(img.size)
            print(img.mode)
        data_img = np.asarray(img)
        if debug: 
            print(data_img.shape)
        uniques = np.unique(data_img.reshape(-1, data_img.shape[-1]), axis=0)
        # uncomment the following line if you want information for each analyzed image  
        print("The number of different colors in image ({}) {} is: {}".format(interesting_image_format, filename, len(uniques)))
        # print("uniques.shape[0] for image {} is: {}".format(filename, uniques.shape[0]))
        
        # Put the number of colors of each image into an array
        number_of_colors_in_images.append(len(uniques))
    
    print(number_of_colors_in_images)
    # Print the maximum number of colors (classes) of all the analyzed images
    print(np.max(number_of_colors_in_images))
    # Print the average number of colors (classes) of all the analyzed images
    print(np.average(number_of_colors_in_images))

def args_preprocess():
    # Command line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--data_dir", default="default_path_to_images", type=str, help='Specify the directory path from where to take the images of which we want to count the classes')
    args = parser.parse_args()
    main(args.data_dir)

if __name__ == '__main__':
    args_preprocess()