我想将现有图像的亮度和对比度都改变100%。
decoded = Image.open(BytesIO(base64.b64decode(base64Data)))
image = cv2.cvtColor(np.array(decoded), cv2.COLOR_BGR2RGB)
有没有允许我执行此操作的功能?
答案 0 :(得分:0)
我为此找不到OpenCV函数,但是我找到了该指南: https://docs.opencv.org/3.4/d3/dc1/tutorial_basic_linear_transform.html 它表示您可以通过以下方式调整对比度和亮度:
new_image = old_image * contrast_coeff + brightness_coeff
但是,我没有使用它,因为如您所见,如果您仅想改变对比度,它不会同时使暗像素变暗和亮像素变亮。
之前我使用过Tensorflow的对比度调整,所以我使用其中的公式:
float_image = image / 255.0 # image must be float!!
mean = np.mean(image, axis=-1) # compute mean values over each channel
new_image = (image - mean) * contrast_coeff + mean # change contrast
另外,您可能希望将结果转换为int,因此最好将值切割为0到1以下的值。可以对其进行归一化,也可以只裁剪:
new_image = np.clip(new_image, a_min=0., a_max=1.) # cut values under 0 and over 1
如您所见,所有这些都不使用OpenCV,而是使用NumPy,所以我希望它适合您的需求。
此外,您可能想了解其中的不同对比度公式:https://en.wikipedia.org/wiki/Contrast_(vision)
答案 1 :(得分:0)
这是使用skimage rescale_intensity的一种简单方法。您提供要成为min = 0和max = 255输出值的最小和最大输入值,并对所有图像值进行线性调整。这是两个示例:
输入:
import cv2
import numpy as np
import skimage.exposure
# load image with alpha channel
img = cv2.imread('lena.png')
# adjust just the input max value
out1 = skimage.exposure.rescale_intensity(img, in_range=(0,128), out_range=(0,255))
cv2.imwrite('lena_stretch_0_128.png', out1)
# adjust both the input min and max values
out2 = skimage.exposure.rescale_intensity(img, in_range=(64,192), out_range=(0,255))
cv2.imwrite('lena_stretch_64_192.png', out2)
cv2.imshow('Out1', out1)
cv2.imshow('Out2', out2)
cv2.waitKey(0)
cv2.destroyAllWindows()
Out1(仅调整输入的最小值):
Out2(同时调整输入的最小值和最大值):
答案 2 :(得分:0)
这里是调整亮度和对比度作为参数的一种非常数学直接的方法。对比度控制输出值与输入值的关系图中直线方程的斜率。截距取决于亮度和对比度。亮度控制直线斜率的枢轴点,以使所需结果越亮,枢轴点就越高。这是提供bri和con参数的代码,这些参数可以在-100到100的范围内更改,但是受限制以使对比度不能反转。 bri = 0和con = -100的值将使图像去饱和,使其完全处于中间灰色。 bri = 100和con = -100的值将产生纯白色图像。同样,bri = -100和con = -100将产生纯黑色图像。所以bri和con值就像百分比变化。因此,bri = 0和con = 0对输入没有影响。
输入:
import cv2
import numpy as np
import math
# load image with alpha channel
img = cv2.imread('lena.png')
# define desired brightness and contrast change values
bri = 20
con = 20
# compute slope and intercept
diffcon = (100 - con)
if diffcon <= 0.1: con=99.9
arg = math.pi * (((con * con) / 20000) + (3 * con / 200)) / 4
slope = 1 + (math.sin(arg) / math.cos(arg))
if slope < 0: slope=0
pivot = (100 - bri) / 200
intcpbri = bri / 100
intcpcon = pivot * (1 - slope)
intercept = (intcpbri + intcpcon)
# print slope and intercept
print(slope, intercept)
# apply slope and intercept
img = img/255.0
out = slope * img + intercept
out[out>1] = 1
out[out<0] = 0
# display IN and OUT images
cv2.imshow('IN', img)
cv2.imshow('OUT', out)
cv2.waitKey(0)
cv2.destroyAllWindows()
# save output image
out = 255.0 * out
out = out.astype(int)
cv2.imwrite('lena_bc_20_20.png', out)