سؤال

أنا أحاول إزالة لون معين من الصورة ومع ذلك فإنه لا يعمل كما تمنيت.حاولت أن تفعل الشيء نفسه كما رأينا هنا باستخدام بيل لجعل كل بكسل بيضاء شفافة ؟ ومع ذلك فإن جودة الصورة قليلا الضياع لذلك يترك قليلا شبح الغريب بكسل الملونة حول أين ما تمت إزالته.حاولت أن تفعل شيئا مثل تغيير بكسل إذا كان كل ثلاث قيم هي أقل من 100 ولكن لأن الصورة كانت رديئة الجودة البيكسلات المحيطة لم تكن حتى الأسود.

لا أحد يعرف من طريقة أفضل مع بيل في بيثون لاستبدال لون و أي شيء المحيطة به ؟ وربما هذا هو فقط متأكد النار طريقة يمكن إزالة الكائنات تماما ومع ذلك لا أستطيع التفكير في وسيلة للقيام بذلك.

صورة خلفية بيضاء و نص الأسود.دعنا نقول فقط أريد أن إزالة النص تماما من الصورة دون ترك أي القطع الأثرية خلف.

حقا نقدر مساعدة شخص ما!شكرا

هل كانت مفيدة؟

المحلول

وستحتاج لتمثيل الصورة كما مجموعة 2 الأبعاد. وهذا يعني إما وضع قائمة من قوائم بكسل، أو عرض مجموعة 1 الأبعاد باعتبارها واحدة 2D مع بعض الرياضيات ذكية. ثم، لكل بكسل هي المستهدفة، ستحتاج إلى العثور على كل بكسل المحيطة بها. هل يمكن أن تفعل هذا مع مولد الثعبان على النحو التالي:

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

نصائح أخرى

أفضل طريقة للقيام بذلك هو استخدام "لون ألفا" الخوارزمية المستخدمة في Gimp لاستبدال اللون.أنه سوف يعمل تماما في حالتك.أنا ل reimplemented هذه الخوارزمية باستخدام بيل مفتوحة المصدر بيثون صورة المعالج phatch.يمكنك العثور على التنفيذ الكامل هنا.هذا محض بيل تنفيذ وأنه لا يجب الأخرى الإعتماد.يمكنك نسخ رمز وظيفة واستخدامها.هنا عينة باستخدام 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)

وعن طريق نمباي وPIL:

وهذا تحميل الصورة إلى مجموعة نمباي الشكل (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 هو الصفوف (tuple) بطول 3، وdata له تشكيل (W,H,3)، نمباي البث orig_color إلى مجموعة من شكل (W,H,3) لأداء data == orig_color المقارنة. النتيجة في مجموعة منطقية من شكل (W,H,3).

و(data == orig_color).all(axis = -1) هو مجموعة منطقية من شكل (W,H) التي غير صحيح أينما لون RGB في data هو original_color.

#!/usr/bin/python
from PIL import Image
import sys

img = Image.open(sys.argv[1])
img = img.convert("RGBA")

pixdata = img.load()

# Clean the background noise, if color != white, then set to black.
# change with your color
for y in xrange(img.size[1]):
    for x in xrange(img.size[0]):
        if pixdata[x, y] == (255, 255, 255, 255):
            pixdata[x, y] = (0, 0, 0, 255)

إذا بكسل هي لا يسهل التعرف عليها منها مثلا تقول (ص <100 و ز <100 و ب <100) أيضا لا يتطابق بشكل صحيح المنطقة السوداء، فهذا يعني أنك لديك الكثير من الضوضاء.

وأفضل طريقة ستكون للتعرف على المنطقة وملء مع اللون الذي تريده، يمكنك تحديد المنطقة يدويا أو قد تكون من خلال الكشف عن حافة مثلا http://bitecode.co.uk/2008/07/edge -detection في والثعبان /

وأو أكثر تطورا النهج من شأنه أن يكون لاستخدام مكتبة مثل مكتبة برمجية مفتوحة للرؤية الحاسوبية ( http://opencv.willowgarage.com/ ويكي / ) لتحديد الكائنات.

وهذا هو جزء من قانون بلدي، فإن النتيجة مثل:

الهدف

import os
import struct
from PIL import Image
def changePNGColor(sourceFile, fromRgb, toRgb, deltaRank = 10):
    fromRgb = fromRgb.replace('#', '')
    toRgb = toRgb.replace('#', '')

    fromColor = struct.unpack('BBB', bytes.fromhex(fromRgb))
    toColor = struct.unpack('BBB', bytes.fromhex(toRgb))

    img = Image.open(sourceFile)
    img = img.convert("RGBA")
    pixdata = img.load()

    for x in range(0, img.size[0]):
        for y in range(0, img.size[1]):
            rdelta = pixdata[x, y][0] - fromColor[0]
            gdelta = pixdata[x, y][0] - fromColor[0]
            bdelta = pixdata[x, y][0] - fromColor[0]
            if abs(rdelta) <= deltaRank and abs(gdelta) <= deltaRank and abs(bdelta) <= deltaRank:
                pixdata[x, y] = (toColor[0] + rdelta, toColor[1] + gdelta, toColor[2] + bdelta, pixdata[x, y][3])

    img.save(os.path.dirname(sourceFile) + os.sep + "changeColor" + os.path.splitext(sourceFile)[1])

if __name__ == '__main__':
    changePNGColor("./ok_1.png", "#000000", "#ff0000")
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top