Python,OpenCV:提高图像亮度而不溢出UINT8数组

Python, OpenCV: Increasing image brightness without overflowing UINT8 array

我试图增加灰度图像的亮度。 cv2.imread()返回一个numpy数组。 我将整数值添加到数组的每个元素。 从理论上讲,这将增加他们每个人。 之后,我可以将上限设置为255,并获得具有更高亮度的图像。

这是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
grey = cv2.imread(path+file,0)

print type(grey)

print grey[0]

new = grey + value

print new[0]

res = np.hstack((grey, new))

cv2.imshow('image', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

但是,内部OpenCV例程显然可以执行以下操作:

1
new_array = old_array % 255

每个高于255的像素强度值都将除以255。

结果,我越来越黑,而不是全白。

这是输出:

1
2
3
<type 'numpy.ndarray'>
[115 114 121 ..., 170 169 167]
[215 214 221 ...,  14  13  11]

这是图片:

enter image description here

如何关闭这种余数机制? 有没有更好的方法可以提高OpenCV的亮度?


一种想法是在添加value之前检查该添加是否会导致溢出,方法是检查255与当前像素值之间的差异,并检查它是否在value之内。如果是这样,我们将不添加value,我们将直接将它们设置为255,否则我们将进行添加。现在,可以通过创建遮罩来简化此决策,并且可以-

1
mask = (255 - grey) < value

然后,将此掩码/布尔数组输入到np.where,以使其根据掩码在255grey+value之间进行选择。

因此,最后我们将实现如下:

1
grey_new = np.where((255 - grey) < value,255,grey+value)

样品运行

让我们使用一个小的代表性示例来演示这些步骤。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
In [340]: grey
Out[340]:
array([[125, 212, 104, 180, 244],
       [105,  26, 132, 145, 157],
       [126, 230, 225, 204,  91],
       [226, 181,  43, 122, 125]], dtype=uint8)

In [341]: value = 100

In [342]: grey + 100 # Bad results (e.g. look at (0,1))
Out[342]:
array([[225,  56, 204,  24,  88],
       [205, 126, 232, 245,   1],
       [226,  74,  69,  48, 191],
       [ 70,  25, 143, 222, 225]], dtype=uint8)

In [343]: np.where((255 - grey) < 100,255,grey+value) # Expected results
Out[343]:
array([[225, 255, 204, 255, 255],
       [205, 126, 232, 245, 255],
       [226, 255, 255, 255, 191],
       [255, 255, 143, 222, 225]], dtype=uint8)

测试样本图像

使用问题中发布的示例图像给我们arr并将value用作50,我们将-

enter image description here


简要地说,您应该为每个值加50,分别找到maxBrightnessthisPixel = int(255 * thisPixel / maxBrightness)

您必须检查每个像素是否溢出。 Divakar建议的方法简单,快速。您实际上可能希望将每个值递增(在您的情况下为50),然后将其规格化为255。这将在图像的明亮区域保留细节。


这是另一种选择:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# convert data type
gray = gray.astype('float32')

# shift pixel intensity by a constant
intensity_shift = 50
gray += intensity_shift

# another option is to use a factor value > 1:
# gray *= factor_intensity

# clip pixel intensity to be in range [0, 255]
gray = np.clip(gray, 0, 255)

# change type back to 'uint8'
gray = gray.astype('uint8)

对我而言有效的另一种方法是使用PIL>图像库中的blend函数将白色图像"融合"到原始图像中。

1
2
3
4
5
6
7
from PIL import Image
correctionVal = 0.05 # fraction of white to add to the main image
img_file = Image.open(location_filename)
img_file_white = Image.new("RGB", (width, height),"white")
img_blended = Image.blend(img_file, img_file_white, correctionVal)

img_blended = img_file * (1 - correctionVal) + img_file_white * correctionVal

因此,如果correctionVal = 0,我们得到原始图像,如果correctionVal = 1,我们得到纯白色。

此功能可自我校正超过255的RGB值。

黑色混合(RGB 0、0、0)会降低亮度。