Bangun Matriks Gaussian

12

Gaussian blur adalah metode yang digunakan untuk mengaburkan gambar dengan lancar. Ini melibatkan pembuatan matriks yang akan digunakan dengan membelitnya dengan piksel gambar. Dalam tantangan ini, tugas Anda adalah membuat matriks yang digunakan dalam Gaussian blur. Anda akan mengambil input r yang akan menjadi jari-jari blur dan input σ yang akan menjadi standar deviasi untuk membangun matriks dengan dimensi (2 r + 1 × 2 r + 1). Setiap nilai dalam matriks itu akan memiliki nilai ( x , y ) yang tergantung pada jarak absolutnya di setiap arah dari pusat dan akan digunakan untuk menghitung G ( x , y ) di mana rumusG adalah

rumus

Sebagai contoh, jika r = 2, kami ingin menghasilkan matriks 5 x 5. Pertama, matriks nilai ( x , y ) adalah

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

Kemudian, biarkan σ = 1,5 dan terapkan G untuk masing-masing ( x , y )

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

Biasanya dalam gambar kabur, matriks ini akan dinormalisasi dengan mengambil jumlah semua nilai dalam matriks itu dan membaginya. Untuk tantangan ini, itu tidak diperlukan dan nilai mentah yang dihitung oleh rumus adalah seperti apa output yang seharusnya.

Aturan

  • Ini adalah sehingga kode terpendek menang.
  • Input r akan menjadi bilangan bulat non-negatif dan σ akan menjadi bilangan real positif.
  • Output harus mewakili sebuah matriks. Ini dapat diformat sebagai array 2d, string yang mewakili array 2d, atau yang serupa.
  • Ketidaktepatan titik-mengambang tidak akan dihitung terhadap Anda.

Uji Kasus

(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
mil
sumber
Seberapa akurat kita membutuhkan pi dan e?
xnor
@xnor Pertanyaan bagus. Jika bahasa Anda memungkinkan, Anda dapat mengasumsikan bahwa nilai-nilai itu sudah disimpan dalam variabel atau yang serupa. Jika tidak, Anda dapat menggunakan nilai ke dua tempat desimal membuat pi = 3.14 dan e = 2.72 di mana Anda dapat menghitung masing-masing nilai tersebut sebagai satu byte. Tentu saja, ketidakakuratan dalam jawaban akhir tidak akan dihitung terhadap Anda lagi.
mil
Apakah output harus berupa angka desimal, atau mungkinkah itu angka yang tepat dengan konstanta di dalamnya?
JungHwan Min
@JungHwanMin Angka pastinya, seperti yang ada di Mathematica, tidak masalah.
miles
1
@miles Saya pikir akan lebih mudah jika Anda hanya mengamanatkan presisi tertentu (misalnya 3 tempat desimal).
orlp

Jawaban:

7

Mathematica, 60 54 50 byte

Terima kasih @GregMartin untuk 4 byte!

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

Mengambil r dan sigma sebagai input, mengembalikan matriks (angka pastinya).

Versi bawaan (58 byte)

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

Tentu saja, Mathematica memiliki built-in untuk ini juga, tetapi terlalu lama.

JungHwan Min
sumber
4
Anda dapat menggantinya -ldengan -#di akhir ( Arrayakan utas yang di atas kedua dimensi untuk Anda); yang menghilangkan kebutuhan untuk mendefinisikan l, menghemat 4 byte.
Greg Martin
5

MATL , 20 byte

_G&:U&+iUE/_Ze5MYP*/

Cobalah online!

Penjelasan

_     % 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
sumber
5

Oktaf, 45 byte

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

Oktaf, 49 byte

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

Cobalah secara Online!

rahnema1
sumber
4

Python, 88 byte

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

Menggunakan aturan di mana Anda dapat melakukan hardcode 3.14 dan 2.72 masing-masing dengan biaya 1 byte.

orlp
sumber
1

Perl 6 , 71 byte

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

Secara teknis ini mungkin lebih dari 71 byte jika dikodekan dan disimpan ke file, tetapi saya tidak bisa menahan penamaan input "sigma" dengan sigma Yunani yang sebenarnya. Itu bisa diubah namanya menjadi surat ASCII biasa jika diinginkan.

Sean
sumber
1

SAS Macro Language, 296 byte

Mungkin cara yang jauh lebih efisien untuk melakukan ini tetapi berhasil :)

Kode ini mencetak dataset yang dihasilkan.

%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
sumber
1

Haskell, 59 byte

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

Contoh penggunaan:

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
sumber
0

Python 2.7, 167 byte

Solusi yang sangat sederhana:

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)

Coba di sini !

Tidak Disatukan:

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
sumber
5
from __future__ import division, Betulkah?
orlp