如何使用 ImageMath 正确计算波段数学?

How to properly calculate band math using ImageMath?

我想对 RGB 图像执行一些简单的波段数学运算。我希望输出为 green/(red+green+blue).

这是我尝试过的方法,但它会生成黑色图像:通过将原始 RGB 图像拆分为红色、绿色和蓝色来生成各个波段。

from PIL import Image, ImageMath
 
im = Image.open(r"SYFW0142.JPG")

im1 = Image.Image.split(im)
red = im1[0]
green = im1[1]
blue = im1[2]

out = ImageMath.eval("green/(red+green+blue)", red=red, green=green, blue=blue)

red 图片:

green 图片:

blue 图片:

out 图片:


编辑: 我意识到这个数学运算会产生 0 到 1 之间的值。但是,即使将方程乘以 255,我仍然得到一个黑色图像。 .

您自己已经注意到,您正在生成 [0.0 ... 1.0] 范围内的值。此外,查看三个通道,由于您的结果全是黑色,因此似乎每个像素都适用以下内容:

g / (r + g + b) < 0.5

所以,现在,您还没有显示编辑中提到的代码,即乘以 255,但我假设您做了这样的事情:

out = ImageMath.eval("green/(red+green+blue)*255", red=red, green=green, blue=blue)

不幸的是,在与 255 相乘之前,表达式 green/(red+green+blue) 仍然是完整计算的,因此每个像素(仍然)有 0 * 255 = 0。把乘法放在前面,像这样:

out = ImageMath.eval("255*green/(red+green+blue)", red=red, green=green, blue=blue)

这样做省事了,因为 all operations are done with 32-bit integers

这是一些代码片段:

from PIL import Image, ImageMath

im = Image.open('path/to/your/image.png')
red, green, blue = Image.Image.split(im)

# Original calculation #1 - wrong result
out = ImageMath.eval("green/(red+green+blue)", red=red, green=green, blue=blue)
print(out.getpixel((0, 0)))
# 0

# Original calculation #2 - still wrong result
out = ImageMath.eval("green/(red+green+blue)*255", red=red, green=green, blue=blue)
print(out.getpixel((0, 0)))
# 0

# Multiplication at the front - right result
out = ImageMath.eval("255*green/(red+green+blue)", red=red, green=green, blue=blue)
print(out.getpixel((0, 0)))
# 85
----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.19041-SP0
Python:        3.9.1
PyCharm:       2021.1.1
Pillow:        8.2.0
----------------------------------------