计算机视觉——DoG和LoG算子


计算机视觉—DoG和LoG算子


[email protected]


       阅读本文,需要有一定的数字图像处理基础,否则不太容易明白数学公式想要传达的物理意义。希望通过仅此一篇文章就能让你理解图像处理中的高斯滤波(也叫高斯平滑、高斯模糊、高斯卷积)、DoG算子、LoG算子,以及它们之间的关系。下面先讲理论,再讲实际应用。在理论部分,一切语言都显得过于苍白,因此我只给出了最核心的、最简单的、最优美的公式,当然包括一些必要的推导过程。

理 论 篇

1、高斯函数


       在图像处理中,常用的二维高斯函数为
G(x,y,σ)=12πσ2e(x2+y2)/2σ2

2、DoG算子


       DoG Difference of Gaussian )算子定义为
DoG=G(x,y,σ1)G(x,y,σ2)

3、LoG算子


       拉普拉斯算子为
2f=2fx2+2fy2

       对二维高斯函数应用拉普拉斯算子得
2G=2Gx2+2Gy2=2σ2+x2+y22πσ6e(x2+y2)/2σ2

       LoG Laplacian of Gaussian )算子定义为
LoG=σ22G

4、DoG和LoG的关系


       对二维高斯函数关于 σ 求一阶偏导数得
Gσ=2σ2+x2+y22πσ5e(x2+y2)/2σ2

       不难发现
Gσ=σ2G

       在 DoG 算子中,令 σ1=kσ2=kσ ,则
DoG=G(x,y,kσ)G(x,y,σ)

       进一步地
Gσ=limΔσ0G(x,y,σ+Δσ)G(x,y,σ)(σ+Δσ)σG(x,y,kσ)G(x,y,σ)kσσ

       因此
σ2G=GσG(x,y,kσ)G(x,y,σ)kσσ

       即
G(x,y,kσ)G(x,y,σ)(k1)σ22G

       这表明 可以用 DoG 算子来近似 LoG 算子

应 用 篇

1、计算高斯卷积模板

#include 
#include 

using namespace std;

#define PI 3.1415926

int main(int argc, char *argv[])
{
    double sigma = 1;
    int N = 2*ceil(3*sigma)+1;
    double *val = new double[N*N];
    int R = N/2;
    for(int i = 0; i < N; i++)
    {
        for(int j = 0; j < N; j++)
        {
            double r = (i-R)*(i-R)+(j-R)*(j-R);
            double res = exp(-r/(2*sigma*sigma));
            res = res/(2*PI*sigma*sigma);
            val[i*N+j] = res;
        }
    }
    delete []val;
    return 0;
} 


下图就是该段代码生成的 5x5 的高斯模板



       在图像处理中,为了提升计算速度,通常会牺牲少部分计算精度,使用整数模板代替浮点数模板。常见的 3x3 5x5 整数模板为

116121242121,12731474141626164726412674162616414741

2、快速计算高斯卷积


       由于高斯函数可以写成可分离的形式,因此可以采用可分离滤波器来实现加速。 可分离滤波器,就是可以把一个多维的卷积转化成多个一维的卷积。具体到二维的高斯滤波,就是指先对行做一维卷积,再对列做一维卷积。这样就可以将计算复杂度从O(M*M*N*N)降到O(2*M*M*N),M、N分别是图像和滤波器的窗口大小。

3、DoG算子应用


       在理论上
DoG(x,y,σ1,σ2)I(x,y)=G(x,y,σ1)I(x,y)G(x,y,σ2)I(x,y)

       因此,实际计算中,只需要先对输入图像作2个不同尺度的高斯平滑,然后将两幅图像相减,非常简单!

4、公式推导——符号计算


       在理解算法原理的时候,难免要进行公式推导。事实上,本文涉及的公式,不全是作者自己推导出来的,例如,求偏导数的公式就是计算机辅助完成的,虽然偷了个懒,但可以快速验证自己的理解是否正确,效率挺高。常见的符号计算工具有MATLAB,但本人使用的是Mac,没装MATLAB,无意间发现有一个Python包 SymPy可以进行符号计算,而且可以将结果导出为LaTeX格式,非常赞,强烈推荐!下面是一段示例代码

from sympy import *

x, y, s, pi, k = symbols('x,y,s,pi,k')

G_0 = 1/(2*pi*s**2) * exp(-(x**2+y**2)/(2*s**2)) 

ff = diff(G_0, s, 1)
gg = diff(G_0, x, 2) + diff(G_0, y, 2)

print latex(together(ff))
print latex(together(gg))

你可能感兴趣的:(计算机视觉)