【问题标题】:Truncated gaussian kernel implementation Matlab,right?截断的高斯内核实现Matlab,对吗?
【发布时间】:2014-07-31 13:59:48
【问题描述】:

我将截断高斯核定义为:

所以我混淆了截断高斯内核的正确实现。看两个案例告诉我,非常感谢

案例一:

G_truncated=fspecial('gaussian',round(2*sigma)*2 + 1,sigma); %  kernel

案例 2:

G=fspecial('gaussian',round(2*sigma)*2 + 1,sigma); %  normal distribution kernel
B = ones(round(2*sigma)*2 + 1,round(2*sigma)*2 + 1);
G_truncated=G.*B;
G_truncated = G_truncated/sum(G_truncated(:)); %normalized for sum=1

【问题讨论】:

  • 如果您真的想自己实现内核,我会在 Yayoi 的答案之上附加。祝你好运!

标签: matlab image-processing computer-vision gaussian


【解决方案1】:

在上一篇文章的基础上,还有一个如何实现内核的问题。你可以使用fspecial,截断内核,使半径之外的任何东西都为零,然后重新规范化它,但我假设你会从第一原则开始这样做......所以让我们弄清楚这一点。首先,您需要生成距遮罩中心的距离空间图。结合起来,您可以使用它来确定高斯值(未归一化)是什么。您根据距离的空间图过滤掉未归一化掩码中的这些值,然后对其进行归一化。因此,考虑到您的标准偏差tau,以及您的半径rho,您可以这样做:

%// Find grid of points
[X,Y] = meshgrid(-rho : rho, -rho : rho)

dists = (X.^2 + Y.^2); %// Find distances from the centre (Euclidean distance squared)
gaussVal = exp(-dists / (2*tau*tau)); %// Find unnormalized Gaussian values

%// Filter out those locations that are outside radius and set to 0
gaussVal(dists > rho^2) = 0;

%// Now normalize
gaussMask = gaussVal / (sum(gaussVal(:)));

这是一个使用rho = 2tau = 2 的示例,每个阶段的输出:

第 1 阶段 - 查找网格坐标

>> X

X =

-2    -1     0     1     2
-2    -1     0     1     2
-2    -1     0     1     2
-2    -1     0     1     2
-2    -1     0     1     2

>> Y

Y = 

-2    -2    -2    -2    -2
-1    -1    -1    -1    -1
 0     0     0     0     0
 1     1     1     1     1
 2     2     2     2     2

第 2 步 - 查找与中心值和非归一化高斯值的距离

>> dists

dists =

 8     5     4     5     8
 5     2     1     2     5
 4     1     0     1     4
 5     2     1     2     5
 8     5     4     5     8

>> gaussVal

gaussVal =

0.3679    0.5353    0.6065    0.5353    0.3679
0.5353    0.7788    0.8825    0.7788    0.5353
0.6065    0.8825    1.0000    0.8825    0.6065
0.5353    0.7788    0.8825    0.7788    0.5353
0.3679    0.5353    0.6065    0.5353    0.3679

第 3 步 - 过滤掉不属于半径范围内的位置并设置为 0

>> gaussVal =

     0         0    0.6065         0         0
     0    0.7788    0.8825    0.7788         0
0.6065    0.8825    1.0000    0.8825    0.6065
     0    0.7788    0.8825    0.7788         0
     0         0    0.6065         0         0

步骤 #4 - 归一化,使总和等于 1

>> gaussMask =

     0         0    0.0602         0         0
     0    0.0773    0.0876    0.0773         0
0.0602    0.0876    0.0993    0.0876    0.0602
     0    0.0773    0.0876    0.0773         0
     0         0    0.0602         0         0

要验证掩码总和为 1,只需执行 sum(gaussMask(:)),您会看到它等于 1...或多或少 :)

【讨论】:

  • 非常完美! +1先生。有效。请参阅有关局部熵的其他问题。我更新了它
  • 我将您的答案升级为球内核。这是非常有用的。尽情享受
【解决方案2】:

您对截断高斯内核的定义与 MATLAB 截断滤波器内核的方式不同,尽管在实践中对于相当大的 d 而言通常无关紧要。

fspecial 已经返回 truncated AND normalized filter,所以第二种情况是多余的,因为它生成的结果与第一种情况完全相同。

来自 MATLAB 帮助:

H = fspecial('gaussian',HSIZE,SIGMA) returns a rotationally
symmetric Gaussian lowpass filter  of size HSIZE with standard
deviation SIGMA (positive). HSIZE can be a vector specifying the
number of rows and columns in H or a scalar, in which case H is a
square matrix.
The default HSIZE is [3 3], the default SIGMA is 0.5.

您可以使用fspecial('gaussian',1,sigma) 生成一个1x1 过滤器,看看它确实是归一化的。

要生成符合您定义的过滤器内核,您需要在第二种情况下使B 成为一个在圆形区域中有一个的矩阵。一个不太严格(但在实践中仍然是多余的)解决方案是使用fspecial('disk',size) 截断您的高斯内核。在任何一种情况下都不要忘记对其进行规范化。

【讨论】:

  • 感谢您的回答。所以这是最终答案。你能告诉所有答案如何实现截断的高斯内核吗?
  • 首先您的定义是针对连续高斯内核,而 fspecial 生成离散内核。即使在离散化时,由 fspecial 生成的高斯核也会被正方形而不是圆形截断。在实践中这两种方式都没有关系,尤其是在计算机视觉应用中。就用case 1生成的kernel,因为它和case 2完全一样。
  • 是的,先生,所以第一种情况与我的定义相近。我正在使用它进行图像分割。谢谢
【解决方案3】:

rayryeng 的回答对我很有用。我只将高斯核扩展到球核。球核定义:

所以基于 rayryeng 的回答。我们可以这样做

sigma=2;
rho=sigma;
tau=sigma;
%// Find grid of points
[X,Y] = meshgrid(-rho : rho, -rho : rho)

dists = (X.^2 + Y.^2); %// Find distances from the centre (Euclidean distance squared)
ballVal=dists;
ballVal(dists>sigma)=0;
ballVal(dists<=sigma)=1;

%// Now normalize
ballMask = ballVal / (sum(ballVal(:)));

如果有任何错误或问题,请告诉我。谢谢

【讨论】:

  • 您不需要规范化掩码,因为定义不需要它。您还可以删除 tau,因为它没有在定义中使用。在dists 计算之后,我个人会这样做:ballVal = ones(size(X)); ballVal(dists &gt; sigma^2) = 0; 请记住,dists 表示欧几里得距离的平方,因此条件需要为sigma^2。你可以使用sigma,前提是你使用sqrt(dists) &gt; sigma;
  • 谢谢!因为内核中的元素总和等于 1 的一个条件。所以我对其进行了标准化。很抱歉错过了这些信息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-15
  • 1970-01-01
  • 2021-12-15
  • 2012-01-02
  • 2014-05-25
  • 2013-08-09
相关资源
最近更新 更多