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

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.


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

5

Oktave, 45 Bytes

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


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.


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.


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;

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

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)

5
from __future__ import division, Ja wirklich?
Orlp
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.