直方图均衡化处理的“中心思想”是把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布。直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同。
我们来看一个灰度图像,让表示灰度出现的次数,这样图像中灰度为 的像素的出现概率是
是图像中所有的灰度数, 是图像中所有的像素数, 实际上是图像的直方图,归一化到 。
把 作为对应于 的累计概率函数, 定义为:
是图像的累计归一化直方图。
我们创建一个形式为 的变化,对于原始图像中的每个值它就产生一个 ,这样 的累计概率函数就可以在所有值范围内进行线性化,转换公式定义为:
注意 T 将不同的等级映射到 域,为了将这些值映射回它们最初的域,需要在结果上应用下面的简单变换:
上面描述了灰度图像上使用直方图均衡化的方法。
(以上内容摘自维基百科)
用FPGA实现直方图操作的思路如下:
1)构建大小为256、深度为19的数组cnt。cnt[ i ]的作用和px(i)类似,所不同的是,在每一帧图像中,cnt[ i ]并不是一个概率值,而是用来表示灰度值为 i 的像素个数。之所以深度为19,是因为cnt可能的最大值为640*480。
2)构建大小为256、深度为27的数组sum。sum[ i ]的作用和c(i)类似,用来表示cnt[ i ]的累加和。例如,sum[5] = cnt[ 0 ] + cnt[ 1 ] + cnt[ 2 ] + cnt[ 3 ] + cnt[ 4 ];
3)当扫描至图像(0,0)点时,所有256个cnt清零;
4)在扫描图像过程中(除了第一个点以及最后一个点),构建case语句,根据输入的灰度值i,对cnt进行如下操作:cnt[ i ] <= cnt[ i ]+1;
输出像素值 <= sum[i]*255/(640*480);
5)当扫描至图像最后一个像素点时,对sum进行如下操作:
sum[ i ] = cnt[ 0 ] + cnt[ 1 ] + cnt[ 2 ] +……+cnt[ i-1 ] ;
整理思路后,发现写verilog并不是难事,只是重复的代码量比较大而已。
最后,附上源码链接:http://u.download.csdn.net/upload/success