Выбор цвета из цельной линии

У меня есть изображение, которое выглядит эквивалентно этому изображению:

this.

Это серия кругов на странице в извилистой линии, и каждая строка отличается друг от друга.

from PIL import Image
im = Image.open("bride.jpg")

После импорта, мне было интересно, есть ли способ различать цвета. Например, это может быть:

[Purple, Cyan, Purple, Cyan, Purple Cyan...]

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

Ответ 1

Просто создайте список значений RGB вдоль строки, а затем отфильтруйте список, чтобы удалить значения смежных значений.

Получите пиксель RGB с использованием PIL

#find RGB values   
rgb_values = []
for point in line:
   r, g, b = rgb_im.getpixel(point)
   rgb_values += [ (r,g,b)]
#remove similar adjacent values
for i in range(len(rgb_values)-1):
    if rgb_values[i] == rgb_values[i+1]:
        rgb_values.pop(i)
        i -= 1
if len(rgb_values) > 1:
    if rgb_values[-1] == rgb_values[-2]:
         rgb_values.pop(-1)

Ответ 2

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

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

from PIL import Image
from numpy import array, arange

im = Image.open("aqoGkjs.png")
rgb_im = im.convert('RGB')

def get_color_at(p):  # color function as mattsap suggested
    r, g, b = rgb_im.getpixel(tuple(p))
    if r > g and r > b:
        return 'Purple'
    elif r < 10 and g < 10:
        return 'Blue'
    return 'Cyan'

colors = []
via_points = [array([25, 65]), array([185, 44]), array([240, 210])]

for i in xrange(len(via_points) - 1):
    for x in arange(0, 1, 0.01):
        p = x * via_points[i] + (1 - x) * via_points[i + 1]  # linear interpolation
        cur_color = get_color_at(p)
        if cur_color == 'Blue':  # ignore borders
            continue
        if not colors or cur_color != colors[-1]:
            colors.append(cur_color)

print colors

Он печатает:

 ['Purple', 'Cyan', 'Purple', 'Cyan', 'Purple', 'Cyan', 'Purple', 'Cyan', 'Purple', 'Cyan', 'Purple', 'Cyan', 'Purple', 'Cyan', 'Purple', 'Cyan', 'Purple']

Для вашего большого изображения вы можете вводить все путевые точки вручную. Или попробуйте сделать смарт-кусок кода, чтобы найти их автоматически;)