估计图像中绿色的百分比

dwm*_*end 3 python image-processing python-imaging-library

我正在尝试提出一种算法,通过使用 PIL 遍历像素来为图像所包含的绿色量提供分数。到目前为止,我已经提出了几种不同的方法,但它们似乎都有缺陷。

第一个将 rgb 中 g 的所有值相加并将其除以所有 3 种颜色的总和。

def percent_green(img_file):
    red = 0
    green = 0
    blue = 0

    img = Image.open(img_file)
    pixels = img.load()
    width, height = img.size
    for x in range(width):
        for y in range(height):
            rgb = pixels[x, y]
            red += rgb[0]
            green += rgb[1]
            blue += rgb[2]

    percent = green / (red + blue + green)
    return percent * 100
Run Code Online (Sandbox Code Playgroud)

这种方法成功地根据图像的绿色程度对图像进行了排序,但仅由 rgb(100, 200, 100) 组成的图像尽管非常绿色,但只能获得 50% 的分数。

我想到的另一种方法是简单地确定包含比红色或蓝色更多的绿色像素的百分比。

def percent_green(img_file):
    img = Image.open(img_file)
    pixels = img.load()
    width, height = img.size
    total_green = 0
    for x in range(width):
        for y in range(height):
            rgb = pixels[x, y]
            if rgb[1] > rgb[0] and rgb[1] > rgb[2]: #if green predominant colour
                total_green += 1


    percent = total_green /(width * height)
    return percent * 100
Run Code Online (Sandbox Code Playgroud)

这个选项的问题是像 rgb(0, 1, 0) 或 rgb(244, 255, 244) 这样的颜色会被算作绿色。理想情况下,我希望以某种方式对颜色的“绿色”进行排名。

我将非常感谢任何算法建议,这些建议可以更好地说明图像的绿色程度。也欢迎任何关于我目前的算法更好或如何改进它们的建议。

Mar*_*ell 5

一种可能的方法是在“色相饱和度和值”色彩空间HSV 色彩空间中查看图像。然后您可以查看色相,看看它是否与您要识别的绿色范围相对应。

在链接的 HSV 色轮上,您可以看到红色的色调为 0,绿色为 120,蓝色为 240。但是,PIL 希望将这些值保存在一个范围为 0..255 而不是 0 的无符号 8 位数字中..360,因此所有值都按 255/360 缩放。因此,在 PIL 中,红队的得分约为 0,绿队的得分约为 85,蓝队的得分约为 170。

因此,您可以使用以下代码将所有介于 80..90 之间的像素计数为绿色。请注意,在 Python 中迭代像素通常是一个非常糟糕的主意 - 它很慢 - 所以我使用 Numpy。如果您不想使用 Numpy,只需像我在下面所做的那样获取 Hue 通道,并在常规 Python 中迭代计算您想要的范围内的像素:

from PIL import Image
import numpy as np

# Load image and convert to HSV
im = Image.open('bp-1.jpg').convert('HSV')

# Extract Hue channel and make Numpy array for fast processing
Hue = np.array(im.getchannel('H'))

# Make mask of zeroes in which we will set greens to 1
mask = np.zeros_like(Hue, dtype=np.uint8) 

# Set all green pixels to 1
mask[(Hue>80) & (Hue<90)] = 1 

# Now print percentage of green pixels
print((mask.mean()*100)
Run Code Online (Sandbox Code Playgroud)

如果我在他的图像上运行它,我会得到 4%

在此处输入图片说明

而有了这张图片,我得到了 31%

在此处输入图片说明

如果您只想计算高度饱和的颜色,您也可以提取并考虑饱和度。