PIL лучший способ заменить цвет?

Вот еще несколько ресурсов, которые необходимо проверить:

  1. Это управление DevExpress WinForms: http://www.devexpress.com/Products/NET/Controls/WinForms/Wizard/

  2. А платформа мастеров собственной разработки: http://weblogs.asp.net/justin_rogers/articles/60155.aspx

  3. платформа мастера А частью Shawn Wildermut платформы Chris Sells Genghis: http://www.sellsbrothers.com/tools/genghis/

16
задан Community 23 May 2017 в 12:34
поделиться

4 ответа

Вам нужно будет представить изображение в виде двухмерного массива. Это означает либо создание списка списков пикселей, либо просмотр одномерного массива как двухмерного с помощью некоторой умной математики. Затем для каждого целевого пикселя вам необходимо найти все окружающие пиксели. Вы можете сделать это с помощью генератора Python следующим образом:

def targets(x,y):
    yield (x,y) # Center
    yield (x+1,y) # Left
    yield (x-1,y) # Right
    yield (x,y+1) # Above
    yield (x,y-1) # Below
    yield (x+1,y+1) # Above and to the right
    yield (x+1,y-1) # Below and to the right
    yield (x-1,y+1) # Above and to the left
    yield (x-1,y-1) # Below and to the left

Итак, вы могли бы использовать его так:

for x in range(width):
    for y in range(height):
        px = pixels[x][y]
        if px[0] == 255 and px[1] == 255 and px[2] == 255:
            for i,j in targets(x,y):
                newpixels[i][j] = replacementColor
5
ответ дан 30 November 2019 в 15:28
поделиться

Лучший способ сделать это - использовать алгоритм «цвет в альфа», используемый в GIMP для замены цвета. Он отлично подойдет в вашем случае. Я повторно реализовал этот алгоритм, используя PIL для фотопроцессора Python с открытым исходным кодом phatch . Вы можете найти полную реализацию здесь . Это чистая реализация PIL и других зависимостей у нее нет. Вы можете скопировать код функции и использовать его. Вот пример использования GIMP: от

alt text до alt text

Вы можете применить функцию color_to_alpha к изображению, используя черный цвет в качестве цвета. Затем вставьте изображение на другой цвет фона, чтобы произвести замену.

Между прочим, эта реализация использует модуль ImageMath в PIL. Это намного эффективнее, чем доступ к пикселям с помощью getdata.

РЕДАКТИРОВАТЬ: Вот полный код:

from PIL import Image, ImageMath

def difference1(source, color):
    """When source is bigger than color"""
    return (source - color) / (255.0 - color)

def difference2(source, color):
    """When color is bigger than source"""
    return (color - source) / color


def color_to_alpha(image, color=None):
    image = image.convert('RGBA')
    width, height = image.size

    color = map(float, color)
    img_bands = [band.convert("F") for band in image.split()]

    # Find the maximum difference rate between source and color. I had to use two
    # difference functions because ImageMath.eval only evaluates the expression
    # once.
    alpha = ImageMath.eval(
        """float(
            max(
                max(
                    max(
                        difference1(red_band, cred_band),
                        difference1(green_band, cgreen_band)
                    ),
                    difference1(blue_band, cblue_band)
                ),
                max(
                    max(
                        difference2(red_band, cred_band),
                        difference2(green_band, cgreen_band)
                    ),
                    difference2(blue_band, cblue_band)
                )
            )
        )""",
        difference1=difference1,
        difference2=difference2,
        red_band = img_bands[0],
        green_band = img_bands[1],
        blue_band = img_bands[2],
        cred_band = color[0],
        cgreen_band = color[1],
        cblue_band = color[2]
    )

    # Calculate the new image colors after the removal of the selected color
    new_bands = [
        ImageMath.eval(
            "convert((image - color) / alpha + color, 'L')",
            image = img_bands[i],
            color = color[i],
            alpha = alpha
        )
        for i in xrange(3)
    ]

    # Add the new alpha band
    new_bands.append(ImageMath.eval(
        "convert(alpha_band * alpha, 'L')",
        alpha = alpha,
        alpha_band = img_bands[3]
    ))

    return Image.merge('RGBA', new_bands)

image = color_to_alpha(image, (0, 0, 0, 255))
background = Image.new('RGB', image.size, (255, 255, 255))
background.paste(image.convert('RGB'), mask=image)
24
ответ дан 30 November 2019 в 15:28
поделиться

Если пиксели трудно идентифицировать, например, вы говорите (r <100 и g <100 и b <100) также не соответствует правильной черной области, это означает, что у вас много шума.

Лучше всего Чтобы идентифицировать область и заполнить ее желаемым цветом, вы можете идентифицировать область вручную или, возможно, с помощью обнаружения краев, например http://bitecode.co.uk/2008/07/edge-detection-in-python /

или более сложный подход заключается в использовании библиотеки наподобие opencv ( http://opencv.willowgarage.com/wiki/ ) для идентификации объектов.

4
ответ дан 30 November 2019 в 15:28
поделиться

Использование numpy и PIL:

Это загружает изображение в numpy-массив формы (W, H, 3) , где W - это ширина и H - высота. Третья ось массива представляет 3 цвета. каналы, R, G, B .

import Image
import numpy as np

orig_color = (255,255,255)
replacement_color = (0,0,0)
img = Image.open(filename).convert('RGB')
data = np.array(img)
data[(data == orig_color).all(axis = -1)] = replacement_color
img2 = Image.fromarray(data, mode='RGB')
img2.show()

Поскольку orig_color является кортежем длиной 3, а данные имеют форма (W, H, 3) , NumPy передает orig_color массиву формы (W, H, 3) для выполнения сравнения данных == orig_color . Результатом является логический массив формы (W, H, 3) .

(data == orig_color) .all (axis = -1) - это логический массив формы (W, H) , который имеет значение True везде, где цвет RGB в данных равен original_color .

14
ответ дан 30 November 2019 в 15:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: