Konstruiere eine Gaußsche Matrix

12

Die Gaußsche Unschärfe ist eine Methode, mit der Bilder gleichmäßig verwischt werden. Dabei wird eine Matrix erstellt, die verwendet wird, indem sie mit den Pixeln eines Bildes gefaltet wird. In dieser Herausforderung besteht Ihre Aufgabe darin, die in der Gaußschen Unschärfe verwendete Matrix zu konstruieren. Sie nehmen eine Eingabe r, bei der es sich um den Radius der Unschärfe handelt, und eine Eingabe σ, bei der es sich um die Standardabweichung handelt, um eine Matrix mit den Abmessungen (2 r + 1 × 2 r + 1) zu erstellen . Jeder Wert in dieser Matrix hat einen ( x , y ) -Wert, der von seinem absoluten Abstand in jeder Richtung vom Zentrum abhängt und zur Berechnung von G ( x , y ) verwendet wird, wobei die Formel verwendet wirdG ist

Formel

Wenn beispielsweise r = 2 ist, möchten wir eine 5 × 5-Matrix erzeugen. Erstens ist die Matrix von ( x , y ) Werten

(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)

Dann sei σ = 1,5 und wende G auf jedes ( x , y ) an.

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

Normalerweise wird diese Matrix bei Bildunschärfe normalisiert, indem die Summe aller Werte in dieser Matrix genommen und durch diese dividiert wird. Für diese Herausforderung ist dies nicht erforderlich, und die von der Formel berechneten Rohwerte sind die Ausgabe, die ausgegeben werden soll.

Regeln

  • Das ist also gewinnt der kürzeste Code.
  • Die Eingabe r ist eine nichtnegative ganze Zahl und σ ist eine positive reelle Zahl.
  • Die Ausgabe muss eine Matrix darstellen. Es kann als 2D-Array, als String für ein 2D-Array oder ähnliches formatiert werden.
  • Gleitkomma-Ungenauigkeiten werden Ihnen nicht angerechnet.

Testfälle

(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
Meilen
quelle
Wie genau müssen pi und e sein?
xnor
@ xnor Gute Frage. Wenn Ihre Sprache es zulässt, können Sie davon ausgehen, dass diese Werte bereits in einer Variablen oder Ähnlichem gespeichert sind. Wenn nicht, können Sie Werte mit zwei Dezimalstellen verwenden, wobei pi = 3.14 und e = 2.72 ist, wobei Sie jeden dieser Werte als ein einzelnes Byte zählen können. Ungenauigkeiten in der endgültigen Antwort werden Ihnen natürlich nicht wieder angerechnet.
Meilen
Muss die Ausgabe eine Dezimalzahl sein oder könnten es exakte Zahlen mit Konstanten sein?
JungHwan Min
@JungHwanMin Die genauen Zahlen wie in Mathematica sind in Ordnung.
Meilen
1
@miles Ich denke, es wäre einfacher, wenn Sie nur eine bestimmte Genauigkeit (zB 3 Dezimalstellen) vorgeben würden.
Orlp

Antworten:

7

Mathematica, 60 54 50 Bytes

Danke @GregMartin für 4 Bytes!

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

Übernimmt r und Sigma als Eingabe, gibt die Matrix zurück (exakte Zahlen).

Eingebaute Version (58 Bytes)

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

Natürlich hat Mathematica auch eine eingebaute, aber es ist zu lang.

JungHwan min
quelle
4
Sie können -ldurch -#am Ende ersetzen ( Arrayfädelt das für Sie über beide Dimensionen ein); Das lerspart das Definieren und spart 4 Bytes.
Greg Martin
5

MATL , 20 Bytes

_G&:U&+iUE/_Ze5MYP*/

Probieren Sie es online!

Erläuterung

_     % 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
Luis Mendo
quelle
5

Oktave, 45 Bytes

@(r,s)exp((x=-(-r:r).^2/2/s^2)+x')/2/s^2/pi
Rainer P.
quelle
4

Oktave, 49 Bytes

@(r,q)1./((Q=2*q^2)*pi*e.^(((x=(-r:r).^2)+x')/Q))

Probieren Sie es online!

rahnema1
quelle
4

Python, 88 Bytes

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)]

Verwendet die Regel, nach der Sie 3.14 und 2.72 mit jeweils 1 Byte Kosten fest codieren können.

orlp
quelle
1

Perl 6 , 71 Bytes

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

Technisch mag dies mehr als 71 Bytes sein, wenn es verschlüsselt und in einer Datei gespeichert wird, aber ich konnte nicht widerstehen, die "Sigma" -Eingabe mit einem tatsächlichen griechischen Sigma zu benennen. Es kann in einen beliebigen ASCII-Buchstaben umbenannt werden, wenn dies gewünscht wird.

Sean
quelle
1

SAS-Makrosprache, 296 Byte

Wahrscheinlich ein viel effizienterer Weg, dies zu tun, aber es funktioniert :)

Dieser Code druckt den resultierenden Datensatz aus.

%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;
J_Lard
quelle
1

Haskell, 59 Bytes

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

Anwendungsbeispiel:

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]]
nimi
quelle
0

Python 2.7, 167 Bytes

Eine sehr einfache Lösung:

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)

Probieren Sie es hier aus !

Ungolfed:

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)
Calconym
quelle
5
from __future__ import division, Ja wirklich?
Orlp