[db:标题]

摘要:基于局部直方图的算法有很多很多,比如中值模糊、表面模糊、选择性模糊等等,这类算法有个通病,就是即使选择使用SIMD指令加速,因为其内在的特性,速度还是不能很快,但是又找不到其他合适的构架来优化他,还必须使用直方图技术,本文介绍了一种简单的方
基于局部直方图的算法有很多很多,我们已经研究这类算法有以下一些:    1、中值滤波   2、表面模糊   3、选择性模糊   4、中值锐化   5、图像局部熵 这类算法有个通病,就是即使选择使用SIMD指令加速,因为其内在的特性,速度还是不能很快,但是又找不到其他合适的构架来优化他,还必须使用直方图技术,比如我们的中值滤波, 我尝试过各种商业软件,其速度都和我博客里提到的那个优化速度差不多,说明大家基本上都是那个套路。你们当确实某个场景需要更快的速度时,我们是否能有其他方法来加速呢,或者使用某个近似的方法来替代呢,经过个人的实践,我觉得还是可以有的。    一个简单的方法就是减少直方图的数量,常规状态下我们直方图有256个元素,因为基于局部直方图的算法基本都是一些统计类算法,是大面积像素的统计信息,所以最终的结果其实也是个统计结果。那么我们压缩直方图的量级,只要压缩量合理,最后的结果可能差异不是很大。    我们可以把直方图压缩为128等级、64等级、32等级,更小的等级可能信息损失量过大,当压缩时,对应的直方图统计工作不会减少,可能计算量还会稍微有点增加,如下面的代码所示: for (int Y = 0; Y < Height; Y++) { if (Y == 0) // 第一行的列直方图,要重头计算 { for (int K = -Radius; K <= Radius; K++) { unsigned char *LinePS = Src + ColOffset[K + Radius] * Stride; for (int X = -Radius; X < Width + Radius; X++) { ColHist[(X + Radius) * HistAmount + (LinePS[RowOffset[X + Radius]] >> Shift)]++; } } } else // 其他行的列直方图,更新就可以了 { unsigned char *LinePS = Src + ColOffset[Y - 1] * Stride; for (int X = -Radius; X < Width + Radius; X++) // 删除移出范围内的那一行的直方图数据 { ColHist[(X + Radius) * HistAmount + (LinePS[RowOffset[X + Radius]] >> Shift)]--; } LinePS = Src + ColOffset[Y + Radius + Radius] * Stride; for (int X = -Radius; X < Width + Radius; X++) // 增加进入范围内的那一行的直方图数据 { ColHist[(X + Radius) * HistAmount + (LinePS[RowOffset[X + Radius]] >> Shift)]++; } }   ......... }   很明显,每个像素点都有右移Shift的计算,这个计算是凭空增加的,幸好,移位的计算量很小。
阅读全文