zoukankan      html  css  js  c++  java
  • 转《图像处理之表面滤波》

    本文介绍经典的表面模糊Surface Blur算法与实现。

    表面模糊是PS里一个重要的保边滤波器,它的算法很简单,公式如下所示:

    主要思想还是计算当前像素X的邻域范围内不同像素的加权求和,边缘地方的像素,加权比较大,平滑的地方加权比较小,以此来保留边缘信息,平滑平坦区域;

    效果如下图所示:

    代码实现如下:

    [cpp] view plain copy
     
     
     
     
    1. #define MIN2(a, b) ((a) < (b) ? (a) : (b))  
    2. #define MAX2(a, b) ((a) > (b) ? (a) : (b))  
    3. #define CLIP3(x, a, b) MIN2(MAX2(a,x), b)  
    4. void f_SurfaceBlur(unsigned char* srcData, int width, int height, int stride, int radius, int threshold)  
    5. {  
    6.     if (srcData == NULL)  
    7.     {  
    8.         return;  
    9.     }  
    10.     float sumr = 0, sumrw = 0, sumg = 0, sumgw = 0, sumb = 0, sumbw = 0, k = 0;  
    11.     int pos = 0, pos0 = 0;  
    12.     unsigned char* tempData = (unsigned char*)malloc(sizeof(unsigned char) * height * stride);  
    13.     memcpy(tempData, srcData, sizeof(unsigned char) * height * stride);  
    14.     for(int j = 0; j < height; j++)  
    15.     {  
    16.         for(int i = 0; i < width; i++)  
    17.         {  
    18.             pos = i * 4 + j * stride;  
    19.             sumr = sumrw = sumg = sumgw = sumb = sumbw = 0;  
    20.             for(int n = -radius; n <= radius; n++)  
    21.             {  
    22.                 for(int m = -radius; m <= radius; m++)  
    23.                 {  
    24.                     int x = CLIP3(i + m, 0, width - 1);  
    25.                     int y = CLIP3(j + n, 0, height - 1);  
    26.                     pos0 = x * 4 + y * stride;  
    27.                     k = 1.0f - abs(tempData[pos0] - tempData[pos]) / (2.5f * threshold);  
    28.                     sumb += k * tempData[pos0];  
    29.                     sumbw += k;  
    30.   
    31.                     k = 1.0f - abs(tempData[pos0 + 1] - tempData[pos + 1]) / (2.5f * threshold);  
    32.                     sumg += k * tempData[pos0 + 1];  
    33.                     sumgw += k;  
    34.   
    35.                     k = 1.0f - abs(tempData[pos0 + 2] - tempData[pos + 2]) / (2.5f * threshold);  
    36.                     sumr += k * tempData[pos0 + 2];  
    37.                     sumrw += k;  
    38.                 }  
    39.             }  
    40.             srcData[pos]     = sumbw == 0 ? srcData[pos]     : CLIP3(sumb / sumbw, 0, 255);  
    41.             srcData[pos + 1] = sumgw == 0 ? srcData[pos + 1] : CLIP3(sumg / sumgw, 0, 255);  
    42.             srcData[pos + 2] = sumrw == 0 ? srcData[pos + 2] : CLIP3(sumr / sumrw, 0, 255);  
    43.         }  
    44.     }  
    45.     free(tempData);  
    46. }  

    代码没有经过优化,是完全按照公式实现的,如果考虑优化,可以考虑使用多线程,或者是YCbCr颜色空间只对Y处理,以此加速,效果会比较明显。

  • 相关阅读:
    几何画板表现两集合的差集的教程
    MathType如何编辑大三角形符号
    几何画板如何绘制动态正切函数图像
    MathType如何设置标尺的单位
    模拟按键
    oauth2.0
    PHP CURL POST提交
    Eclipse导入到web项目没有run on server
    实时刷新
    js 实时数据显示
  • 原文地址:https://www.cnblogs.com/ckAng/p/9894450.html
Copyright © 2011-2022 走看看