我一直试图在OpenCV python上学习一些图像处理。我有一个16位的图像,我想在这个16位图像上应用LUT转换,而不把它减少到8位。从文档中,我看到OpenCV中的LUT函数只适用于8位图像.有人知道一个有效的方法来使用这个功能的16位图像吗?
我对8位图像使用LUT转换。它们正常工作,但是对于16位图像,抛出的错误是:error: (-215:Assertion failed) (lutcn == cn || lutcn == 1) && \_lut.total() == 256 && \_lut.isContinuous() && (depth == CV_8U || depth == CV_8S) in function 'cv::LUT'
。
后来,我发现这是因为LUT函数仅适用于8位图像.
发布于 2022-04-04 17:03:54
正如您已经发现的,OpenCV的LUT方法的实现只支持8位LUTs。但是,您可以实现自己的任意位分辨率,这实际上非常简单。对于映像中的每个值,直接用于访问LUT,它将输出所需的值。因为OpenCV与NumPy接口,所以您可以直接将输入图像和索引使用到LUT中,以便获得最终的输出,同时利用NumPy数组索引。
首先定义一个LUT -你需要确保它是16位,我假设你有从0到65535的值来尊重16位分辨率。一旦您这样做,使用表索引到您的图像。下面是一个使用伽马调整的例子:
import numpy as np
def adjust_gamma(image, gamma=1.0):
# build a lookup table mapping the pixel values [0, 65535] to
# their adjusted gamma values
inv_gamma = 1.0 / gamma
table = ((np.arange(0, 65536) / 65535) ** inv_gamma) * 65535
# Ensure table is 16-bit
table = table.astype(np.uint16)
# Now just index into this with the intensities to get the output
return table[image]
这应用了输入图像的逆伽玛调整,首先生成一个16位的LUT,然后用图像直接索引到其中创建输出图像。注意,输入图像也被假定为16位.如果有任何超出0-65535范围的值,这将给出一个超出范围的索引错误。
注-多通道图像
请注意,上述情况假设为单通道映像。如果您想应用于多通道(即RGB图像),那么您需要为每个通道定义一个LUT,并将LUT分别应用于每个通道。最简单的方法是在所有通道上设置一个for
循环。肯定有更多的矢量法在一次尝试,但我不会偏离你的问题的意图,我希望这是尽可能简单的阅读。
首先定义一个2D LUT,其中这个矩阵中的每一行都是一个LUT。具体来说,行i
对应于适用于图像的信道i
的LUT。完成后,循环通过通道维度并应用LUT。为了节省一些时间,我们还可以预先分配输出图像,使其为零,然后相应地填写每个通道。
类似于:
# Assume LUT is defined as `table` and it's a 2D NumPy array
output = np.zeros_like(image)
for i in range(image.shape[2]):
output[..., i] = table[i, image[..., i]]
output
将包含所需的结果。但是,对于特殊情况下,LUT跨所有通道都是相同的,您可以只使用以前使用的相同的1DLUT,也可以使用我前面提到的相同的索引方法:
output = table[image]
https://stackoverflow.com/questions/71734861
复制相似问题