博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
图像处理入门——滤波
阅读量:6036 次
发布时间:2019-06-20

本文共 3595 字,大约阅读时间需要 11 分钟。

hot3.png

模糊

图像模糊的方法可以将每个像素的rgb值用周围像素的加权平均值来代替。比如用周围的9个像素来计算加权平均值,权值可以用一个3x3的矩阵来表示:

| 1   2   1 |

| 2   4   2 |   *  (1/16)

| 1   2   1 |

中间的像素是要处理的像素,越靠近中间权值越大;所有权值的和为1。用平均值代替原像素的rgb值之后,每个像素于周围像素的差异程度变小了;该矩阵相当于一个二维的低通滤波器。下面是c#的代码

public Bitmap FilterBitmap(Bitmap bmp){    // 创建如下3x3矩阵:    //          | 1 2 1 |    // (1/16) * | 2 4 2 |    //          | 1 2 1 |    double[,] core = new double[,] { { 1, 2, 1 }, { 2, 4, 2 }, { 1, 2, 1 } };    int scale = 16;    for (int i = 0; i < 3; i++)        for (int j = 0; j < 3; j++)            core[i, j] /= scale;    Bitmap retBmp = new Bitmap(bmp.Width, bmp.Height);    double r, g, b;    int width = bmp.Width - 1;    int height = bmp.Height - 1;    // 循环处理第2行开始到倒数第2行;第2列开始到倒数第2列的像素,    // 因为第最外面一圈的像素周围没有8个像素    for (int y = 1; y < height; y++)    {        for (int x = 1; x < width; x++)        {                                // 将周围8个像素的rgb加权平均值作为被处理像素的值            r = g = b = 0;            for (int j = -1; j <= 1; j++)            {                for (int i = -1; i <= 1; i++)                {                    Color pix = bmp.GetPixel(x + i, y + j);                    r += core[i + 1, j + 1] * pix.R;                    g += core[i + 1, j + 1] * pix.G;                    b += core[i + 1, j + 1] * pix.B;                }            }                                // 确保rgb的值在0到255            if (r < 0) r = 0; if (r > 255) r = 255;                                                    if (b < 0) b = 0; if (b > 255) b = 255;                                if (g < 0) g = 0; if (g > 255) g = 255;                             retBmp.SetPixel(x, y, Color.FromArgb((int)r, (int)g, (int)b));        }    }    return retBmp;}

动态模糊或径向模糊等处理方法也是用加权平均值代替原像素的值,只是用于计算平均值的像素是一条曲线或射线上的像素而不是周围一圈的像素。

 

锐化

相对于模糊,锐化可以让图像看似更加清晰。方法是把每一个像素与周围像素的差异放大。同样可以用一个3x3矩阵来表示周围9个像素的权值,权值相加为1;与用于模糊的矩阵不同的是,用于锐化的矩阵中间像素的权值是正的,而周围的权值是负的。以下面的矩阵为例

| 0   –1    0 |

| –1   5   -1 |

| 0   –1    0 |

中间像素的rgb值先增大5倍,再与周围4个像素的rgb值做差,即:该像素 +(该像素-上面像素)+(该像素-下面像素)+(该像素-左边像素)+(该像素-右边像素)。结果是,如果周围像素相对该像素较暗,则差值为正,使得该像素更亮;反之如果周围像素相对较亮,则使得该像素更暗。该矩阵具有动态增加对比度的效果,相当于一个高通滤波器,

 

浮雕效果

浮雕效果与锐化的方法相似,稍不同的是矩阵中的权值相加为0,比如把上面矩阵中间的5改成4,用该像素与周围像素的差值代替该像素:

| 0    –1    0 |

| –1    4   -1 |

| 0    –1    0 |

不过一般的浮雕效果是有光照方向感的,比如东南方向(只与东南方向的像素对比):

| 0     0    0 |

| 0    2   -1 |

| 0   –1    0 |

效果是,如果该像素与周围相同,则该像素rgb的值变成0;如果该像素比周围像素亮,则差值为正;否则差值为负。但因为rgb的值只能是0~255,所以要把处理后的rgb值加上一个正的偏移量。

public Bitmap FilterBitmap(Bitmap bmp){    // 创建如下3x3矩阵:    // | 0  0   0 |    // | 0  2  -1 |    // | 0  -1  0 |    int[,] core = new int[,] { { 0, 0, 0 }, { 0, 2, -1 }, { 0, -1, 0 } };                // 偏移量    int offset = 100;    Bitmap retBmp = new Bitmap(bmp.Width, bmp.Height);    int width = bmp.Width - 1;    int height = bmp.Height - 1;                int r, g, b;    for (int y = 1; y < height; y++)    {        for (int x = 1; x < width; x++)        {            r = g = b = 0;            for (int j = -1; j <= 1; j++)            {                for (int i = -1; i <= 1; i++)                {                    Color pix = bmp.GetPixel(x + i, y + j);                    r += core[i + 1, j + 1] * pix.R;                    g += core[i + 1, j + 1] * pix.G;                    b += core[i + 1, j + 1] * pix.B;                }            }            // 加上偏移量            r += offset;            g += offset;            b += offset;            if (r < 0) r = 0; if (r > 255) r = 255;            if (g < 0) g = 0; if (g > 255) g = 255;            if (b < 0) b = 0; if (b > 255) b = 255;            retBmp.SetPixel(x, y, Color.FromArgb(r, g, b));        }    }    return retBmp;}

锐化与浮雕处理可以应用于图像的边缘检测
以上主要参考《图像编程精髓——从开发自己的Photoshop开始》

转载于:https://my.oschina.net/soitravel/blog/54319

你可能感兴趣的文章
Shell命令-文件压缩解压缩之gzip、zip
查看>>
个人总结
查看>>
uva 673 Parentheses Balance
查看>>
Bzoj 2252: [2010Beijing wc]矩阵距离 广搜
查看>>
css 禁止选中文本
查看>>
bzoj2165
查看>>
算术运算表达式正则及分析
查看>>
Oracle 12c 多租户 手工创建 pdb 与 手工删除 pdb
查看>>
shell初涉
查看>>
[浪子学编程][MS Enterprise Library]ObjectBuilder之创建策略祥解(二)
查看>>
windows添加和删除服务
查看>>
关于云栖,有点无语的几个地方,管理能不能管?
查看>>
Windows线程的同步与互斥
查看>>
C#进阶系列——MEF实现设计上的“松耦合”(四):构造函数注入
查看>>
AngularJs ng-change事件/指令(转)
查看>>
linux系统下安装两个或多个tomcat
查看>>
ProtoBuffer 简单例子
查看>>
iOS多线程开发系列之(一)NSThread
查看>>
微信小程序初体验(上)- 腾讯ISUX社交用户体验设计成员出品
查看>>
SAP WM Physical Inventory Method ST & PZ
查看>>