这是一个简单的尝试,将内部区域的平均值与外部区域的平均值匹配。它不能很好地工作,因为它是全局变化并且没有考虑整个图像的亮度变化。但是你可以玩弄它来开始。
它获取一个掩码图像并获取内部和外部区域的均值。然后获取差值并从内部区域中减去。
输入:
import cv2
import numpy as np
# load image
img = cv2.imread('writer.jpg', cv2.IMREAD_GRAYSCALE)
# rectangle coordinates
x = 61
y = 8
w = 663
h = 401
# create mask for inner area
mask = np.zeros_like(img, dtype=np.uint8)
mask[y:y+h, x:x+w] = 255
# compute means of inner rectangle region and outer region
mean_inner = np.mean(img[np.where(mask == 255)])
mean_outer = np.mean(img[np.where(mask == 0)])
# compute difference in mean values
bias = 0
diff = mean_inner - mean_outer + bias
# print mean of each
print("mean of inner region:", mean_inner)
print("mean of outer region:", mean_outer)
print("difference:", diff)
# subtract diff from img
img_diff = cv2.subtract(img, diff)
# blend with original using mask
result = np.where(mask==255, img_diff, img)
# save resulting masked image
cv2.imwrite('writer_balanced.jpg', result)
# show results
cv2.imshow("IMAGE", img)
cv2.imshow("MASK", mask)
cv2.imshow("RESULT", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
mean of inner region: 195.44008004122423
mean of outer region: 154.1415758021116
difference: 41.298504239112646
结果:
您可以更改偏差以使内部区域整体更亮或更暗。
添加
这是下一个改进顺序。只需测量彼此靠近的内部和外部最暗区域,然后对最亮区域执行相同操作。然后从测量中计算强度的线性变换并应用于图像。然后使用遮罩来混合两个图像。
这类似于@Christoph Rackwitz 提出的建议。除了他做了非常严格的计算,我只是做了一些视觉测量。
例如,这里是我测量的地方:
import cv2
import numpy as np
# load image
img = cv2.imread('writer.jpg', cv2.IMREAD_GRAYSCALE)
# rectangle coordinates
x = 62
y = 8
w = 662
h = 401
# create mask for inner area
mask = np.zeros_like(img, dtype=np.uint8)
mask[y:y+h, x:x+w] = 255
# measure darkest and lightest neighboring regions inside and outside mask area of input
# darkest from chair in lower right
# brightest from background wall in upper left
in1=95
out1=8
in2=250
out2=250
# compute linear transformation equation coefficients
# let x1=in1, y1=out1, x2=in2, y2=out2
# y1=a*x1+b
# y2=a*x2+b
# y2-y1 = a*(x2-x1)
# a = (y2-y1)/(x2-x1)
# b = y2 - a*x2
x1 = in1
y1 = out1
x2 = in2
y2 = out2
a = (y2-y1)/(x2-x1)
b = y2 - a*x2
print("a:", a, "b:", b)
# process image with linear transformation
modified = (a * img.astype(np.float64) + b).clip(0,255).astype(np.uint8)
# blend with original using mask
result = np.where(mask==255, modified, img)
# save resulting masked image
cv2.imwrite('writer_balanced2.jpg', result)
# show results
cv2.imshow("IMAGE", img)
cv2.imshow("MASK", mask)
cv2.imshow("RESULT", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果: