如何使用OpenCV Python调整亮度、对比度和色彩饱和度?

5

我是一名新手图像处理工程师,我的编程语言是Python3,并使用了OpenCV图像处理库。我想要调整以下属性:

  1. 亮度
  2. 对比度
  3. 鲜艳度
  4. 色调
  5. 饱和度
  6. 明度

对于4、5、6这三个属性,在我的代码中我使用以下代码将它们转换到HSV空间。

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
h += value # 4
s += value # 5
v += value # 6
final_hsv = cv2.merge((h, s, v))
img = cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR)

我找到的1和2的唯一教程在这里。该教程使用C++,但我用Python编程。此外,我不知道如何调整3.饱和度。非常感谢您的帮助,谢谢!


1
这应该有所帮助... https://dev59.com/_1kS5IYBdhLWcg3w6qIz#50053219 - Mark Setchell
@MarkSetchell 谢谢!我刚试了一下,这个方法可行! - Antonie Lin
太棒了!祝你好运。 - Mark Setchell
4个回答

9
感谢@MarkSetchell提供链接。 简而言之,答案仅使用numpy,公式如下所示。
new_image = (old_image) × (contrast/127 + 1) - contrast + brightness
这里的对比度(contrast)和亮度(brightness)是在[-127,127]范围内的整数。标量127用于此范围。 此外,以下是我使用的代码。
brightness = 50
contrast = 30
img = np.int16(img)
img = img * (contrast/127+1) - contrast + brightness
img = np.clip(img, 0, 255)
img = np.uint8(img)

值得一提的是,OpenCV有一个内置函数convertScaleAbs,它将为您完成所有的剪裁工作。它将给出abs(alpha*img + beta)。在这种情况下,alpha=contrast/127+1。beta = brightness-contrast。 - bfris

1

一种简单的亮度调整方法,适用于彩色单色图像,是

img = cv2.imread('your path',0)
brt = 40  

img[img < 255-brt] += brt  

cv2.imshow('img'+ img)

其中 brt 可以是正数,表示增加亮度,也可以是负数,表示降低亮度。

以下链接为使用此代码处理的图像在 brt = 40 时的处理前后对比:

输入图像

输出图像


1
这里是使用Python/OpenCV增强图像的一种方法。
将图像转换为HSV格式,然后创建一个sigmoid函数LUT。
(sigmoid函数从原点开始呈线性增长,但随后逐渐变平。)

enter image description here

请参阅https://en.wikipedia.org/wiki/Sigmoid_function 将LUT应用于S通道。
转换回BGR。
输入:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread('yellow_building.jpg')

# convert image to hsv colorspace as floats
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
print(np.amax(s), np.amin(s), s.dtype)

# set vibrance
vibrance=1.4

# create 256 element non-linear LUT for sigmoidal function
# see https://en.wikipedia.org/wiki/Sigmoid_function
xval = np.arange(0, 256)
lut = (255*np.tanh(vibrance*xval/255)/np.tanh(1)+0.5).astype(np.uint8)

# apply lut to saturation channel
new_s = cv2.LUT(s,lut)

# combine new_s with original h and v channels
new_hsv = cv2.merge([h,new_s,v])

# convert back to BGR
result =  cv2.cvtColor(new_hsv,  cv2.COLOR_HSV2BGR)

# save output image
cv2.imwrite('yellow_building_vibrance.jpg', result)

# display images
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果:

enter image description here


1

我不确定这是否有帮助,但是对于更改亮度和对比度,我个人会将图像切换到PIL.Image并使用PIL.ImageEnhance,在使用比率或百分比时非常方便。

image = PIL.Image.open("path_to_image")

#increasing the brightness 20%
new_image = PIL.ImageEnhance.Brightness(image).enhance(1.2)

#increasing the contrast 20%
new_image = PIL.ImageEnhance.Contrast(image).enhance(1.2)

我仍然没有找到Vibrance的清晰方法。有关ImageEnahance的更多信息,建议阅读官方文档 - https://pillow.readthedocs.io/en/stable/reference/ImageEnhance.html

对于Conversion,我使用这个...

注意 - OpenCV使用BGR通道,而PIL使用RGB通道。因此,如果未正确转换,可能会出现混乱。

#convert pil.image to opencv (numpy.ndarray)
#need numpy library for this
cv_image = numpy.array(pil_image)

#convert opencv to pil.image

image = cv2.cvtColor(cv_image, cv2.COLOR_BGR2RGB)
pil_image = Image.fromarray(image)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接