首页 文章

Python,OpenCV:增加图像亮度而不会溢出UINT8数组

提问于
浏览
3

我正在尝试增加灰度图像的亮度 . cv2.imread() 返回一个numpy数组 . 我正在为数组的每个元素添加整数值 . 从理论上讲,这会增加每一个 . 之后,我可以将上限阈值设为255,并获得更高亮度的图像 .

这是代码:

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例程显然是这样的:

new_array = old_array % 255

高于255的每个像素强度值变为除以255的余数 .

结果,我变得黑暗而不是完全变白 .

这是输出:

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

这是图像:

enter image description here

如何关闭此余数机制?有没有更好的方法来提高OpenCV的亮度?

4 回答

  • 10

    一个想法是在添加 value 之前检查添加是否会通过检查 255 与当前像素值之间的差异并检查它是否在 value 内而导致溢出 . 如果是的话,我们不会添加 value ,我们会直接在 255 设置,否则我们会添加 . 现在,这个决策可以通过创建面具来缓解,并且 -

    mask = (255 - grey) < value
    

    然后,将此掩码/布尔数组提供给np.where,让它根据掩码在 255grey+value 之间进行选择 .

    因此,最后我们将实施 -

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

    Sample run

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

    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)
    

    Testing on sample image

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

    enter image description here

  • 2

    简而言之,你应该为每个值添加50,找到 maxBrightness ,然后 thisPixel = int(255 * thisPixel / maxBrightness)

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

  • 0

    这是另一种选择:

    # 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)
    
  • 1

    另一种对我有效的方法是使用PIL>图像库中的混合功能将白色图像“混合”到原始图像 .

    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,我们得到纯白色 .

    此功能可自行校正RGB值超过255 .

    黑色混合(RGB 0,0,0)会降低亮度 .

相关问题