常见图像增强(python 实现)

本文介绍了图像处理中的反色、对数和伽马变换,用于增强图像细节和调整动态范围。反色变换用于反转图像灰度,对数变换压缩动态范围,伽马变换则通过幂函数调节对比度。伽马变换常用于校正CRT显示器的非线性输出。文中还提供了代码示例,并讨论了分段线性变换作为伽马变换的补充。
摘要由CSDN通过智能技术生成

反色变换

推荐B站UP,十四阿哥很nice
几节图像处理课讲的很清楚。
用于增强暗背景下的图像,使人眼能够观看到更多细节。
假设原始图像的灰度范围是[0,L],L表示该图像最大的灰度值,则反色变换为output = L - input

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

# 1,反色变换
# 假设原始图像的灰度范围是[0,L],L表示该图像最大的灰度值
# 则反色变换为output = L - input

def image_inverse(input):
    value_max = np.max(input)
    output = value_max - input
    return output

gray_img = np.asarray(Image.open('X.jpg').convert('L'))
inv_img = image_inverse(gray_img)

plt.subplot(121)
plt.title('original')
plt.imshow(gray_img, cmap='gray', vmin=0, vmax=255)

plt.subplot(122)
plt.title('inverse')
plt.imshow(inv_img, cmap='gray', vmin=0, vmax=255)
plt.show()

在这里插入图片描述

对数变换

对数变换,目的是压缩图像矩阵值域的动态范围,让我们可以看到更多细节
假设原始图像灰度取值范围是[x1,x2], (x1>=x2>=0)
则对数变换为 output = log(1 + input)
log输入为0时输出为负无穷,+1就是为了避免此情况(或者理解为偏置)

imshow绘图时,若不指定vmin,vmax,默认输入最小值为vmin对应0,vmax对应255

def set_Chinese():
    import  matplotlib
    matplotlib.rcParams['font.sans-serif'] = ['SimHei']
    matplotlib.rcParams['axes.unicode_minus'] = False

def image_log(input):
    return np.log(1 + input)

set_Chinese() # 解决中文乱码问题
input = np.array([[10, 150],
                  [250, 25500]])
output = image_log(input)
fig = plt.figure()
ax1 = fig.add_subplot(121)
ax1.set_title('对数变换前', fontsize=12)
ax1.imshow(input, cmap='gray', vmin=0, vmax=25500)

ax2 = fig.add_subplot(122)
ax2.set_title('对数变换后', fontsize=12)
ax2.imshow(output, cmap='gray')
plt.show()

在这里插入图片描述

伽马变换

又称幂律变换,因为使用幂函数来操作输入图像,表达式

  • gamma次幂称为伽马系数,在伽马变换中规定这个数必须为正数
  • eps 称为补偿系数,默认0(如果没有eps,当input中有为0时,对该像素的伽马变换就失效了,0的任意次幂都为0)

但幂运算又导致图像输出动态范围过大,引入归一化(8bit像素):

def gamma_trans(input, gamma=2, eps=0):
    return 255.*(((input + eps) / 255.) ** gamma)


def update_gamma(val):
    gamma = slider1.val
    output = gamma_trans(input_arr, gamma=gamma, eps=0.5)
    print('------------\n', output)
    ax1.set_title('伽马变换后,gamma = ' + str(gamma))
    ax1.imshow(output, cmap='gray', vmin=0, vmax=255)


set_Chinese()
input_arr = np.array([[0, 50, 100, 150],
                    [0, 50, 100, 150],
                    [0, 50, 100, 150],
                    [0, 50, 100, 150]])

fig = plt.figure()
ax0 = fig.add_subplot(121)
ax0.set_title('输入矩阵')
ax0.imshow(input_arr, cmap='gray', vmin=0, vmax=255)

ax1 = fig.add_subplot(122)

plt.subplots_adjust(bottom=0.3)  # 划分一块滑动条,从底部向上30%
# 设置属性和颜色
s1 = plt.axes([0.25, 0.1, 0.55, 0.03], facecolor='lightgoldenrodyellow')
# 创建滑动条,范围0-2,初始为1,步长0.1
slider1 = Slider(s1, '参数gamma', 0.0, 2.0, valfmt='%.f', valinit=1.0, valstep=0.1)
slider1.on_changed(update_gamma)
plt.show()

在这里插入图片描述
肉眼观测的话gamma(>1)越大图像越黑,gamma(<1)越小图像越亮。
应用:

  • 矫正显示失真

CRT显示器的物理特性导致送入显示器的灰度值并非线性输出,而是以幂函数的形式非线性输出。不同厂家的幂不一样,一般介于1.8-2.5所以我们先对输入做伽马变换,gamma = 1 /(厂家的幂)处理,保证线性输出。

'''
【功能】利用γ变换提前矫正图像,从而实现图像在CRT显示器中正常显示
【B站/YouTube】轩辕十四很nice
【开源协议】The MIT License (MIT)
'''


from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons


def set_chinese():   # 中文显示工具函数
	import matplotlib
	print("[INFO] matplotlib版本为:%s" % matplotlib.__version__)
	matplotlib.rcParams['font.sans-serif'] = ['FangSong']
	matplotlib.rcParams['axes.unicode_minus'] = False

def gamma_trans(input, gamma=2, eps=0 ):
    return 255. * (((input + eps)/255.) ** gamma)

def crt_distortion(input, gamma=2):  # 模拟CRT失真(做了归一化)
    return 255. * ((input/255.) ** gamma)


