数字图像灰度变换(基于opencv)

空间域指的是图像平面本身,空间域中的图像处理方法直接对图像中的像素进行处理。灰度变换是一种常见的数字图像处理技术,旨在空间域中调整图像像素的灰度值,以改善图像质量或实现特定的视觉效果。

在空间域处理基于:

g(x,y)=T[f(x,y)]

 其中,f(x,y)是输入图像,g(x,y)是输出图像,T是在点(x,y)领域上定义的针对f的变换矩阵(算子)。

1. 图像反转

图像反转变换是常见的线性变换,图像反转变换函数:s=L-1-r

归一化后的反转变换函数图像:

通过这个函数得到的灰度级在[0,L-1],类似于胶片的感觉。

L = 256
conv_img = L - 1 - image_grey

2. 对数变换

不满足加性和同质性的变换是非线性变换,对数变换是常用的数字图像非线性变换,对数变换的通式是:s=clog(1+r),其中c是常数,并假设r\geq 0

c = 0.17
f_img = image_grey.astype(np.float32)
log_img = c * np.log(1 + f_img)

对数变换是对原图的逐像素实现对数变换的映射,由对数函数的趋势可知,斜率单调递减,因此对于数字图像处理来说,可以扩展低亮度区域,压缩高亮度区域,从而提高图像的可视化效果。

3. 伽马变换

伽马变换的形式是:s=cr^{^{\gamma }},其中c\gamma都是正常数。

考虑到偏移时,也可以写为:s=c(r+\varepsilon )^{\gamma }

伽马变换可以改变图像的对比度:

\gamma > 1:使暗区更暗,亮区更亮; \gamma < 1:使暗区更亮,亮区压缩;c=\gamma =1:恒等变换。

def gamma_transformation(image, gamma):
    # 归一化图像
    normalized_img = image / 255.0
    # 伽马变换
    gamma_corrected = np.power(normalized_img, gamma)
    # 还原到 [0, 255] 并转换为 uint8 类型
    result = np.uint8(gamma_corrected * 255)
    return result

如果是三通道彩色数字图像,需要对每个通道都进行变换

def gamma_transformation_color(image, gamma):
    normalized_img = image / 255.0
    gamma_corrected = np.power(normalized_img, gamma)
    result = np.uint8(gamma_corrected * 255)
    return result

gamma_values = [0.4, 0.7, 1.0, 1.5, 2.0]
image_brg = cv2.cvtColor(image_brg, cv2.COLOR_BGR2RGB)

plt.figure(figsize=(10, 7),dpi=300)
plt.subplot(2, 3, 1)
plt.title('Original Image', fontsize=16)
plt.imshow(image_brg)
plt.axis('off')

for i, gamma in enumerate(gamma_values):
    transformed_img = gamma_transformation_color(image_brg, gamma)
    plt.subplot(2, 3, i + 2)
    plt.title(f'Gamma = {gamma}', fontsize=16)
    plt.imshow(transformed_img)
    plt.axis('off')
plt.tight_layout()
plt.show()

4. 分段线性变换

分段线性变换通过将输入灰度值映射到不同的区间,使图像的亮度和对比度得到调整。其原理是将整个灰度范围划分为若干段,并对每一段应用不同的线性变换,使得灰度值在不同区间内按照相应的线性关系进行映射。分段线性变换函数的优点是其形式可以任意复杂

光照不足、成像传感器的动态范围偏小、图像获取过程中镜头参数的设置不当都有可能导致低对比度图像。对比度拉伸可以扩展灰度级范围,使得图像的灰度级尽可能覆盖整个理想范围。分段线性变换是典型的对比度拉伸方案。

def LF(y1, y2, img):
    k = (y2[1] - y1[1]) / (y2[0] - y1[0])
    b = y1[1] - k * y1[0]
    y = k * img + b
    return np.clip(y, 0, 255)

def SLT(y1, y2, img):
    result = np.zeros_like(img, dtype=np.float32)
    
    a1 = img <= y1[0]
    a2 = (img > y1[0]) & (img < y2[0])
    a3 = img >= y2[0]

    result[a1] = 0
    result[a2] = LF(y1, y2, img[a2])
    result[a3] = 255
    
    return np.uint8(result)


if __name__ == '__main__':
    
    y1 = (np.min(image_gray), 0)
    y2 = (np.max(image_gray), 255)   # 适应性更强的分段点选择
    
    transformed_img = SLT(y1, y2, image_gray)

    plt.rcParams["font.family"] = "Times New Roman"
    plt.figure(figsize=(10, 7), dpi=300)
    plt.subplot(1, 2, 1)
    plt.title("Original Image", fontsize=16)
    plt.axis('off')
    plt.imshow(image_gray, cmap='gray', vmin=0, vmax=255)

    plt.subplot(1, 2, 2)
    plt.title("SLT Image", fontsize=16)
    plt.axis('off')
    plt.imshow(transformed_img, cmap='gray', vmin=0, vmax=255)

    plt.tight_layout()
    plt.show()

最大和最小像素分段点的选择:

  1.  分段点选择简单直观;
  2. 通过将图像的最小灰度值映射为0、最大灰度值映射为255,线性拉伸可以充分利用整个灰度范围,从而增强图像的对比度,改善图像质量;
  3. 最大和最小选择,使得变换可以自适应每张图像的灰度分布,无需人为设定分段点(可视效果不一定最优);
  4. 确保了图像中的最亮和最暗区域的信息不会被裁剪或过度压缩。

上述数字图像的灰度变换均是基于点的图像增强策略,具有通俗易懂和操作简单的优点,但是将二维图像转为数值化矩阵(阵列)会丢失空间信息,并且在给定变换函数时,无法预估变换后的图像是否满足视觉质量要求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值