我想在 OpenCV 中将图像的亮度调整到某个值。例如,考虑这张图片:
我用以下方法计算亮度:
import cv2
img = cv2.imread(filepath)
cols, rows = img.shape
brightness = numpy.sum(img) / (255 * cols * rows)
我得到的平均亮度为 35%。例如,要将其提高到 66%,我会这样做:
minimum_brightness = 0.66
alpha = brightness / minimum_brightness
bright_img = cv2.convertScaleAbs(img, alpha = alpha, beta = 255 * (1 - alpha))
我得到一张似乎有 50% 透明度面纱的图像:
我可以通过仅使用偏差来避免这种影响:
bright_img = cv2.convertScaleAbs(img, alpha = 1, beta = 128)
而且图像似乎也有面纱:
如果我手动完成,例如在 Photoshop 中将亮度调整为 150,结果似乎还不错:
但是,这不是自动的,也不会给出目标亮度。
我可以通过伽玛校正和/或直方图均衡来实现,以获得更自然的结果,但除了反复试验之外,我没有看到获得目标亮度的简单方法。
有没有人成功地将亮度自动调整到目标?
更新
卡纳特建议:
bright_img = cv2.convertScaleAbs(img, alpha = 1, beta = 255 * (minimum_brightness - brightness))
结果更好但仍然有面纱:
Yves Daoust 建议保留 beta = 0
,所以我调整了 alpha = minimum_brightness / brightness
以获得目标亮度:
ratio = brightness / minimum_brightness
if ratio >= 1:
print("Image already bright enough")
return img
# Otherwise, adjust brightness to get the target brightness
return cv2.convertScaleAbs(img, alpha = 1 / ratio, beta = 0)
结果很好:
原文由 miguelmorin 发布,翻译遵循 CC BY-SA 4.0 许可协议
您可以尝试使用带有直方图裁剪的对比度优化来自动调整亮度。您可以通过增加直方图剪辑百分比 (
clip_hist_percent
) 来增加目标亮度。这是 25% 裁剪的结果自动计算 Alpha 和 Beta
这是剪辑的可视化。蓝色(原始),橙色(自动调整后)。
剪裁为 35% 的结果
其他方法可以使用 直方图均衡或 CLAHE 。
另一种版本是使用饱和度算法而不是使用 OpenCV 的
cv2.convertScaleAbs
向图像添加偏差和增益。内置方法不采用绝对值,这会导致无意义的结果(例如,使用 alpha = 3 和 beta = -210 的 44 像素在 OpenCV 中变为 78,而实际上它应该变为 0)。