使用线性变换改变图像的亮度/对比度

1,855 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情

前言

对比度、亮度增强技术是两种非常常见技术,这些技术是在许多图像处理任务(例如,图像分类)中使用预处理步骤。在本节中,我们将学习如何使用 OpenCV 库来修改图像的对比度和亮度。

使用线性变换改变图像的亮度/对比度

乘法和加法是两种常用的图像操作运算,使用这两种运算可以组成基本线性变换:g(x)=αf(x)+βg(x)=αf(x)+β,其中常数参数 α>0α>0ββ 通常分别称为对比度(增益)和亮度(偏置)参数。可以将 f(x)f(x) 视为源图像像素,而 g(x)g(x) 则是输出图像像素,因此,我们可以将表达式改写为 g(i,j)=αf(i,j)+βg(i,j)=α·f(i,j)+β,其中 iijj 表示像素位于第 ii 行和第 jj 列中。在本节中,我们将学习如何使用 OpenCVconvertscaleabs() 实现基本线性变换,并观察其对图像的影响,该函数用法如下:

cv2.convertScaleAbs(src, alpha, beta)

在输入图像的每个通道上,该函数顺序执行三个操作,缩放,计算绝对值,转换为无符号的 8 位类型(对于输入图像 srcsrc,返回的输出图像是 srcalpha+betasrc*alpha+beta)。

幂转换也称为 gamma 校正,当 γ>1γ>1 时图像将转移到频谱的黑色端,而在 γ<1γ<1 时会使图像显得偏淡,使用 LUT() 函数可以将图像的查找表更改为具有幂转换的新图像,该用法函数如下:

cv2.LUT(src, lut)

首先导入所需的库和函数,并加载输出图像,然后使用 OpenCV 函数定义函数 basic_linear_transform()gamma_correction() 分别实现对比度修改和伽马校正:

import cv2
import numpy as np
import matplotlib.pylab as plt

alpha, beta, gamma = 1, 0, 1

def basic_linear_transform(img, alpha, beta):
    return cv2.convertScaleAbs(img, alpha=alpha, beta=beta)

def gamma_correction(img, gamma):
    lookup_table = np.empty((1,256), np.uint8)
    for i in range(256):
        lookup_table[0,i] = np.clip(pow(i / 255.0, gamma) * 255.0, 0, 255)
    return cv2.LUT(img, lookup_table)

image = cv2.imread('1.png')

用不同的 alphagamma 值调用函数 basic_linear_transform() 以改变输入图像的亮度,并绘制输出图像:

plt.figure(figsize=(20,20))
i = 1
for alpha in [0.25, 0.5, 1, 1.5, 2.5]:
    for beta in [0, 0.5, 1, 1.5, 2]:
        image_corrected = basic_linear_transform(image, alpha, beta)
        plt.subplot(5,5,i), plt.imshow(cv2.cvtColor(image_corrected, cv2.COLOR_BGR2RGB)), plt.axis('off')
        plt.title(r'$\alpha$={:.2f}, $\beta$={:.2f}'.format(alpha, beta), size=10)
        i += 1
plt.suptitle('Basic linear transform to change brightness', size=20)
plt.show()

Figure_29.png

用不同的 gamma 参数值调用函数 gamma_correction(),并绘制输出图像:

plt.figure(figsize=(20,20))
i = 1
for gamma in np.linspace(0, 2, 16):
    image_gamma_corrected = gamma_correction(image, gamma)
    plt.subplot(4,4,i), plt.imshow(cv2.cvtColor(image_gamma_corrected, cv2.COLOR_BGR2RGB)), plt.axis('off')
    plt.title(r'$\gamma$={:.2f}'.format(gamma), size=10)
    i += 1
plt.suptitle('Gamma correction', size=20)
plt.show()

Figure_30.png