我正在尝试进行一些图像处理,为此我获得了一个 8 位灰度图像。我应该通过生成一个查找表来更改图像的对比度,该查找表增加 50 到 205 之间像素值的对比度。我使用以下 MATLAB 代码生成了一个查找表。
a = 2;
x = 0:255;
lut = 255 ./ (1+exp(-a*(x-127)/32));
当我绘图时lut
,我得到如下图:
到目前为止一切都很好,但是我该如何增加 50 到 205 之间像素值的对比度呢?变换映射的最终图应类似于:
我正在尝试进行一些图像处理,为此我获得了一个 8 位灰度图像。我应该通过生成一个查找表来更改图像的对比度,该查找表增加 50 到 205 之间像素值的对比度。我使用以下 MATLAB 代码生成了一个查找表。
a = 2;
x = 0:255;
lut = 255 ./ (1+exp(-a*(x-127)/32));
当我绘图时lut
,我得到如下图:
到目前为止一切都很好,但是我该如何增加 50 到 205 之间像素值的对比度呢?变换映射的最终图应类似于:
从您的评论来看,您只需要一个线性映射,其中强度< 50
映射到 0,强度> 205
映射到 255,其他一切都是介于两者之间的线性映射。您可以通过以下方式简单地做到这一点:
slope = 255 / (205 - 50); % // Generate equation of the line -
% // y = mx + b - Solve for m
intercept = -50*slope; %// Solve for b --> b = y - m*x, y = 0, x = 50
LUT = uint8(slope*(0:255) + intercept); %// Generate points
LUT(1:51) = 0; %// Anything < intensity 50 set to 0
LUT(206:end) = 255; %// Anything > intensity 205 set to 255
LUT 现在看起来像:
plot(0:255, LUT);
axis tight;
grid;
请注意我是如何在强度为< 50
和时截断强度的> 205
。MATLAB 从索引 1 开始索引,因此我们需要将强度偏移 1,以便它们正确映射到从 0 开始的像素强度。
要最终将其应用于您的图像,您所要做的就是:
out = LUT(img + 1);
这是假设这img
是您的输入图像。再次注意,+1
当 MATLAB 从位置 1 开始索引时,我们必须将输入偏移,而强度从 0 开始。
您可以通过使用轻松做到这一点imadjust
,它基本上在引擎盖下为您完成了这项工作。你这样称呼它:
outAdjust = imadjust(in, [low_in; high_in], [low_out; high_out]);
low_in
并high_in
表示图像中存在的最小和最大输入强度。请注意,这些是在 之间进行归一化的[0,1]
。 low_out
并high_out
调整图像的强度,以便low_in
映射到low_out
、high_in
映射到high_out
以及其他所有内容之间的对比度拉伸。对于你的情况,你会这样做:
outAdjust = imadjust(img, [0; 1], [50/255; 205/255]);
这应该拉伸对比度,使输入强度50
映射到输出强度0
,输入强度205
映射到输出强度255
。任何强度< 50
和分别> 205
自动饱和到0
和255
。
您需要获取图像中的每个像素并将其替换为查找表中的相应值。这可以通过一些嵌套for
循环来完成,但这不是最惯用的方式。我建议使用arrayfun
替换像素的函数。
new_image = arrayfun(@(pixel) lut(pixel), image);
lut
使用直接在图像上生成的代码可能更有效。如果性能是一个问题并且您不需要使用查找表,请尝试比较两种方法。
new_image = 255 ./ (1 + exp(-image * (x-127) / 32));
请注意,new_image
变量将不再是类型uint8
。如果您需要再次显示它(例如,使用imshow
),则需要通过写入将其转换回来uint8(new_image)
。