【问题标题】:Increase image brightness without overflow增加图像亮度而不溢出
【发布时间】:2017-10-18 06:31:25
【问题描述】:

我在尝试增加图像亮度时遇到问题。

这是原图:

我想得到的图像是这样的:

现在用下面的代码增加亮度:

    image = cv2.imread("/home/wni/vbshare/tmp/a4_index2.png",0)

    if sum(image[0])/len(image[0])<200:
        new = np.where((255-image)<image,255,image*2)
    else:
        new = image
    return new

而且,我得到了以下图像:

所以,似乎有些点的亮度溢出了。

我尝试将阈值从 200 更改为其他数字,例如125、100、140 等 但是,图像亮度要么保持几乎相同的暗度,要么溢出。

环境:

Python:2.7.10

Opencv:3.2.0

对此的任何建议表示赞赏。

谢谢。

【问题讨论】:

  • 您可以使用cv2.adaptiveThreshold() 获得类似的结果,但您可能无法获得确切的原始形式。
  • 所附图片均无效。
  • 你确定?我没关系
  • @Wesley 很有趣。一定是一些暂时的问题。
  • 无论如何,对于你的问题——为了避免溢出,我会使用饱和的操作。例如cv2.add 源数组自身,使用掩码选择要更新的元素。这并不是说这是一种理想的方法。

标签: python numpy opencv image-processing


【解决方案1】:

这是我对清理特定图像的简单算法的尝试。随意使用它并进一步调整它以获得所需的结果。

注意:显示的代码应该适用于 OpenCV 的 2.4.x 和 3.x 分支。

步骤 0

将输入图像加载为灰度。

img = cv2.imread('paper.jpg',0)

步骤 1

放大图像,以去除文字。 此步骤在一定程度上有助于保存条形码。

dilated_img = cv2.dilate(img, np.ones((7,7), np.uint8)) 

第二步

使用适当大小的内核对结果进行中值模糊,以进一步抑制任何文本。

这应该会为我们提供一个包含所有阴影和/或变色的相当好的背景图像。

bg_img = cv2.medianBlur(dilated_img, 21)

第三步

计算原始和我们刚刚获得的背景之间的差异。相同的位为黑色(接近0差),文本为白色(差大)。

因为我们想要白底黑字,所以我们反转结果。

diff_img = 255 - cv2.absdiff(img, bg_img)

第四步

标准化图像,以便我们使用完整的动态范围。

norm_img = diff_img.copy() # Needed for 3.x compatibility
cv2.normalize(diff_img, norm_img, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)

第 5 步

此时,我们的纸张仍然有些灰。我们可以将其截断,然后重新规范化图像。

_, thr_img = cv2.threshold(norm_img, 230, 0, cv2.THRESH_TRUNC)
cv2.normalize(thr_img, thr_img, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)

完成...

嗯,至少对我而言 ;) 你可能想要裁剪它,然后做你想做的任何其他后期处理。


注意:在获得差异图像后,可能值得切换到更高的精度(16+ 位整数或浮点数),以最大限度地减少重复归一化中累积的舍入误差。

【讨论】:

  • 您好,感谢您的回复。我只是试一试,得到我想要的。将接受作为答案。
  • 嗨@DanMašek @dan-ma%c5%a1ek,您能否提供一些代码示例或说明在哪里应用您的评论:> 注意:可能值得切换到更高的精度(16+ 位 int或浮动)在获得差异图像后,以最大程度地减少重复归一化中累积的舍入误差。
【解决方案2】:

您需要的是thresholding。这将允许您将所有不是很暗的东西设置为纯白色,并将非常暗的东西设置为纯黑色(或任何其他颜色)。这应该可以帮助您开始:

cutoff_val = 100 # everything above this is set to set_color
set_color = 255 
ret,thresh_img = cv2.threshold(image,cutoff_val,set_color,cv2.THRESH_BINARY)

玩弄之后,使用adaptive thresholding 可以获得更好的结果。

请参阅 this great tutorial 做你想做的事 --- 还有额外的好处,它还包括一个关于翘曲的教程,以便为纸张获得一个矩形区域!

编辑:你的图像结合阈值和自适应阈值得到了很好的结果。

cutoff_val = 150 # everything above this is set to the cutoff val
set_color = 255 # if 
ret,thresh_img = cv2.threshold(image,cutoff_val,set_color,cv2.THRESH_TRUNC)
window_sz = 3
thresh_img2 = cv2.adaptiveThreshold(thresh_img,set_color,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
            cv2.THRESH_BINARY,window_sz,2)

【讨论】:

  • 嗨,我只是试了一下你的代码,是的,它变得更亮了,但也很糊涂,我猜是来自 cv2.ADAPTIVE_THRESH_GAUSSIAN_C,所以我改为 cv2.ADAPTIVE_THRESH_MEAN_C,但几乎同样的结果。因为在此之后我仍然需要做一些 ocr 识别,所以,您能否建议在增加亮度时保持清晰度:-)
猜你喜欢
  • 2016-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-11
  • 2015-11-17
  • 2015-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多