gpt4 book ai didi

python - 使用 PIL,我可以以可定制的方式组合两个(或更多)波段吗?

转载 作者:行者123 更新时间:2023-12-05 09:27:26 27 4
gpt4 key购买 nike

我想“分解”一个图像(即split()),通过与另一个 channel 相结合来修改其中一个 channel 并重新“组合”(即 merge())它们。

这个例子应该通过使用我希望存在的特征将它们映射到红色 channel 来突出显示边缘:

from PIL import Image, ImageFilter
base = Image.open("example.jpg")
base.show()

base image

edges = (base
.convert("L")
.filter(ImageFilter.Kernel((3, 3), (-1, -1, -1, -1, 8,-1, -1, -1, -1), 1, 0))
.point(lambda p: 255 if p > 10 else 0))
edges.show()

edges

r, g, b = base.split()

# now I want the blue channel/band for each pixel to be whatever respective
# pixel is brighter on a given set of bands

# this is what I want to do, but `combine()` does not exist
b_with_edges = Image.combine((r, edges), lambda pixels: max(pixels))
# instead - for the example I'm dropping blue and take just the edges
b_with_edges = edges

new_image = Image.merge("RGB", (r, g, b_with_edges))
new_image.show()

combined image with edge highlighting

当然我可以手动遍历所有像素并手动组合它们。从我从 PIL 中看到的情况来看,它似乎是一个非常发达且灵活的库,所以我希望有一些内置的方式..

更新:

由于 CrazyChucky 的回答对于这个用例非常有效,我敢于添加一个提炼版本:

from PIL import Image, ImageFilter, ImageChops
base = Image.open("example.jpg").reduce(1)
r, g, b = base.split()
edges = (base
.convert("L")
.filter(ImageFilter.Kernel((3, 3), (-1, -1, -1, -1, 8,-1, -1, -1, -1), 1, 0))
.point(lambda p: 255 if p > 10 else 0))
image_with_edge_highlighting = Image.merge("RGB", (r, g, ImageChops.lighter(b, edges)))
image_with_edge_highlighting.show()

最佳答案

您在这种特殊情况下描述的内容听起来像 ImageChops.lighter :

from PIL import ImageChops

b_with_edges = ImageChops.lighter(r, edges)

它使用两个给定图像中较亮(具有较高值)的像素生成新图像。

按照您的代码合并后,我得到以下结果:

Output image

就是说...虽然 ImageChops 模块有很多有用的功能,但我不知道有一个更通用、可定制的功能可以接受您描述的可调用。这样的函数,如果存在的话,可能会有用,但可能不会很高效。它本质上是一个围绕 for 循环的包装器,在 Python 级别而不是 C 级别进行迭代——很像 Pandas 的 apply方法。

( point ,你已经在你的问题中证明了,是我所知道的最接近的东西......但当然它只对单个图像进行操作,使用查找表。)

你可以这样实现,直接通过PixelAccess访问和设置像素每个图像的 load 返回的类方法:

def custom_image_combine(images, fn):
width, height = images[0].size
return_image = Image.new(images[0].mode, (width, height))
return_image_access = return_image.load()
accessors = [image.load() for image in images]
for x in range(width):
for y in range(height):
return_image_access[x, y] = fn(
accessor[x, y] for accessor in accessors
)
return return_image

b_with_edges = custom_image_combine((r, edges), max)

请注意,您可以简单地提供 max,而不是使用它的 lambda

关于python - 使用 PIL,我可以以可定制的方式组合两个(或更多)波段吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72433307/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com