image - 如何改变RGB图像的动态范围?

标签 image matlab rgb

我有 16 位原始图像(12 个有效位)。我将其转换为 RGB,现在我想更改动态范围。我创建了 2 个 map 函数。您可以在下面看到它们的可视化。正如您所看到的,第一个函数将值 0-500 映射到 0-100,第二个函数将其余值映射到 101-255。

enter image description here

现在我想在 RGB 图像上应用映射函数。我正在做的是迭代每个像素,为每个 channel 找到适当的函数并将其应用到 channel 上。例如,像素为RGB=[100 2000 4000]。在 R channel 上,我将应用第一个函数,因为 100 在 0-500 范围内。但是,在 G 和 B channel 上,我将应用第二个函数,因为它们的值在 501-4095 之间。

但是,通过这种方式,我实际上改变了像素的实际颜色,因为我在像素的 channel 上应用了不同的函数。

你能建议如何做,或者至少给我一个方向或展示一些文章吗?

最佳答案

您正在做的是非常简单的成像操作,经常应用于图像和视频处理。有时它(不准确地)被称为查找表 (LUT),尽管它并不总是通过实际的查找表来实现。这方面的例子有 Gamma 调整或对数编码。

例如,这种编码的一个例子是 sRGB,它是线性光的 Gamma 编码。您可以在这里阅读:http://en.wikipedia.org/wiki/SRGB 。您会看到它具有非线性调整。

LUT 这个名字暗示了一种很好的实现方法。如果您可以将图像设为 uint8 或 uint16 值集,则可以为任何输入值创建所需输出值的向量。查找表具有与变量类型的可能范围相同数量的元素。如果您使用 uint8,您将拥有一个包含 256 个值的查找表。然后查找就很容易了,您只需使用图像值作为 LUT 的索引即可获取结果值。计算效率是 LUTS 如此广泛使用的原因。

就您而言,由于您在 RGB 空间中工作,因此可以以完全相同的方式将曲线应用于三个颜色 channel 中的每一个。由于这个原因,RGB 空间很不错。然而,由于各种原因,有时每个 channel 实现不同的 LUT。

因此,如果您有一张图像(我们将使用 MATLAB 中包含的图像,并通过缩放来假装它是 12 位):

someimage = uint16(imread('autumn.tif')).*16;
image(someimage.*16); % Need to multiply again to display 16 bit data scaled properly

Original image

对于您的 LUT,您可以将其实现为:

lut = uint8([(0:500).*(1/5), (501:4095).*((255-101)/(4095-501)) + 79.5326]);
plot(lut);  %Take a look at the lut

Plot of the LUT

这将进行您在问题中描述的分段计算。

您可以这样制作新图像:

convertedimage = lut(double(someimage)+1);
image(convertedimage);

enter image description here

请注意,由于 MATLAB 使用 double 索引(基于 1),因此您需要正确转换并加 1。这并不像你想象的那样减慢速度。 MATLAB 就是为此而生的。我已经使用 MATLAB 几十年了,但这对我来说仍然很奇怪。

此方法可让您喜欢 LUT 创建(日志、exp 等),并且运行速度仍然非常快。

在您的情况下,您的 LUT 仅需要 4096 个元素,因为您的输入数据只有 12 位。您可能需要小心边界,因为 uint16 可能具有更高的值。一种简洁的绑定(bind)方法是使用 minend 函数:

convertedimage = lut(min(double(someimage)+1, end));

现在,这已经实现了您的功能,但也许您想要一个稍微不同的功能。例如,这种类型的常见功能是简单的 Gamma 调整。 Gamma 值为 2.2 意味着输入图像值将按 1/2.2 次方缩放(如果在 0 和 1 之间缩放)。我们可以按如下方式创建这样的 LUT:

lutgamma = uint8(256.*(((0:4095)./4095).^(1/2.2)));
plot(lutgamma);

Plot of a gamma LUT

我们再次通过简单的索引应用 LUT:

convertedimage = lutgamma(min(double(someimage)+1, end));

我们得到以下图像:

enter image description here

使用平滑的 LUT 通常会提高整体图像质量。分段线性 LUT 往往会导致生成的图像在阴影区域出现奇怪的不连续性。

这些在许多成像系统中非常常见,因此 LUT 具有文件格式。要明白我的意思,请看这个 LUT generator来自一家大型相机公司。 LUT 很重要,看起来您的方向是正确的。

关于image - 如何改变RGB图像的动态范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29979689/

相关文章:

java - 在 v2 map 上绘制不同颜色的折线

c# - 如何将一组颜色 'shades' 替换为另一组颜色

java - 单击 JButton 时显示图像

html - 当父 div 为百分比时保持图像比例

visual-studio - 为 TLD 运行 compile.m 时出错

matlab - 如何绘制带有文本标签的饼图?

javascript - 如何使用roslibjs和sensor_msgs/Image类型的主题来显示图像

matlab:具有大量数据点的散点图

algorithm - 可见光谱的RGB值

rgb - Arduino RGB LED 清除