Оценка процентного содержания зеленого цвета в изображении - PullRequest
1 голос
/ 12 июня 2019

Я пытаюсь придумать алгоритм, чтобы дать изображениям оценку количества зеленого, которое они содержат, путем перебора пикселей с помощью PIL.До сих пор я придумал несколько разных методов, но все они кажутся ошибочными.

Первый суммирует все значения g в rgb и делит его, но в сумме все 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

Этот метод позволяет ранжировать изображения по тому, насколько они зеленые, но, например, изображение, состоящее только из 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

Проблема с этой опцией состоит в том, что цвета, такие как rgb (0, 1, 0) или rgb (244, 255, 244) будет считаться зеленым.В идеале я хотел бы, чтобы какой-то способ оценил «зеленость» цвета.

Я был бы очень признателен за любые предложения алгоритмов, которые могут дать лучший процент того, насколько зеленое изображение.Любые предложения о том, какой из моих нынешних алгоритмов лучше или как их улучшить, также приветствуются.

1 Ответ

2 голосов
/ 12 июня 2019

Один из возможных способов - посмотреть на изображение в "Насыщенность и значение оттенка" Цветовое пространство Цветовое пространство HSV .Затем вы можете посмотреть на оттенок и посмотреть, соответствует ли он диапазону зеленых, которые вы хотите идентифицировать.

На связанном цветовом круге HSV вы можете увидеть, что красные имеют оттенок 0, зеленые 120 и синийравны 240. Однако PIL хочет сохранить эти значения в 8-разрядном числе без знака с диапазоном 0..255, а не 0..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()*mask.size)/100)

Если я запускаю его наего изображение, я получаю 4%

enter image description here

В то время как с этим изображением я получаю 31%

enter image description here

Вы также можете извлечь и рассмотреть насыщенность, если хотите считать только насыщенные цвета.

...