直方图线性拉伸相对于直方图均衡化来说就更好理解一些了,即用线性变化将灰度直方图较窄的部分拉伸至整个区间,增强整幅图像的对比度。
线性拉伸的效果如下图所示,可以看出图像对比度有所改善,保留了直方图基本的轮廓,同时将直方图范围拉伸至0~255。
图 1 直方图拉伸效果图
算法也比较容易理解,f(x,y)为输入图像,得到输出图像g(x,y)
其中A和B可以分别定义为图像的最小灰度值与最大灰度值,即
但是实际应用中并不会直接采用上述的A和B,这是由于图像中可能存在噪声的原因。想象如果图像中存在几个纯白点(255)和纯黑点(0),那么拉伸后的效果就无法达到预期。
因此我们人为的设定两个阈值Thr_Min和Thr_Max,拉伸系数A,B定义如下:
其中∑H(k)为灰度直方图累计和。下图更直观的表示了A和B的取值,Thr_ Min和Thr_Max是蓝色部分的面积。
图 2 A,B系数的定义
系统框架
图 3 直方图线性拉伸系统框架
上图可以看出,前半部分的直方图统计电路和上篇均衡化完全一样,只是对后半部分的电路做了些修改。计算直方图线性拉伸后的像素值的步骤如下:
1. 统计第一帧图像的灰度直方图
2. 计算直方图累计和
3. 由阈值Thr_Min和Thr_Max算出拉伸系数A,B
4. 第二帧图像灰度值带入公式计算后输出
和直方图均衡化一样,这里我们不考虑帧缓存的问题,也就是前一帧的A,B作为当前帧A,B来使用。
代码分析
A,B系数的计算
hist_cnt为计算出的累计和(与直方图均衡化中的求法一样),当累计和大于阈值的时候,记录下此时累计和对应的地址out_pixel[8:1](即灰度值),作为我们的拉伸系数A,B,同时设置取得系数标志get_max或get_min为1。最后要在第二帧累计和到来时,清零A,B及get标志。
2. B-A的计算
取得系数B后(get_max=1),即可计算出B-A 。
3. f(x,y)-A (第一级流水)
当f(x,y)小于系数A时,直接令f(x,y)-A=0;当f(x,y)大于系数B时,直接令f(x,y)-A=B-A。
4. [f(x,y)-A ]*255 (第二级流水)
5.[f(x,y)-A ]*255/(B-A) (第三级流水)
实验结果
图 4 原图 图 5 阈值为100时处理后的图像
有没有觉得这两幅图并没有什么差别,小编也纳闷了很久。之前有提到过噪声可能对直方图线性拉伸的影响,下面是将阈值Thr_Min调高至1000后得到的结果。
图 6 阈值为1000时处理后的图像
可以看出直方图线性拉伸需要人为的调整阈值的大小,才能达到理想效果。而直方图均衡化则不需要。