直方图概念和分类
图像直方图用作数字图像中色调分布的图形表示。它绘制了每个色调值的像素数。通过查看特定图像的直方图,观看者将能够一目了然地判断整个色调分布。
图表的水平轴代表色调变化,而垂直轴代表该特定色调的像素总数。
水平轴的左侧表示暗区,中间表示中间色调值,右侧表示亮区。纵轴表示在每个区域中捕获的区域大小(像素总数)。
因此,非常暗图像的直方图的大部分数据点将位于图的左侧和中心。
相反,具有很少黑暗区域或阴影的非常明亮的图像的直方图的大部分数据点将位于图的右侧和中心。
在FPGA处理中常用的是灰度直方图,灰度直方图描述了一幅图像的灰度级统计信息,主要应用于图像分割、图像增强及图像灰度变换等处理过程。
而FPGA对于直方图处理主要分为以下三种:
我们常见或者听说的直方图概念主要指直方图均衡,这也是最简单的一种方式,常见某些入门级的图像处理书籍或者文章。直方图规定化和直方图拉伸我们后面慢慢介绍,先重点介绍直方图均衡。公众号:OpenFPGA
直方图统计及FPGA实现
从数学上来说,图像直方图描述的是图像各个灰度级的统计特性,它是用图像灰度值的一个函数来统计一幅图像中各个灰度级出现的次数或概率,其数学定义如下所示:公众号:OpenFPGA
直方图统计是比较简单的,将彩色图像转成灰度图像后就可以统计了,伪代码如下:公众号:OpenFPGA
go
unsigned int pHistCnt[256];
int i,j =0;
memset(pHistCnt,0,256);
for( i=0;i<m dwHeight; i++)
for( j=0;j<m_dwWidth;j++)
pHistCnt[m_pBitmap[i*mdwWidth+j]]++;//统计打开图像中各个灰度像素点个数
上面的代码就是遍历图像将数据存储到数据里即可。
上图中右边是左边图像的直方图统计。
实际用FPGA实现的时候一般会用到归一化的直方图,即不关心实际每个灰度值的具体值而是出现的概率。具体为假定一幅图像的像素个数为N(N=图像长度*图像宽度),灰度级总数为L(级数和图像的位数有关,假定是8位图像,则总数为2^8=256),这时候图像中灰度级l(小L)的像素总数为 。每个灰度级除以总像素数即得到各个灰度级出现的概率:公众号:OpenFPGA
上面的公式有个别称:直方图概率密度函数(也称归一化的灰度直方图),记为PDF
直方图统计完能干嘛呢?很明显的是从直方图中能读取到图像的亮度和对比度信息。若直方图的统计主要偏向右侧分布,那么图像相对较亮;反之亦然。当直方图统计分布比较均匀时,这时候图像的对比度较大,若直方图统计分布比较集中时,则图像对比度较小。公众号:OpenFPGA
下面几张图说明了上面的结论:
较暗的图像,同时对比度较低 较亮的图像,同时对比度较低 对比度很高的图像
FPGA功能分析
对于FPGA进行直方图操作的时候有两种方式,一种是真操作,一种是伪操作:真操作就是将图像缓存后进行后续处理(均衡等),然后再将图像发送出去;伪操作就是将图像流水过后将需要的信息进行缓存,然后在下一幅图像来之后,将前一副图像得到的信息作用于当前图像。由于常用的操作是基于视频帧,避免视频延迟过大,所以我们一般常用伪操作,即缓存当前帧信息后作用后一帧图像。
上面的特点我们一般选择片内双口 RAM 作为缓存存储器。对于 8 位的深度图来说,统计结果的数据量并不大,因此选择片内存储。此外,一方面统计模块需要与其他时序进行配合,因此需提供双边读写接口;另一方面,统计过程中需要地址信息,因此选择 RAM 形式的存储器。
基上,直方图统计步骤如下:
-
将当前统计值读出,加 1 后重新写入 RAM
-
重复以上步骤,直到当前图像统计完毕
-
在下一幅图像到来之前将结果读出
-
读出之后对 RAM 内容进行清零
因此,我们需要三个电路完成直方图统计:统计电路、读出电路和清零电路。
关于这三个电路设计我们下期文章再详细介绍。
FPGA电路设计
FPGA代码设计
思考
若图像直方图是分段式集中应该怎么处理比较合适?