【发布时间】:2020-01-02 02:16:51
【问题描述】:
我正在制作一个程序,您可以在其中选择图像和颜色,它只会反转与该颜色匹配的像素。我一直在浏览 stackoverflow 和 reddit 以寻求解决方案,但到目前为止还没有运气。
我首先尝试做这样的事情:
img = Image.open('past.png')
pixels = img.load()
for i in goodpixels:
ImageOps.invert(pixels[i])
AttributeError: 'tuple' 对象没有属性 'mode'
不走运,因为 ImageOps.invert 只反转完整图像。接下来我尝试使用 ImageOps.polarize 但意识到我不能使用它,因为它需要灰度阈值而不是 rgb 值。
img = Image.open('past.png')
pixels = img.load()
for i in goodpixels:
ImageOps.solarize(img, threshold=pixels[i])
TypeError: '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()
编辑:我想通了!感谢 Mark Setchell 令人难以置信的大脑!我最终使用 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 方法看起来像这样:
result = np.where((pastarray==[0, 0, 0]).all(axis=-1)[...,None], inverse, pastarray)
这引发了错误:AttributeError: 'bool' object has no attribute 'all'
事实证明,我所要做的就是将我的颜色转换为数组!
【问题讨论】:
-
Numpy 只需要几行代码,这是您应该对图像使用的,因为它有很多算法并且速度非常快。因此,将您的 PIL Image 转换为 Numpy 数组制作整个内容的副本并将其全部反转。然后使用
np.where()来选择,对于每个像素位置是使用原始图像还是倒置图像。 -
@MarkSetchell 谢谢!我会研究 numpy。
-
看起来应该差不多...stackoverflow.com/a/59322460/2836621
-
抱歉,我没有靠近电脑,无法提供更详细的帮助。如果你知道如何去做,你可以把它写下来作为其他人使用的答案,并接受它是正确的,并获得积分。祝你好运!如果遇到困难就回来 - 问题是免费的????
-
继续努力!如果您有一些新代码,请点击您的问题下方的
edit并添加!
标签: python python-3.x python-imaging-library