时至今日,openCV 已经出到了3.2版本,且其社区也足够庞大,其全面性已无需赘述。但我们用 Golang 这样一门待火不火的语言来造一些相关的轮子,也蛮有趣

    声明:本文以及图片为原创,转载请联系作者。

    下面我分享一下用 Golang 实现一些图像处理过程中的收获。

    高斯模糊效果

    高斯模糊是一种比较常见的模糊效果,我们在各类图像处理软件或库、框架等地方会经常见到。首先看一下效果:

    Golang 图像处理上的一些实践 - 图1

    (左边为原图,右边为 Sigma=10 ,10 像素模糊后)

    高斯模糊(英语:Gaussian Blur),也叫高斯平滑。简单点说,是将『二位正态分布』应用于图像处理,从算法的角度来说,十分的简单易懂。参考了阮一峰老师的文章:高斯模糊算法**后,我来班门弄斧,谈一下实现过程中的感悟。

    一副图像,这里指非矢量图,一般由许多像素点构成,像素点内包含色值数据,一般为 RGBA 形式。为了将一副图片模糊处理,也就是说将某一点像素的 RGBA 值向周围像素「靠拢」,即受周围影响,从而达到模糊目的。

    最简单的平均值方法如下图左,均等分配。但这样明显会对图片造成较大失真,所以我们又想到了如下图右的均值分法:

    Golang 图像处理上的一些实践 - 图2

    这种处理方式会使图像失去原来的性质,所以高斯模糊是一种不可逆处理。

    在权重的分配上,我们采用了高斯的二维正态分布函数,这也是『高斯模糊』名字由来,下面咳咳(敲黑板,记笔记),我们来复习一维高斯函数:

    Golang 图像处理上的一些实践 - 图3

    其中,μ是x的均值,σ是x的方差。因为计算平均值的时候,中心点就是原点,所以μ等于0。由一维高斯函数可推导得二维高斯函数(可理解为沿 x=μ 旋转)。见下图。

    Golang 图像处理上的一些实践 - 图4

    Sigma 越大,图形越矮胖,越小越高瘦。下面是 Golang 的二维高斯模糊公式实现:

    1. // GaussFunc 二维高斯函数
    2. func GaussFunc(x, y int, Sigma float64) float64 {
    3. return (1.0 / (2.0 * math.Pi * Sigma * Sigma)) * math.Pow(math.E, ((-1.0)*(float64(x*x+y*y)/(2.0*Sigma*Sigma))))
    4. }

    由此设定 Sigema 的值后,可计算 x=y=n 像素,x*y 像素块内每个点的概率值,且所有值相加应等于1,如下图所示3X3像素块所示:

    Golang 图像处理上的一些实践 - 图5

    由于每次都进行概率运算效率较低,若固定像素固定 Sigma 处理模糊,可提前将概率矩阵算好打表使用,将提高处理速度。

    接下来,将矩阵内像素的 RGBA 值分别乘对应的权重值相加,所得结果就是中心像素的 RGBA 值,我们只需将该像素填充到正确的位置。

    处理完所有像素点,就能得到对应参数的高斯模糊效果图。如下:

    Golang 图像处理上的一些实践 - 图6

    这时我们应该考虑一个问题,那就是边缘处理,四个边缘的像素点无法向外计算。

    目前有两种办法解决,一种是把已有的点拷贝到另一面的对应位置,模拟出完整的矩阵、或者将超出边界的点按边界点 RGBA 值处理。

    如果出现边缘单色化,可采取切除相应像素边缘的方式优化。

    如果你不关心这些,也可以直接使用该图形库:

    1. go get github.com/jeasonstudio/GaussianBlur
    1. // GaussianBlur 高斯模糊处理
    2. // sourceImg \ tagImg 处理前 \ 后图片相对路径地址
    3. // num 高斯模糊像素,单位 px,注意,此项过高将直接影响时间
    4. // Sigma 塞个马,周围像素权重
    5. func GaussianBlur(sourceImg, tagImg string, num int, Sigma float64)

    留图不留种,菊花万人捅:GitHub: GaussianBlur/jeasonstudio**

    欢迎大家关注我的专栏:知乎专栏-代码小白的日常

    下一篇系列预告:Golang 图像处理实践之边缘检测算法