使用OpenCV自动确定图像是否需要对比度增强

10

OpenCV有一个方便的cvEqualizeHist()函数,对于褪色/低对比度的图像效果很好。然而,当给出一个已经具有高对比度的图像时,结果是一个低对比度的图像。我懂得原因 - 直方图被均匀分布了。

问题是 - 我如何知道低对比度和高对比度图像之间的差异?

我正在处理灰度图像,将它们的对比度设置正确,以便对它们进行阈值处理不会删除我要提取的文本(这是另一个故事)。欢迎建议 - 特别是如何找出图像中大多数像素是浅灰色的(这意味着需要执行相等化直方图)。 请帮忙!

编辑:感谢大家提供许多信息丰富的答案。但标准差计算对我的要求已足够,因此我把它作为我的问题的答案。


我需要计算一张图片的对比度。我通过计算图像的“meanStdDev”来实现。这样做正确吗?有时候我会得到超过100的SD值。那么一个好的对比度阈值是多少呢?而将SD转换为100的刻度的范围是多少? - 2vision2
我们将SD除以255进行归一化处理,因为像素值(假设为8位图像)不可能超过这个范围。然后乘以适当的比例尺,例如100。这就是所谓的归一化。剩下的你可以尝试不同的图像。 - AruniRC
谢谢,我已经做了。一个好图像的阈值范围是多少? - 2vision2
@2vision2 很抱歉,这是不可能随意说出的。最好的方法是:您可以检查几张图像上的值并自己解决! - AruniRC
4个回答

6

您可以使用简单的图像统计量来确定图像是否具有足够的对比度。图像的方差可能是一个很好的起点。如果方差低于某个阈值(需要经验确定),则可以认为它是“低对比度”的。


确实,对于给定的图像,方差随着对比度的增加而增加,但由于它是一种统计量,它忽略了图像内部的空间关系。因此,它有时可能作为可靠的对比度指标,但通常不会。 - mpenkov
@AruniRC 我需要计算一张图片的对比度。我通过计算图像的“meanStdDev”来实现。这样做正确吗?有时候我得到的SD值超过了100。一个好的对比度阈值是多少?将SD转换为100的比例范围是多少? - 2vision2

6
如果您只是为了后面进行阈值处理而调整对比度,那么您可以使用Ohtsu's method自适应地设置阈值,从而避免对比度调整步骤。
如果您仍然有兴趣了解图像对比度,则请继续阅读。
虽然有许多不同的方法来计算“对比度”。通常,这些指标是局部应用的,而不是整个图像,以使结果对图像内容更敏感:
- 将图像分成相邻的非重叠邻域。 - 选择与图像特征大小相近的邻域大小(例如,如果主要特征是水平文本,则将邻域设置为高度足以捕获2行文本,并且宽度相同)。 - 将指标分别应用于每个邻域。 - 对指标结果进行阈值处理,以分离低方差块和高方差块。这将防止大的空白区域扭曲您的对比度估计。
从那里开始,您可以使用许多功能来确定对比度:
  • 高度评量块的比例与低度评量块
  • 高度评量块的平均值
  • 高度评量块与低度评量块之间的强度距离(使用均值、众数等)

相较于全局图像方差,这可能更好地表征图像对比度。原因如下:

alt text (标准偏差:50.6)

alt text (标准偏差:7.9)

这两个图片完全对比(灰色背景仅为突出显示它们是图片),但它们的标准偏差(从而方差)完全不同。


我最初使用了大津阈值法,但文本部分及其背景变成了黑色。然后通过均衡化直方图再进行阈值处理就可以了。 - AruniRC
我删除了之前的评论——那是意外添加的。你有没有进行局部对比度计算?我还没有看到你处理的图像,所以很难在已经说过的基础上再提出建议。如果你发布一个样例图像,你的问题可能会更容易回答。 - mpenkov
抱歉回复晚了(如果你还在的话 :P)。目前正在完成轮廓提取编码,之后将开始对比度调整。一个简单的标准差与实验确定的截止值似乎可行。 - AruniRC

3
  1. 计算图像的累积直方图
  2. y(x) = A*x + B的形式对累积直方图进行线性回归。
  3. 计算real_cumulative_frequency(x)-y(x)RMSE
  4. 如果RMSE接近于零,则图像已经均衡化。(这意味着对于均衡化的图像,累积直方图必须是线性的)

这个想法来自于这里

编辑: 我在我的博客中说明了这种方法(包括C示例代码)。


仅使用std不就足够了吗...http://en.wikipedia.org/wiki/Contrast_(vision)... 您的评论将会很有帮助... - santiago_apr1
有许多不同的方法来计算对比度。但在我看来,如果 OP 尝试发现 cvEqualizeHist() 是否应用于图像 - 那么你必须考虑到 直方图均衡化 的特定情况,以便在图像中检测该操作(或其缺失)。 - Agnius Vasiliauskas

0

在skimage中提供了支持。 skimage.exposure.is_low_contrast参考资料

例如:

>>> image = np.linspace(0, 0.04, 100)
>>> is_low_contrast(image)
    True
>>> image[-1] = 1
>>> is_low_contrast(image)
    True
>>> is_low_contrast(image, upper_percentile=100)
    False

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接