如何将变换应用于 VIPS/Python 中的特定色调范围
How to apply a transformation to a certain tonal range in VIPS/Python
我必须对 VIPS(和 Python)中 16 位 tiff 文件的不同色调范围应用各种转换。我已经设法做到了,但我是 VIPS 的新手,我不相信我这样做是有效的。这些图片每张都有几百兆字节,削减每个多余的步骤可以为我节省每张图片几秒钟的时间。
我想知道是否有更有效的方法来实现我从下面的代码中获得的相同结果,例如使用查找表(我无法真正弄清楚它们在 VIPS 中是如何工作的)。代码将红色通道中的阴影分开,并通过转换传递它们。
im = Vips.Image.new_from_file("test.tiff")
# Separate the red channel
band = im[0]
# Find the tone limit for the bottom 5%
lim = band.percent(5)
# Create a mask using the tone limit
mask = (band <= lim)
# Convert the mask to 16 bits
mask = mask.cast(band.BandFmt, shift = True)
# Run the transformation on the image and keep only the shadow areas
new_shadows = (65535 * (shadows / lim * 0.1)) & mask
在 运行 每个色调范围(高光、阴影、中间调)或多或少相似的代码之后,我将所有生成的图像加在一起以重建原始波段:
new_band = (new_shadows.add(new_highlights).add(new_midtones)).cast(band.BandFmt)
我为您制作了一个演示程序,展示了如何使用 vips 直方图函数执行此类操作:
import sys
import pyvips
im = pyvips.Image.new_from_file(sys.argv[1])
# find the image histogram
#
# we'll get a uint image, one pixel high and 256 or
# 65536 pixels across, it'll have three bands for an RGB image source
hist = im.hist_find()
# find the normalised cumulative histogram
#
# for a 16-bit source, we'll have 65535 as the right-most element in each band
norm = hist.hist_cum().hist_norm()
# search from the left for the first pixel > 5%: the position of this pixel
# will give us the pixel value that 5% of pixels fall below
#
# .profile() gives back a pair of [column-profile, row-profile], we want index 1
# one. .getpoint() reads out a pixel as a Python array, so for an RGB Image
# we'll have something like [19.0, 16.0, 15.0] in shadows
shadows = (norm > 5.0 / 100.0 * norm.width).profile()[1].getpoint(0, 0)
# Now make an identity LUT that matches our original image
lut = pyvips.Image.identity(bands=im.bands,
ushort=(im.format == "ushort"))
# do something to the shadows ... here we just brighten them a lot
lut = (lut < shadows).ifthenelse(lut * 100, lut)
# make sure our lut is back in the original format, then map the image through
# it
im = im.maplut(lut.cast(im.format))
im.write_to_file(sys.argv[2])
它对源图像进行一次查找直方图操作,然后进行一次映射直方图操作,所以速度应该很快。
这只是调整阴影,您需要稍微扩展它以同时处理中间调和高光,但您可以从单个初始直方图进行所有三项修改,因此应该不会慢。
如果您还有其他问题,请在 libvips 跟踪器上提出问题:
我必须对 VIPS(和 Python)中 16 位 tiff 文件的不同色调范围应用各种转换。我已经设法做到了,但我是 VIPS 的新手,我不相信我这样做是有效的。这些图片每张都有几百兆字节,削减每个多余的步骤可以为我节省每张图片几秒钟的时间。
我想知道是否有更有效的方法来实现我从下面的代码中获得的相同结果,例如使用查找表(我无法真正弄清楚它们在 VIPS 中是如何工作的)。代码将红色通道中的阴影分开,并通过转换传递它们。
im = Vips.Image.new_from_file("test.tiff")
# Separate the red channel
band = im[0]
# Find the tone limit for the bottom 5%
lim = band.percent(5)
# Create a mask using the tone limit
mask = (band <= lim)
# Convert the mask to 16 bits
mask = mask.cast(band.BandFmt, shift = True)
# Run the transformation on the image and keep only the shadow areas
new_shadows = (65535 * (shadows / lim * 0.1)) & mask
在 运行 每个色调范围(高光、阴影、中间调)或多或少相似的代码之后,我将所有生成的图像加在一起以重建原始波段:
new_band = (new_shadows.add(new_highlights).add(new_midtones)).cast(band.BandFmt)
我为您制作了一个演示程序,展示了如何使用 vips 直方图函数执行此类操作:
import sys
import pyvips
im = pyvips.Image.new_from_file(sys.argv[1])
# find the image histogram
#
# we'll get a uint image, one pixel high and 256 or
# 65536 pixels across, it'll have three bands for an RGB image source
hist = im.hist_find()
# find the normalised cumulative histogram
#
# for a 16-bit source, we'll have 65535 as the right-most element in each band
norm = hist.hist_cum().hist_norm()
# search from the left for the first pixel > 5%: the position of this pixel
# will give us the pixel value that 5% of pixels fall below
#
# .profile() gives back a pair of [column-profile, row-profile], we want index 1
# one. .getpoint() reads out a pixel as a Python array, so for an RGB Image
# we'll have something like [19.0, 16.0, 15.0] in shadows
shadows = (norm > 5.0 / 100.0 * norm.width).profile()[1].getpoint(0, 0)
# Now make an identity LUT that matches our original image
lut = pyvips.Image.identity(bands=im.bands,
ushort=(im.format == "ushort"))
# do something to the shadows ... here we just brighten them a lot
lut = (lut < shadows).ifthenelse(lut * 100, lut)
# make sure our lut is back in the original format, then map the image through
# it
im = im.maplut(lut.cast(im.format))
im.write_to_file(sys.argv[2])
它对源图像进行一次查找直方图操作,然后进行一次映射直方图操作,所以速度应该很快。
这只是调整阴影,您需要稍微扩展它以同时处理中间调和高光,但您可以从单个初始直方图进行所有三项修改,因此应该不会慢。
如果您还有其他问题,请在 libvips 跟踪器上提出问题: