Image 如何更改RGB图像的动态范围?

Image 如何更改RGB图像的动态范围?,image,matlab,rgb,Image,Matlab,Rgb,我有16位原始图像(12个有效位)。我将其转换为rgb,现在我想更改动态范围。我创建了2个映射函数。您可以在下面看到它们。如您所见,第一个函数将值0-500映射到0-100,第二个函数将其余值映射到101-255 现在我想在rgb图像上应用贴图函数。我所做的是迭代每个像素,为每个通道找到合适的函数,并在通道上应用它。例如,像素为RGB=[100 2000 4000]。在R通道上,我将应用第一个函数,因为100在0-500范围内。但是,在G和B通道上,我将应用第二个函数,因为它们的值在501-4

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

现在我想在rgb图像上应用贴图函数。我所做的是迭代每个像素,为每个通道找到合适的函数,并在通道上应用它。例如,像素为RGB=[100 2000 4000]。在R通道上,我将应用第一个函数,因为100在0-500范围内。但是,在G和B通道上,我将应用第二个函数,因为它们的值在501-4095中

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


你能建议怎么做,或者至少给我一个方向,或者给我看一些文章吗?

你正在做的是一个非常简单的成像操作,通常应用于图像和视频处理。有时它(不精确地)被称为查找表(LUT),即使它并不总是通过实际的查找表实现。例如伽马调整或日志编码

例如,这种编码的一个例子是sRGB,它是线性光的伽马编码。您可以在此处阅读:。你会看到它有一个非线性调整

LUT这个名字意味着一种很好的方法。如果可以将图像设置为uint8或uint16值集,则可以为任何输入值创建所需输出值的向量。查找表的元素数与变量类型的可能范围相同。如果您使用的是uint8,那么将有一个256个值的查找表。这样查找就很容易了,只需将图像值用作LUT的索引,即可获得结果值。这种计算效率是LUT得到如此广泛应用的原因

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

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

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

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

这就是你在问题中描述的分段计算

您可以通过以下方式制作新图像:

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

请注意,因为MATLAB使用双精度索引(基于一个双精度索引),所以需要正确地转换并添加一个双精度索引。这并不像你想象的那么慢;MATLAB就是这样做的。我已经使用MATLAB几十年了,这对我来说仍然很奇怪

这种方法可以让您对LUT创建(日志、exp等)产生兴趣,而且它仍然运行得非常快

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

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);

同样,我们通过一个简单的索引应用LUT:

convertedimage = lutgamma(min(double(someimage)+1, end));
我们得到以下图像:

使用平滑LUT通常会提高整体图像质量。分段线性LUT将导致结果图像在着色区域中具有奇数不连续性


这些在许多成像系统中非常常见,因此LUT具有文件格式。要明白我的意思,请看一家大型相机公司的这张照片。LUT是一个大问题,看起来你的思路是正确的。

我想你指的是Photoshop称之为“增强单色对比度”的东西,如图所示-请看“第3步:尝试不同的算法”

基本上,我认为您可以在所有通道中找到一个单个最小值,并在所有3个通道中找到一个单个最大值,并对所有通道应用相同的缩放,而不是使用各自的最小值和最大值单独执行每个通道


或者,您可以转换到Lab(亮度加
a
b
)模式,并将您的功能应用到亮度通道(不影响保存颜色信息的
a
b
通道),然后转换回RGB,您的颜色不受影响。

我认为这被称为a。我的第一个想法是,最好使用RGB或替代RGB。我有两个问题:1-什么是
79.5326
number?2-即使在该解决方案中,每个通道也将应用不同的功能。假设rgbPxl=[5020003000]。第一个功能将应用于红色通道,第二个功能将应用于绿色和蓝色通道,不是吗?因此,我们将更改实际颜色。我在理解中是否遗漏了什么?我说的对吗?即使在你的方法中,两个不同的函数也将应用于每个通道?常数
79.5326
只是分段线性函数第二部分的线性偏移值。它是根据
101-501*(255-101)/(4095-501)
计算的。所示示例将相同的LUT应用于每个通道,这是RGB空间中保持颜色所需的。如果我们想对每个通道应用不同的函数,我们需要专门独立地对每个颜色通道进行索引,比如“convertedimage(:,:,1)=lut(double(someimage(:,:,1))+1;”对于红色通道等,我了解每个通道使用相同的LUT。但是,我看到的是:第一条曲线
convertedimage = lutgamma(min(double(someimage)+1, end));