如何在 Python OpenCV 中增加图像的对比度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39308030/
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
How do I increase the contrast of an image in Python OpenCV
提问by tsaebeht
I am new to Python OpenCV. I have read some documents and answers herebut I am unable to figure out what the following code means:
我是 Python OpenCV 的新手。我在这里阅读了一些文档和答案,但我无法弄清楚以下代码的含义:
if (self.array_alpha is None):
self.array_alpha = np.array([1.25])
self.array_beta = np.array([-100.0])
# add a beta value to every pixel
cv2.add(new_img, self.array_beta, new_img)
# multiply every pixel value by alpha
cv2.multiply(new_img, self.array_alpha, new_img)
I have come to know that Basically, every pixel can be transformed as X = aY + b where a and b are scalars.
. Basically, I have understood this. However, I did not understand the code and how to increase contrast with this.
我已经知道了Basically, every pixel can be transformed as X = aY + b where a and b are scalars.
。基本上,我已经理解了这一点。但是,我不明白代码以及如何与此增加对比度。
Till now, I have managed to simply read the image using img = cv2.imread('image.jpg',0)
到目前为止,我已经设法简单地使用 img = cv2.imread('image.jpg',0)
Thanks for your help
谢谢你的帮助
回答by Jeru Luke
I would like to suggest a method using the LAB color channel. Wikipedia has enough information regarding what the LAB color channel is about.
我想建议一种使用 LAB 颜色通道的方法。维基百科有足够的关于 LAB 颜色通道的信息。
I have done the following using OpenCV 3.0.0 and python:
我使用 OpenCV 3.0.0 和 python 完成了以下操作:
import cv2
#-----Reading the image-----------------------------------------------------
img = cv2.imread('Dog.jpg', 1)
cv2.imshow("img",img)
#-----Converting image to LAB Color model-----------------------------------
lab= cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
cv2.imshow("lab",lab)
#-----Splitting the LAB image to different channels-------------------------
l, a, b = cv2.split(lab)
cv2.imshow('l_channel', l)
cv2.imshow('a_channel', a)
cv2.imshow('b_channel', b)
#-----Applying CLAHE to L-channel-------------------------------------------
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
cl = clahe.apply(l)
cv2.imshow('CLAHE output', cl)
#-----Merge the CLAHE enhanced L-channel with the a and b channel-----------
limg = cv2.merge((cl,a,b))
cv2.imshow('limg', limg)
#-----Converting image from LAB Color model to RGB model--------------------
final = cv2.cvtColor(limg, cv2.COLOR_LAB2BGR)
cv2.imshow('final', final)
#_____END_____#
You can run the code as it is. To know what CLAHE (Contrast Limited Adaptive Histogram Equalization)is about, you can again check Wikipedia.
您可以按原样运行代码。要了解 CLAHE(对比度限制自适应直方图均衡化)是什么,您可以再次查看维基百科。
回答by bfris
\\this post has been heavily edited from original. the kernel of the original answer is preserved in the Note below\\
\\这篇文章已从原文大量编辑。原始答案的内核保留在下面的注释中\\
For Python, I haven't found an OpenCV function that provides contrast. As others have suggested, there are some techniques to automatically increase contrast.
对于 Python,我还没有找到提供对比的 OpenCV 函数。正如其他人所建议的,有一些技术可以自动增加对比度。
In the official OpenCV docs, it is suggested that this equation can be used to apply both contrast and brightness at the same time:
在OpenCV 官方文档中,建议可以使用此公式同时应用对比度和亮度:
new_img = alpha*old_img + beta
new_img = alpha*old_img + beta
where alpha corresponds to a contrast and beta is brightness. Different cases
其中 alpha 对应于对比度,beta 是亮度。不同情况
alpha 1 beta 0 --> no change
0 < alpha < 1 --> lower contrast
alpha > 1 --> higher contrast
-127 < beta < +127 --> good range for brightness values
In C/C++, you can implement this equation using cv::Mat::convertTo, but we don't have access to that part of the library from Python. To do it in Python, I would recommend using the cv::addWeightedfunction, because it is quick and it automatically forces the output to be in the range 0 to 255 (e.g. for a 24 bit color image, 8 bits per channel).
在 C/C++ 中,您可以使用 cv::Mat::convertTo 来实现这个等式,但我们无法从 Python 访问该部分库。要在 Python 中执行此操作,我建议使用cv::addWeighted函数,因为它很快,并且它会自动强制输出范围为 0 到 255(例如,对于 24 位彩色图像,每个通道 8 位)。
import cv2
img = cv2.imread('input.png')
# call addWeighted function. use beta = 0 to effectively only operate one one image
out = cv2.addWeighted( img, contrast, img, 0, brightness)
output = cv2.addWeighted
>>>>>Begin Note<<<<<
>>>>>开始注意<<<<<
As originally posted, I referred to this formula from this online GIMP book](http://pippin.gimp.org/image_processing/chap_point.html) is
正如最初发布的那样,我从这本在线 GIMP 书中引用了这个公式]( http://pippin.gimp.org/image_processing/chap_point.html) 是
new_image = (old_image - 0.5) × contrast + 0.5
new_image = (old_image - 0.5) × 对比度 + 0.5
and this modified formula to change the contrast scale to go from -127 to +127:
这个修改后的公式将对比度比例从 -127 更改为 +127:
new_image = (old_image) × (contrast/127 + 1) - contrast
new_image = (old_image) × (contrast/127 + 1) - 对比度
These formulas will both yield brightness and contrast changes, but they have the weaknesses:
这些公式都会产生亮度和对比度的变化,但它们有缺点:
- the second formula is not rigorously derived from the first
- they do not correspond to brightness and contrast behavior observed in other programs (e.g. PhotoShop, GIMP, etc)
- 第二个公式不是严格地从第一个公式推导出来的
- 它们与在其他程序(例如 PhotoShop、GIMP 等)中观察到的亮度和对比度行为不对应
>>>>>End Note<<<<<
>>>>>尾注<<<<<
From here on out, I will try to reproduce the behavior generally seen in photo editing programs and specifically the behavior in the GIMP.
从现在开始,我将尝试重现通常在照片编辑程序中看到的行为,特别是在 GIMP 中的行为。
Contrast
对比
In the GIMP, contrast levels go from -127 to +127. I adapted the formulas from hereto fit in that range.
在 GIMP 中,对比度级别从 -127 到 +127。我调整了这里的公式以适应该范围。
f = 131*(contrast + 127)/(127*(131-contrast))
new_image = f*(old_image - 127) + 127 = f*(old_image) + 127*(1-f)
f = 131*(对比度 + 127)/(127*(
131-对比度)) new_image = f*(old_image - 127) + 127 = f*(old_image) + 127*(1-f)
To figure out brightness, I figured out the relationship between brightness and levels and used information in this levels postto arrive at a solution.
为了弄清楚亮度,我弄清楚了亮度和级别之间的关系,并使用此级别帖子中的信息来得出解决方案。
#pseudo code
if brightness > 0
shadow = brightness
highlight = 255
else:
shadow = 0
highlight = 255 + brightness
new_img = ((highlight - shadow)/255)*old_img + shadow
brightness and contrast in Python and OpenCV
Python 和 OpenCV 中的亮度和对比度
Putting it all together and adding using the reference "mandrill" image from USC SIPI:
将它们放在一起并使用来自USC SIPI的参考“ mandrill”图像添加:
import cv2
import numpy as np
# Open a typical 24 bit color image. For this kind of image there are
# 8 bits (0 to 255) per color channel
img = cv2.imread('mandrill.png') # mandrill reference image from USC SIPI
s = 128
img = cv2.resize(img, (s,s), 0, 0, cv2.INTER_AREA)
def apply_brightness_contrast(input_img, brightness = 0, contrast = 0):
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 = 131*(contrast + 127)/(127*(131-contrast))
alpha_c = f
gamma_c = 127*(1-f)
buf = cv2.addWeighted(buf, alpha_c, buf, 0, gamma_c)
return buf
font = cv2.FONT_HERSHEY_SIMPLEX
fcolor = (0,0,0)
blist = [0, -127, 127, 0, 0, 64] # list of brightness values
clist = [0, 0, 0, -64, 64, 64] # list of contrast values
out = np.zeros((s*2, s*3, 3), dtype = np.uint8)
for i, b in enumerate(blist):
c = clist[i]
print('b, c: ', b,', ',c)
row = s*int(i/3)
col = s*(i%3)
print('row, col: ', row, ', ', col)
out[row:row+s, col:col+s] = apply_brightness_contrast(img, b, c)
msg = 'b %d' % b
cv2.putText(out,msg,(col,row+s-22), font, .7, fcolor,1,cv2.LINE_AA)
msg = 'c %d' % c
cv2.putText(out,msg,(col,row+s-4), font, .7, fcolor,1,cv2.LINE_AA)
cv2.putText(out, 'OpenCV',(260,30), font, 1.0, fcolor,2,cv2.LINE_AA)
cv2.imwrite('out.png', out)
I manually processed the images in the GIMP and added text tags in Python/OpenCV:
我手动处理了 GIMP 中的图像并在 Python/OpenCV 中添加了文本标签:
Note:@UtkarshBhardwaj has suggested that Python 2.x users must cast the contrast correction calculation code into float for getting floating result, like so:
注意:@UtkarshBhardwaj 已经建议 Python 2.x 用户必须将对比度校正计算代码转换为 float 以获得浮动结果,如下所示:
...
if contrast != 0:
f = float(131*(contrast + 127))/(127*(131-contrast))
...
回答by nathancy
Brightness and contrast can be adjusted using alpha (α
) and beta (β
), respectively. The expression can be written as
可以分别使用 alpha ( α
) 和 beta ( β
)调整亮度和对比度。表达式可以写成
OpenCV already implements this as cv2.convertScaleAbs()
, just provide user defined alpha
and beta
values
OpenCV 已经实现了这一点cv2.convertScaleAbs()
,只需提供用户定义alpha
和beta
值
import cv2
image = cv2.imread('1.jpg')
alpha = 1.5 # Contrast control (1.0-3.0)
beta = 0 # Brightness control (0-100)
adjusted = cv2.convertScaleAbs(image, alpha=alpha, beta=beta)
cv2.imshow('original', image)
cv2.imshow('adjusted', adjusted)
cv2.waitKey()
Before ->
After
之前->
之后
Note:For automatic brightness/contrast adjustment take a look at automatic contrast and brightness adjustment of a color photo
注意:对于自动亮度/对比度调整,请查看彩色照片的自动对比度和亮度调整
回答by be_good_do_good
Best explanation for X = aY + b
(in fact it f(x) = ax + b
)) is provided at https://math.stackexchange.com/a/906280/357701
在https://math.stackexchange.com/a/906280/357701上提供了对X = aY + b
(实际上是f(x) = ax + b
)的最佳解释
A Simpler one by just adjusting lightness/luma/brightness for contrast as is below:
一个更简单的只是调整亮度/亮度/亮度的对比度,如下所示:
import cv2
img = cv2.imread('test.jpg')
cv2.imshow('test', img)
cv2.waitKey(1000)
imghsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
imghsv[:,:,2] = [[max(pixel - 25, 0) if pixel < 190 else min(pixel + 25, 255) for pixel in row] for row in imghsv[:,:,2]]
cv2.imshow('contrast', cv2.cvtColor(imghsv, cv2.COLOR_HSV2BGR))
cv2.waitKey(1000)
raw_input()