获取32R的图像的直方图的一个算法

来源:互联网 发布:淘宝aⅴ视频分类 国产 编辑:程序博客网 时间:2024/06/12 21:46
                                                                               朱金灿
 
        在求非8U类型的图像数据的直方图时一般采用拉伸到0到255范围。但是这样做的一个很大弊端是造成图像信息丢失(因为从0到几万拉伸到0到255,信息丢失是肯定的)。
为了防止信息丢失,现在需要在不对图像拉伸的情况下求取32R数据的直方图。
 
毫无疑问,你不能开辟一个大数组去保存所有像素值的个数,因为一则2的32次方数值4294967296,估计编译器不允许开辟这样大的内存,二则32R的图像的像素值范围就是0到几万,开辟这么大的数组去保存无疑是浪费内存。那么开辟一个几万的数组去保存是否就是合适呢?也不合适,首先32R的图像存在像素值是负数的情况,这样数组下标号和像素值无法对应起来,这样就无法将像素值和像素个数联系起来,其次虽然32R的图像的像素值范围就是0到几万,但是在很多情况下实际的像素级只有几百或几千个,开辟一个几万的数组依然存在浪费内存的问题。
 
为此需要使用一个数据结构将像素值和像素个数联系起来。开始我设想使用STL的map,以像素值为键,像素个数为键值,后来我发现和算法结合起来map显得效率很低。
 
为此我设计了一个结构体:
struct GrayMap
{
 long PixelValue;   // 像素值
 long PixelNum;   // 对应该像素值的像素个数
};
 
具体算法如下:
1.       遍历图像,获取图像的最大值Max和最小值Min
2.       开辟一个static<long>(abs(Max-Min)) 个GrayMap数组GrayMapVec
3.       再次遍历图像,每读取一个像素值,判断GrayMapVec是否存在这一像素值(需要遍历GrayMapVec数组),若存在,则将其对应元素的像素个数加1,若不存在则将其插入到GrayMapVec,同时记录实际存在的像素级RealPixelGrade。
4.       开辟一个RealPixelGrade个GrayMap的数组RealGrayMapVec,将GrayMapVec的像素个数不为0的元素插入到RealGrayMapVec(此举是为了进一步减少不必要的内存)
 
若使用map作为基本数据结构,瓶颈存在于遍历map。由此我体会到数据结构可能是这样一种东西:你轻易不会遇到这方面的问题,就算遇到了,现成的数据结构也足以解决我们的大多数问题,比如STL、MFC的集合类。但是万一遇到了,很可能是致命的问题,这时你不得不感叹数据结构的重要性了。
 
原创粉丝点击