numpy 如何在python中部分更改图像的颜色?

owfi6suc  于 2023-05-22  发布在  Python
关注(0)|答案(2)|浏览(169)

如何更改图像中给定索引的RGB值?这给了我一个空白的画面:

import numpy as np
from PIL import Image

target_image = Image.open("img.png")
target_image_array = np.array(target_image)
pixels = target_image_array.reshape(-1, 3)

skip_indices = np.arange(101_600, 254_000)

indices_to_grey_out = np.delete(pixels, skip_indices, 0)

pixels_greyed_out = pixels.copy()
pixels_greyed_out[indices_to_grey_out, [0, 1, 2]] = 0

pixels_greyed_out = pixels_greyed_out.reshape(target_image_array.shape)
modified_img = Image.fromarray(pixels_greyed_out)
modified_img.show()
q3aa0525

q3aa05251#

我不明白你到底想用扁平化和不连续的索引做什么,但是纯粹从你的评论来看,我理解你想影响图像中的一些特定颜色,所以我会尝试演示一下。
这是一个径向梯度图像,中心为rgb(20, 50, 140),边缘为rgb(40, 70, 160),所以我碰巧知道有4,884个(非线性相邻,如果有关系的话)像素值为rgb(25,55,145)

现在,让我们打开它并将其变成一个Numpy数组:

from PIL import Image
import numpy as np

# Open image and make into Numpy array
im = Image.open('a.png').convert('RGB')
na = np.array(im)

# Make Boolean (True/False) mask of interesting pixels
mask = np.all(na==[25,55,145], axis=-1)

# Briefly save the mask so we can see what it selects
Image.fromarray(mask).save('DEBUG-mask.png')

# Let's also count the number of pixels selected by the mask
print(np.count_nonzero(mask))       # prints 4,884

现在我们可以使用遮罩来改变所选的像素。让我们在原始图像中将遮罩像素设置为红色:

na[mask] = [255,0,0]
Image.fromarray(na).save('DEBUG-1.png')

现在使用蒙版的来影响未选中的像素。让我们把它们变成灰色:

na[~mask] = [128,128,128]
Image.fromarray(na).save('DEBUG-2.png')

如果要遮罩多个颜色,可以使用逻辑运算将遮罩组合在一起。所以,假设你想额外屏蔽颜色rgb(28,58,148),你可以在上面代码的末尾添加以下内容:

# Mask for second colour
mask2 = np.all(na==[28,58,148], axis=-1)

# Combine the two masks into new, bigger mask
both = mask | mask2

# Make masked pixels yellow and display
na[both] = [255,255,0]
Image.fromarray(na).show()

如果你想屏蔽一个颜色范围,我建议使用OpenCVinRange(),它可以让你设置R,G和B的下限和上限,然后选择中间的所有颜色。

import cv2

# Mask range 25>R>35, 55>G>65, 145<B<160
colRange = cv2.inRange(na,np.array([25,55,145]) ,np.array([35,65,160]))

# Make range of colours lime green
na[colRange>0] = [0,255,0]

如果有人好奇我是如何开始制作径向渐变的,我在终端中使用了ImageMagick和以下命令:

magick -size 500x500 radial-gradient:"rgb(20, 50, 140)-rgb(40, 70, 160)" -depth 8 a.png

一个更简单、更清晰的版本可能是:

magick -size 500x500 radial-gradient:lime-magenta -depth 8 a.png
ttygqcqt

ttygqcqt2#

如果你只想改变一个像素,你可以做以下的事情:

import numpy as np
from PIL import Image
from matplotlib import pyplot as plt

target_image = Image.open("/content/img.jpg")
target_image.putpixel((100, 200), (0, 0, 0))
print(target_image.getpixel((100, 200)))
plt.imshow(target_image)

如果你想改变图像的一个切片,最好先将其更改为numpy,然后按如下方式更改值:

import numpy as np
from PIL import Image
from matplotlib import pyplot as plt

img = Image.open("/content/img.jpg")
img = np.array(img)
img[100:200, 200:400] = 0
img = Image.fromarray(img)
plt.imshow(img)

相关问题