如何使用 python + OpenCV 快速更改图像亮度?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32609098/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 11:53:52  来源:igfitidea点击:

How to fast change image brightness with python + OpenCV?

pythonopencvnumpyimage-processing

提问by Pavel

I have a sequence of images. I need to average brightness of these images.

我有一系列图像。我需要平均这些图像的亮度。

First example(very slow):

第一个例子(很慢):

img = cv2.imread('test.jpg') #load rgb image
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #convert it to hsv

for x in range(0, len(hsv)):
    for y in range(0, len(hsv[0])):
        hsv[x, y][2] += value

img = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
cv2.imwrite("image_processed.jpg", img)

Second example(quickly)

第二个例子(快速)

hsv += value

This example very fast but it changes all values HSV (I need to change only V (brightness))

这个例子非常快,但它改变了所有的 HSV 值(我只需要改变 V(亮度))

采纳答案by Divakar

Sliceto select just the third channel and then modify those elements -

Slice只选择第三个通道,然后修改这些元素 -

hsv[:,:,2] += value

回答by ZdaR

Iterating over the whole image to make changes is not a very scalable option in opencv, Opencv provides a lot of methods and functions to perform the arithmetic operations on the given image.

迭代整个图像以进行更改在 opencv 中不是一个非常可扩展的选项,Opencv 提供了许多方法和函数来对给定图像执行算术运算。

You may simply split the converted HSV image in the individual channels and then process the V channel accordingly as:

您可以简单地在各个通道中拆分转换后的 HSV 图像,然后相应地处理 V 通道,如下所示:

img = cv2.imread('test.jpg') #load rgb image
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #convert it to hsv

h, s, v = cv2.split(hsv)
v += 255
final_hsv = cv2.merge((h, s, v))

img = cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR)
cv2.imwrite("image_processed.jpg", img)

回答by Bill Grates

I know this question is a bit old, but I thought I might post the complete solution that worked for me (takes care of the overflow situation by saturating at 255):

我知道这个问题有点老了,但我想我可能会发布对我有用的完整解决方案(通过在 255 处饱和来处理溢出情况):

def increase_brightness(img, value=30):
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    h, s, v = cv2.split(hsv)

    lim = 255 - value
    v[v > lim] = 255
    v[v <= lim] += value

    final_hsv = cv2.merge((h, s, v))
    img = cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR)
    return img

This can be used as follows:

这可以按如下方式使用:

frame = increase_brightness(frame, value=20)

回答by Rendicahya

import cv2
import numpy as np

