构造高斯矩阵


12

高斯模糊是一种用于平滑模糊图像的方法。它涉及创建一个矩阵,该矩阵将通过与图像像素卷积来使用。在这个挑战中,您的任务是构造用于高斯模糊的矩阵。为了构造一个尺寸为(2 r + 1×2 r + 1)的矩阵,您将使用输入r作为模糊半径,并使用输入σ作为标准偏差。该矩阵中的每个值都有一个(xy)值,该值取决于其在每个方向上距中心的绝对距离,并将用于计算Gxy),其中G

式

例如,如果r = 2,我们想生成一个5 x 5的矩阵。首先,(xy)值的矩阵为

(2, 2) (1, 2) (0, 2) (1, 2) (2, 2)
(2, 1) (1, 1) (0, 1) (1, 1) (2, 1)
(2, 0) (1, 0) (0, 0) (1, 0) (2, 0)
(2, 1) (1, 1) (0, 1) (1, 1) (2, 1)
(2, 2) (1, 2) (0, 2) (1, 2) (2, 2)

然后,让σ = 1.5并将G应用于每个(xy

0.0119552 0.0232856 0.0290802 0.0232856 0.0119552
0.0232856 0.0453542 0.0566406 0.0453542 0.0232856
0.0290802 0.0566406 0.0707355 0.0566406 0.0290802
0.0232856 0.0453542 0.0566406 0.0453542 0.0232856
0.0119552 0.0232856 0.0290802 0.0232856 0.0119552

通常在图像模糊中,可以通过将该矩阵中所有值的总和除以该矩阵来对其进行归一化。对于此挑战,这不是必需的,并且由公式计算得出的原始值应为输出。

规则

  • 这是因此最短的代码获胜。
  • 输入r将是一个非负整数,而σ将是一个正实数。
  • 输出必须表示一个矩阵。可以将其格式化为2d数组,代表2d数组的字符串或类似格式。
  • 浮点数错误将不算在您身上。

测试用例

(r, σ) = (0, 0.25)
2.54648

(1, 7)
0.00318244 0.00321509 0.00318244
0.00321509 0.00324806 0.00321509
0.00318244 0.00321509 0.00318244

(3, 2.5)
0.00603332 0.00900065 0.0114421  0.012395 0.0114421 0.00900065 0.00603332
0.00900065  0.0134274 0.0170696 0.0184912 0.0170696  0.0134274 0.00900065
 0.0114421  0.0170696 0.0216997  0.023507 0.0216997  0.0170696  0.0114421
  0.012395  0.0184912  0.023507 0.0254648  0.023507  0.0184912   0.012395
 0.0114421  0.0170696 0.0216997  0.023507 0.0216997  0.0170696  0.0114421
0.00900065  0.0134274 0.0170696 0.0184912 0.0170696  0.0134274 0.00900065
0.00603332 0.00900065 0.0114421  0.012395 0.0114421 0.00900065 0.00603332

(4, 3.33)
0.00339074 0.00464913 0.00582484 0.00666854 0.00697611 0.00666854 0.00582484 0.00464913 0.00339074
0.00464913 0.00637454 0.00798657  0.0091434 0.00956511  0.0091434 0.00798657 0.00637454 0.00464913
0.00582484 0.00798657  0.0100063  0.0114556   0.011984  0.0114556  0.0100063 0.00798657 0.00582484
0.00666854  0.0091434  0.0114556   0.013115  0.0137198   0.013115  0.0114556  0.0091434 0.00666854
0.00697611 0.00956511   0.011984  0.0137198  0.0143526  0.0137198   0.011984 0.00956511 0.00697611
0.00666854  0.0091434  0.0114556   0.013115  0.0137198   0.013115  0.0114556  0.0091434 0.00666854
0.00582484 0.00798657  0.0100063  0.0114556   0.011984  0.0114556  0.0100063 0.00798657 0.00582484
0.00464913 0.00637454 0.00798657  0.0091434 0.00956511  0.0091434 0.00798657 0.00637454 0.00464913
0.00339074 0.00464913 0.00582484 0.00666854 0.00697611 0.00666854 0.00582484 0.00464913 0.00339074

我们需要pi和e的精度如何?
xnor

@xnor好问题。如果您的语言允许,您可以假定这些值已经存储在变量或类似的变量中。如果不是,则可以使用到小数点后两位的值,使pi = 3.14和e = 2.72,您可以在其中将每个值都计为一个字节。当然,最终答案中的不正确之处将不会再计入您的视线。
英里

输出是否必须是十进制数字,还是可能是其中包含常数的精确数字?
JungHwan Min

@JungHwanMin确切的数字(例如Mathematica中的数字)很好。
英里

1
@miles我认为如果您只要求一定的精度(例如3个小数位),会更容易。
orlp

Answers:


7

Mathematica,60 54 50字节

感谢@GregMartin 4个字节!

Array[s=2#2^2;E^(-{##}.{##}/s)/π/s&,1+2{#,#},-#]&

将r和sigma作为输入,返回矩阵(精确数字)。

内置版本(58字节)

GaussianMatrix[{##},Standardized->1<0,Method->"Gaussian"]&

当然,Mathematica也为此内置了一个功能,但是它太长了。


4
您可以替换-l通过-#末(Array会跟帖说在这两个方面你); 这样就无需定义l,节省了4个字节。
格雷格·马丁

5

MATL,20字节

_G&:U&+iUE/_Ze5MYP*/

在线尝试!

说明

_     % Take input r implicitly. Negate
G     % Push r again
&:    % Binary range: [-r -r+1 ... r]
U     % Square, elementwise
&+    % Matrix of all pairwise additions
i     % Take input σ
U     % Square
E     % Multiply by 2. Gives 2σ^2
/     % Divide
_     % Negate
Ze    % Exponential
5M    % Push 2σ^2 again
YP    % Push pi
*     % Multiply
/     % Divide. Display implicitly



4

Python,88个字节

lambda r,s:[[.5/3.14/s/s/2.72**((x*x+y*y)/2/s/s)for x in range(-r,r+1)]for y in range(-r,r+1)]

使用规则,您可以以每1字节的成本对3.14和2.72进行硬编码。


1

Perl 6,71个字节

->\r,\σ{map ->\y{map ->\x{exp((x*x+y*y)/-2/σ/σ)/2/pi/σ/σ},-r..r},-r..r}

从技术上讲,如果将其编码并保存到文件中,则可能会超过71个字节,但是我无法抗拒将“ sigma”输入命名为实际的希腊sigma。如果需要,可以将其重命名为任何纯ASCII字母。


1

SAS宏语言,296字节

可能是一种更有效的方法,但是有效:)

此代码打印出结果数据集。

%macro G(r,s);%let l=%eval(2*&r+1);%let pi=%sysfunc(constant(pi));data w;array a[*] t1-t&l;%do i=-&r %to &r;%do j=-&r %to &r;%let t=%sysfunc(sum(&j,&r,1));a[&t]=%sysevalf(1/(2*&pi*&s**2)*%sysfunc(exp(-(%sysfunc(abs(&j))**2+%sysfunc(abs(&i))**2)/(2*&s**2))));%end;output;%end;proc print;run;%mend;

1

Haskell,59个字节

r#s|i<-[-r..r]=[[exp(-(x*x+y*y)/2/s/s)/2/pi/s/s|x<-i]|y<-i]

用法示例:

1#7

[[3.1824449424224664e-3,3.2150851187016326e-3,3.1824449424224664e-3],
 [3.2150851187016326e-3,3.2480600630999047e-3,3.2150851187016326e-3],
 [3.1824449424224664e-3,3.2150851187016326e-3,3.1824449424224664e-3]]

0

Python 2.7,167个字节

一个非常简单的解决方案:

from __future__ import division;from math import*;r,s=input();s*=2*s;R=range(-r,r+1);print"\n".join("\t".join(str(pow(e,-(x*x+y*y)/s)/(pi*s))[:9]for x in R)for y in R)

在这里尝试

取消高尔夫:

from __future__ import division
from math import *
r,s = input()                         # Take input
s *= 2*s                              # Set s = 2*s^2; simplifies the expression
R = range(-r,r+1)                     # Range object; used twice

                                   # G(x,y)             # Stripped
print "\n".join("\t".join(str(pow(e,-(x*x + y*y)/s)/(pi*s))[:9] for x in R) for y in R)

5
from __future__ import division,真的吗?
orlp 2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.