def update_gamma(val):

    gamma = slider1.val  # 获取"失真γ"


    # 图像送入CRT前,先做伽马变换预处理
    gamma_ = 1 / gamma   #  "矫正γ" 为 "失真γ" 的倒数
    correct_img = gamma_trans(gray_img, gamma_, 0)  #
    ax1.set_title("伽马矫正,矫正γ = 1/" + str(round(gamma,2)))
    ax1.imshow(correct_img, cmap='gray',vmin=0,vmax=255)

    # 简易模拟CRT输出
    output = crt_distortion(correct_img, gamma)
    print(output)
    ax2.set_title("模拟CRT输出,失真γ = " + str(round(gamma,2)))
    ax2.imshow(output, cmap='gray',vmin=0,vmax=255)


if __name__ == '__main__':
    set_chinese()

    gray_img = np.asarray(Image.open('./intensity_ramp.tif').convert('L'))

    fig = plt.figure()
    ax0 = fig.add_subplot(131)
    ax1 = fig.add_subplot(132)
    ax2 = fig.add_subplot(133)


    ax0.set_title("原始图片")
    ax0.imshow(gray_img, cmap='gray',vmin=0,vmax=255)


    plt.subplots_adjust(bottom=0.3)
    s1 = plt.axes([0.25, 0.1, 0.55, 0.03], facecolor='lightgoldenrodyellow')
    slider1 = Slider(s1, 'CRT失真γ: ', 0.0, 4.0,
                      valfmt='%.f', valinit=1.0, valstep=0.1)
    slider1.on_changed(update_gamma)
    slider1.reset()
    slider1.set_val(2)

    plt.show()

在这里插入图片描述

数学原理:

伽马变换可以调节图片对比度,进而体现更多细节。

  • gamma < 1,提亮图像,扩展暗部的动态范围,压缩亮部的动态范围
  • gamma > 1,变暗图像,压缩暗部动态范围,扩展亮部动态范围

伽马变换:通过幂函数扩展后的动态范围没有变,只是改变了直方图的数据分布。
在这里插入图片描述
但伽马变换的曲线总是存在斜率约等于1的部分,如果图片的像素分布落在斜率等于1的区间,伽马变换的效果就比较微弱了。
所以引入分段线性变换

分段线性变换

顾名思义,是个分段函数,分多少段也看需求。假设分成三段。
在这里插入图片描述

  • 11
    点赞
  • 105
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: 对数变化是一种常见图像增强方法,通过将原始图像的像素值取对数来增强图像的对比度。Python中可以使用OpenCV库来实现对数变化图像增强。 首先,需要导入OpenCV库: ```python import cv2 import numpy as np ``` 然后,读取图像并将其转换为灰度图像: ```python image = cv2.imread('input.jpg') gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) ``` 接下来,对灰度图像进行对数变化: ```python # 对数变化 enhanced_image = np.log1p(gray_image) enhanced_image = cv2.normalize(enhanced_image, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U) ``` 最后,显示增强后的图像并保存: ```python cv2.imshow('Enhanced Image', enhanced_image) cv2.imwrite('output.jpg', enhanced_image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在这个代码段中,对数变化使用了NumPy库中的`np.log1p`函数,它将图像的像素值取对数压缩到[0, 255]的范围内,并使用OpenCV的`cv2.normalize`函数将结果映射到[0, 255]的像素范围内。 以上就是使用Python实现对数变化图像增强的步骤。 ### 回答2: 对数变化是一种常用的图像增强技术,用于增加图像的对比度和细节。Python提供了一种简单的方式来实现对数变化图像增强。 首先,我们需要导入Python图像处理库,例如OpenCV或PIL。这里以OpenCV为例: ``` import cv2 import numpy as np ``` 然后,我们需要加载图像并将其转换为灰度图像,因为对数变化只能用于灰度图像: ``` img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE) ``` 接下来,我们可以使用以下公式来对图像进行对数变化: ``` enhanced_img = c * np.log(1 + img) ``` 其中,c是常数,用于调整对比度和亮度。通常情况下,c的取值范围为1-255。 最后,我们可以将增强后的图像保存到本地: ``` cv2.imwrite('enhanced_image.jpg', enhanced_img) ``` 完整的代码如下: ``` import cv2 import numpy as np img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE) enhanced_img = c * np.log(1 + img) cv2.imwrite('enhanced_image.jpg', enhanced_img) ``` 这样,我们就可以使用Python实现对数变化图像增强了。可以根据具体的需求调整参数c来获得更好的增强效果。 ### 回答3: 对数变化图像增强是一种常用的图像处理方法,通过对图像像素值进行对数变换,可以增强图像的对比度并减少图像中央灰度级别的压缩。下面是使用Python实现对数变化图像增强的步骤: 1. 导入所需的库:首先,我们需要导入PIL库(Python Imaging Library)和NumPy库,用于图像处理和矩阵计算。 2. 读取图像:使用PIL库的Image模块打开待处理的图像,并将其转换为NumPy数组。 3. 对数变换:对图像的每个像素值进行对数变换。假设原始像素值为x,变换后的像素值y可以通过公式y = c * log(1 + x)计算得到,其中c是一个常数或系数,用于调节对比度。 4. 像素值调整:由于对数变换会使较暗像素值变得更明亮,较亮像素值变得更暗,因此可能会导致图像部分细节的丢失。为了避免这种情况,可以对变换后的像素值进行调整,确保它们在0到255的范围内。 5. 显示和保存图像:最后,将处理后的图像显示出来,并可以选择将其保存到本地文件。 总结起来,使用Python实现对数变化图像增强的步骤包括导入库、读取图像、对数变换、像素值调整以及显示和保存图像。通过调节对数变换的参数,可以根据具体需求增强图像的对比度。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JiYH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值