Python分段线性函数
Henry_zs 人气:01. 分段线性函数介绍
分段线性函数同样是点运算,基于像素的图像增强,也就是对比度拉伸。
大概的原理就是:将不同灰度区间的灰度值经过不同的映射函数映射到另一个灰度区间的过程。
因为使用变换函数的个数是三个,所以我们经常使用的分段线性函数是三段线性变换函数
对应的数学公式为
- a = 1 ,b = 0 时,恒等函数,不改变图像的灰度值
- a >1, 对比度增强
- 0 < a < 1 , 对比度减弱
- b 控制图像的亮度,b > 0 图像变亮,b < 0 图像变弱
对比度:定义为图像中最高和最低灰度级之间的灰度差
但没有真正意义上的计算公式,只是大概意思的表示
如果一副图像灰度的动态范围具有高的动态范围,那我们就认为这幅图像的对比度高
2. 代码实现
import numpy as np import cv2 def linear_transform(img): height,width = img.shape[:2] r1,s1 = 80,10 r2,s2 = 140,200 k1 = s1 / r1 # 第一段斜率 k2 = (s2 - s1) / (r2 - r1) # 第二段斜率 k3 = (255 - s2) / (255 - r2) # 第三段斜率 img_copy = np.zeros_like(img) for i in range(height): for j in range(width): if img[i,j] < r1 : img_copy[i,j] = k1 * img[i,j] elif r1 <= img[i,j] <= r2: img_copy[i,j] = k2 * (img[i,j] - r1) + s1 else: img_copy[i,j] = k3 * (img[i,j] - r2) + s2 return img_copy img = cv2.imread('./img.png',0) ret = linear_transform(img) cv2.imshow('img',np.hstack((img,ret))) cv2.waitKey() cv2.destroyAllWindows()
处理结果为
这里代码的实现较为简单,不再赘述,单纯的取图像的像素点然后进行映射而已。
3. other
说说中间两个分段点怎么取值的问题
因为通过观察原图发现,图像整体灰度值偏低,所以我们将原图(0-80)的灰度值压缩到(0-10)范围内,再将中间的(80-140) 灰度值放大,就可以将中间的对比度拉大
书上的分段点取得是(r1,s1) = (r.min , 0) , (r2,s2) = (r.max , 255)
只需要将上面的代码改成这样,就可以得到下面的图片
但是这种方法可能不是很泛化,因为观察这幅图片的直方图可以发现,原图片的低灰度值和高灰度值都是没有的。而往往大多数的图片动态范围都是(0,255)。如果按照书上的进行,就会变成
(r1,s1) = (0, 0) , (r2,s2) = (255 , 255),就变成y = x的恒等变换了
最后,因为观察直方图,可以知道,在80-90 左右 的左侧像素值均为背景信息,我们可以进行压缩对比度。而在 90-130 中间灰度占比多,为前景信息,我们可以进行对比度拉伸
上面的分段点就是观察直方图得出来得值
- 所以分段线性函数的分段点可以通过直方图简单得到
- 分段线性变换可以不是连续的
加载全部内容