python - 有没有办法用 Pillow 仅反转特定像素?

标签 python python-3.x python-imaging-library

我正在制作一个程序,您可以在其中选择图像和颜色,它只会反转与该颜色匹配的像素。我一直在 stackoverflow 和 reddit 上寻找解决方案,但到目前为止还没有运气。

我首先尝试做这样的事情:

img = Image.open('past.png')
pixels = img.load()
for i in goodpixels:
    ImageOps.invert(pixels[i])

属性错误:“元组”对象没有属性“模式”

运气不好,因为 ImageOps.invert 只反转完整图像。接下来我尝试使用 ImageOps.polarize 但意识到我无法使用它,因为它需要灰度阈值而不是 rgb 值。

img = Image.open('past.png')
pixels = img.load()
for i in goodpixels:
    ImageOps.solarize(img, threshold=pixels[i])

类型错误:“int”和“tuple”实例之间不支持“<”

这是我的问题,我不知道这是否可能。如果需要太多工作,我可能会放弃该项目,因为我只是让自己忙碌起来,而这不是为了分数/工作。

更多代码:

def checkpixels():
    img = Image.open('past.png')
    height, width = img.size
    img = img.convert('RGB')
    targetcolor = input('What color do you want to search for, you can use RGB format or common names like \'red\', \'black\', e.t.c. Leave this blank to invert all pixels. ')
    print('Processing image. This could take several minutes.')
    isrgb = re.match(r'\d+, \d+, \d+|\(\d+, \d+, \d+\)', targetcolor)
    if type(isrgb) == re.Match:
        targetcolor = targetcolor.strip('()')
        targetcolor = targetcolor.split(', ')
        targetcolor = tuple(map(int, targetcolor))
        print(str(targetcolor))
        for x in range(width):
            for y in range(height):
                color = img.getpixel((y-1, x-1))
                if color == targetcolor:
                    goodpixels.append((y-1, x-1))
    else:
        try:
            targetcolor = ImageColor.getcolor(targetcolor.lower(), 'RGB')
            print(targetcolor)
            for x in range(width):
                for y in range(height):
                    color = img.getpixel((y-1, x-1))
                    if color == targetcolor:
                        goodpixels.append((y-1, x-1))
        except:
            print('Not a valid color smh.')

    return goodpixels
goodpixels = []
goodpixels = checkpixels()

编辑:我明白了!感谢马克·塞切尔令人难以置信的大脑!我最终使用 numpy 将图像和目标颜色转换为数组,制作图像的反转副本,并使用 numpy.where() 来决定是否切换像素。我还计划将目标颜色设置为一个范围,这样所选的颜色就不必那么具体。总而言之,我的代码如下所示:

goodpixels = []
targetcolor = inputcolor()
img = Image.open('past.png')
invertimage = img.copy().convert('RGB')
invertimage = ImageOps.invert(invertimage)
invertimage.save('invert.png')
pastarray = np.array(img)
targetcolorarray = np.array(targetcolor)
pixels = img.load()
inverse = np.array(invertimage)
result = np.where((pastarray==targetcolorarray).all(axis=-1)[...,None], inverse, pastarray)
Image.fromarray(result.astype(np.uint8)).save('result.png')

当然,inputcolor()是一个离屏函数,它只是决定输入是颜色名称还是rgb值。在此示例中我还使用了 import numpy as np

我遇到的一个问题是我原来的 .where 方法看起来像这样:

结果 = np.where((pastarray==[0, 0, 0]).all(axis=-1)[...,None], inverse, Pastarray)

这引发了错误:AttributeError: 'bool' object has no attribute 'all' 事实证明我所要做的就是将颜色转换为数组!

最佳答案

许多库允许您将图像作为 numpy 数组导入到 Python 中。 PILopencv2 是用于处理图像的有据可查的库:

pip 安装 opencv2

示例 numpy.where() 选择,满足设定的条件,在本例中反转低于 THRESHOLD 的所有像素值:

import cv2
import numpy as np
import matplotlib.pyplot as plt

# cut off thereshold
THRESHOLD = 230

pixel_data = cv2.imread('filename.png')
pixel_data = np.where(pixel_data < THRESHOLD, 1/pixel_data, pixel_data)

# display the edited image using matplotlib
plt.imshow(pixel_data)

numpy.where() 函数将条件应用于 numpy 数组。更多详细信息请访问:numpy official documentation

关于python - 有没有办法用 Pillow 仅反转特定像素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59548103/

相关文章:

python - 如何编写与使用它的类具有相同导入的装饰器?

python - SMOTE后保留pandas数据帧结构,在python中过采样

python - 是否可以从 Python Boto 同步调用 AWS Lambda 函数?

python - 使用 Python Pillow 的镜头模糊效果

python - 哪种算法可以合理地减少多个列表? ("who killed who"问题)

python - 如何限制用户输入?

django - 从 Django 模板语言生成动态 HTML 表格

python - Python 中缺少数据点

python - PIL.ImageChops.subtract 和首先转换为 numpy 数组然后减去它们之间有什么区别?

python 图像识别