高斯模糊算法的实现和优化

前两年我发过一文:Win32下的C++高斯模糊算法实例,里面给出了一个高斯模糊的实现,并写了粗略的简介。

不过当时内容讲得非常简单,而且附带的例子算法是有缺陷的:

  • 一是对图片的边角采用“跳过”的方式处理,导致模糊后的图片有黑边;
  • 二是算法本身采用的是二维矩阵,效率上不如一维高斯模糊好。

鉴于此,这里重新整理并试图完整的讲述一下高斯模糊。


一、高斯模糊是什么

模糊算法,不论是使用哪种算法,目的都是为了让图片看起来不如原来那么清晰。

清晰的图片,像素间的过渡会较为干脆利落,简而言之,就是像素之间的差距比较大。
而模糊的本质,其实就是使用某种算法把图像像素和像素之间的差距缩小,让中间点和周围点变得差不多;即,让中间点取一个范围内的平均值。
模糊到了极致,比如用于计算模糊的取值区域为整张图片,就会得到一张全图所有像素颜色都差不多的图片:


左边是原图,右边是彻底模糊之后的对比图

 

计算模糊的取值区域就是滤镜区域,那么关键就是,我们采用什么曲线函数来生成平均值了。

假设滤镜区域为正方形,且半径为r,我们可以用如下曲线函数来计算图片上某一个点的值:


这是一个非常简单的直线函数,求得的点值即为算术平均值,图片上某个点的值仅和模糊半径r有关,与坐标的位置无关。

 

由此我们可以得到用于模糊图像的滤镜算法:

 

void Average(filter_t& kernel, long radius)
{
    long diamet = Diamet(radius);           // (r * 2) + 1
    kernel.set(radius, diamet * diamet);    // kernel size is d * d

    double average = 1.0 / (double)kernel.size();

    for(long n = 0, i = 0; i < diamet; ++i)
        for(long j = 0; j < diamet; ++j, ++n)
            kernel[n] = average;
}


然后使用如下算法遍历整张图片,并使用滤镜处理像素:

 

 

void Blur2D(bitmap_t& bitmap, filter_t& kernel)
{
    for(long inx = 0, y = 0; y < bitmap.h(); ++y)
    {
        for(long x = 0; x < bitmap.w(); ++x, ++inx)
        {
            double r = 0.0, g = 0.0, b = 0.0;
            for (long n = 0, j = -kernel.radius(); j <= kernel.radius(); ++j)
            {
                long j_k = Edge(j, y, bitmap.h());
                for (long i = -kernel.radius
  • 14
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值