【问题标题】:Increase image contrast using look up table in MATLAB在 MATLAB 中使用查找表增加图像对比度
【发布时间】:2014-10-01 05:00:20
【问题描述】:

我正在尝试进行一些图像处理,为此我获得了 8 位灰度图像。我应该通过生成一个查找表来更改图像的对比度,该表可以增加 50 到 205 之间像素值的对比度。我使用以下 MATLAB 代码生成了一个查找表。

a = 2;
x = 0:255;
lut = 255 ./ (1+exp(-a*(x-127)/32));

当我绘制lut 时,我得到如下图:

到目前为止一切都很好,但是我该如何提高 50 到 205 之间像素值的对比度?变换映射的最终图应该是这样的:

【问题讨论】:

  • 为每个像素强度 (x) 分配 y 中的值。因此,例如,值为 50 的像素分配了 255./(1+exp(-2*(50-127)/32)) ~0 的值,为 205 的像素分配了 255./(1+exp (-2*(205-127)/32)) ~255
  • Y = lut(x+1) 是新值
  • @ASantosRibeiro,谢谢。此外,当我增加“a”的值(当前为 2)时,我看到图像变得更亮。你能告诉我这是为什么吗?或者'a'应该是一个永远不能改变的固定值?
  • @DavidNorman - a 控制曲线的变化率。当a 增加时,变化率增加,这意味着等式中的exp 部分将更快地趋向于零。通过取其倒数,当a 更大而不是更小时,随着强度的增加,您将更快地获得更高的值。因此,a -> infty 对比度变得更高。

标签: image matlab image-processing lookup contrast


【解决方案1】:

从您的 cmets 来看,您只需要一个 linear 映射,其中 < 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;

注意我是如何截断强度为&lt; 50&gt; 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_inhigh_in 表示图像中存在的最小和最大输入强度。请注意,这些在[0,1] 之间进行了标准化。 low_outhigh_out 调整图像的强度,使 low_in 映射到 low_outhigh_in 映射到 high_out,其他所有内容都在两者之间进行对比。对于你的情况,你会这样做:

outAdjust = imadjust(img, [0; 1], [50/255; 205/255]);

这应该拉伸对比度,使得输入强度 50 映射到输出强度 0 并且输入强度 205 映射到输出强度 255。任何强度 &lt; 50&gt; 205 会自动分别饱和到 0255

【讨论】:

  • 感谢您的回答。当我在 50 和 205 之间绘制这个新的值变换时,我应该看到一个斜坡,它在 x 轴上从 0:50 保持在 0 并且在 x 轴上 255 处线性增加到 205?我在我的问题中添加了一张坡道图片
  • @DavidNorman 哦...那么您想要一个 线性 斜坡,还是像您提供的图像那样的指数斜坡?如果你想要一个线性斜坡,你所要做的就是outAdjust = imadjust(in, [0; 1], [50/255; 205/255]);。这完全改变了我的答案。我会修改我的帖子。
  • 抱歉误导,指数图是为了显示我在生成查找表时得到的结果。我还应该补充一点,我不允许使用 matlab 函数。我们必须学会制作自己的功能,这是我目前正在努力的地方。我不理解“映射”、强度和其他东西的整个概念
  • 是的,这个练习的重点是了解这种线性渐变如何使图片更令人愉悦并出现更多细节
  • 我仍然不明白的是,从 0:255 开始的一系列值如何增加 512x512 尺寸或任何其他尺寸的图像的对比度?映射如何工作?为了增加图像的对比度是把像素设置为低值吧?
【解决方案2】:

您需要获取图像中的每个像素并将其替换为查找表中的相应值。这可以通过一些嵌套的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) 将其转换回来。

【讨论】:

  • 只是一个小评论。 arrayfun 这种能力似乎很浪费。你可以简单地做:new_image = lut(image+1);+1 是为了适应从 1 开始的索引,而图像像素强度从 0 开始。
  • @AndrewPilsner - 哦,当然!谢谢:)!
猜你喜欢
  • 1970-01-01
  • 2015-12-17
  • 2019-10-03
  • 1970-01-01
  • 1970-01-01
  • 2017-01-11
  • 2012-08-02
  • 2020-04-22
  • 1970-01-01
相关资源
最近更新 更多