image = cv2.imread('image.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

increase = 100

v = image[:, :, 2]
v = np.where(v <= 255 - increase, v + increase, 255)
image[:, :, 2] = v

image = cv2.cvtColor(image, cv2.COLOR_HSV2BGR)

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

回答by Gui Meira

The other answers suggest doing the saturation "by hand" using all kinds of numpy magic, but you can also use cv2.add()and let OpenCV handle that for you:

其他答案建议使用各种 numpy 魔法“手动”进行饱和,但您也可以使用cv2.add()并让 OpenCV 为您处理:

import cv2
import numpy as np

image = cv2.read('image.png')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
value = 42 #whatever value you want to add
cv2.add(hsv[:,:,2], value, hsv[:,:,2])
image = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
cv2.imwrite('out.png', image)

回答by Santhosh Dhaipule Chandrakanth

Hope this is useful for someone

希望这对某人有用

@Divakar answer Python, OpenCV: Increasing image brightness without overflowing UINT8 array

@Divakar 回答Python、OpenCV:在不溢出 UINT8 数组的情况下增加图像亮度

mImage = cv2.imread('image1.jpg')

hsvImg = cv2.cvtColor(mImage,cv2.COLOR_BGR2HSV)

value = 0

vValue = hsvImg[...,2]
hsvImg[...,2] = np.where((255-vValue)<value,255,vValue+value)

plt.subplot(111), plt.imshow(cv2.cvtColor(hsvImg,cv2.COLOR_HSV2RGB))
plt.title('brightened image'), plt.xticks([]), plt.yticks([])
plt.show()

To decrease the brightness

降低亮度

mImage = cv2.imread('image1.jpg')

hsvImg = cv2.cvtColor(mImage,cv2.COLOR_BGR2HSV)

# decreasing the V channel by a factor from the original
hsvImg[...,2] = hsvImg[...,2]*0.6

plt.subplot(111), plt.imshow(cv2.cvtColor(hsvImg,cv2.COLOR_HSV2RGB))
plt.title('brightened image'), plt.xticks([]), plt.yticks([])
plt.show()

回答by Bilal

Might be too old but I use cv.covertTo which works for me

可能太旧了,但我使用 cv.covertTo 对我有用

Mat resultBrightImage;    
origImage.convertTo(resultBrightImage, -1, 1, percent); // Where percent = (int)(percent_val/100)*255, e.g., percent = 50 to increase brightness by 50%

convertTo uses saturate_cast at the end to avoid any overflows. I don't use Python and the above is in C++ but I hope it is easily convertible in Python and hope it helps

convertTo 最后使用 saturate_cast 来避免任何溢出。我不使用 Python,上面是 C++,但我希望它可以在 Python 中轻松转换并希望它有所帮助

回答by Md. Hanif Ali Sohag

You can use this function to change your desired brightness or contrast using C++just like the same way you do it on photoshop or other similar photo editing software.

您可以使用此功能使用 C++更改所需的亮度或对比度,就像您在 photoshop 或其他类似的照片编辑软件上所做的一样。

def apply_brightness_contrast(input_img, brightness = 255, contrast = 127):
    brightness = map(brightness, 0, 510, -255, 255)
    contrast = map(contrast, 0, 254, -127, 127)

    if brightness != 0:
        if brightness > 0:
            shadow = brightness
            highlight = 255
        else:
            shadow = 0
            highlight = 255 + brightness
        alpha_b = (highlight - shadow)/255
        gamma_b = shadow

        buf = cv2.addWeighted(input_img, alpha_b, input_img, 0, gamma_b)
    else:
        buf = input_img.copy()

    if contrast != 0:
        f = float(131 * (contrast + 127)) / (127 * (131 - contrast))
        alpha_c = f
        gamma_c = 127*(1-f)

        buf = cv2.addWeighted(buf, alpha_c, buf, 0, gamma_c)

    cv2.putText(buf,'B:{},C:{}'.format(brightness,contrast),(10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
    return buf

def map(x, in_min, in_max, out_min, out_max):
    return int((x-in_min) * (out_max-out_min) / (in_max-in_min) + out_min)

After that you need to call the functions by creating trackbar using cv2.createTrackbar()and call that above functions with proper parameters as well. In order to map the brightness values which ranges from -255 to +255 and contrast values -127 to +127, you can use that map()function. You can check the full details of about python implementation here.

之后,您需要通过使用创建轨迹栏来cv2.createTrackbar()调用函数,并使用适当的参数调用上述函数。为了映射范围从 -255 到 +255 的亮度值和对比度值 -127 到 +127,您可以使用该map()函数。您可以在此处查看有关Python 实现的完整详细信息。

回答by Vikas

def change_brightness(img, alpha, beta):
   return cv2.addWeighted(img, alpha, np.zeros(img.shape, img.dtype),0, beta)

Here alpha & beta are input parameters. Each pixel of the input image will change according to this formula.

这里 alpha 和 beta 是输入参数。输入图像的每个像素都会根据这个公式发生变化。

 alpha(pixel_value) + beta.

Lower value of alpha like 2 or 3 is good

像 2 或 3 这样的较低的 alpha 值是好的

回答by oezguensi

I know this shouldn't be so hard and there to adjust the brightness of an image. Also, there are already plenty of great answers. I would like to enhance the answer of @BillGrates, so it works on grayscale images and with decreasing the brightness: value = -255creates a black image whereas value = 255a white one.

我知道这不应该那么难,可以调整图像的亮度。此外,已经有很多很好的答案。我想增强@BillGrates 的答案,因此它适用于灰度图像并降低亮度:value = -255创建黑色图像而value = 255白色图像。

def adjust_brightness(img, value):
    num_channels = 1 if len(img.shape) < 3 else 1 if img.shape[-1] == 1 else 3
    img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) if num_channels == 1 else img
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    h, s, v = cv2.split(hsv)

    if value >= 0:
        lim = 255 - value
        v[v > lim] = 255
        v[v <= lim] += value
    else:
        value = int(-value)
        lim = 0 + value
        v[v < lim] = 0
        v[v >= lim] -= value

    final_hsv = cv2.merge((h, s, v))

    img = cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) if num_channels == 1 else img
    return img