增加图像亮度而不溢出

问题描述 投票:0回答:3

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

这是原图:

enter image description here

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

enter image description here

现在使用以下代码增加亮度:

    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

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

enter image description here

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

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

环境:

Python:2.7.10

OpenCV:3.2.0

如有任何建议,我们将不胜感激。

谢谢。

python numpy opencv image-processing scikit-image
3个回答
68
投票

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

NB:所示代码应适用于 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)) 

Dilated

步骤2

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

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

bg_img = cv2.medianBlur(dilated_img, 21)

Blurred

步骤3

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

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

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

Inverted Difference

步骤4

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

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)

Normalized

步骤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)

Gray Trimmed

完成...

嗯,至少对我来说是这样;)您可能想要裁剪它,并进行您想要的任何其他后处理。


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


4
投票

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

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)

尝试之后,您可以使用自适应阈值获得更好的结果。

参见 这个很棒的教程 基本上可以做你想要的事情——还有额外的好处,它还包括一个关于扭曲以获得纸张矩形区域的教程!

编辑:我通过结合阈值处理和自适应阈值处理的图像得到了非常好的结果。

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)

0
投票

从图像中去除阴影的问题可以被认为是带通滤波(可以使用DOG滤波器来实现):

from skimage.filters import difference_of_gaussians
from skimage.color import rgb2gray   

im = rgb2gray(plt.imread('images/kqKGH.jpg'))
im = im / im.max()
im_filtered = difference_of_gaussians(im, 0.1, 10.0) # choose suitable low & high sigmas
im_filtered = im_filtered / im_filtered.max()

plt.figure(figsize=(12,8))
plt.subplot(121), plt.imshow(im), plt.axis('off')
plt.subplot(122), plt.imshow(im_filtered), plt.axis('off')
plt.tight_layout()
plt.show()

下图显示了原始图像和带通滤波后的图像。

enter image description here

现在,可以选择使用像 otsu(或其他阈值算法)这样的最佳阈值来获取二值图像,如下所示:

from skimage.filters import threshold_otsu
im_filtered_thresh = im_filtered > threshold_otsu(im_filtered)

获得如下输出图像:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.