สร้างเกาส์เมทริกซ์


12

Gaussian blurเป็นวิธีที่ใช้สำหรับการทำให้ภาพเบลออย่างราบรื่น มันเกี่ยวข้องกับการสร้างเมทริกซ์ซึ่งจะใช้โดยการโน้มน้าวกับพิกเซลของภาพ ในการท้าทายนี้งานของคุณคือการสร้างเมทริกซ์ที่ใช้ในการเบลอแบบเกาส์ คุณจะใช้อินพุทrซึ่งจะเป็นรัศมีของความพร่ามัวและอินพุทσซึ่งจะเป็นค่าเบี่ยงเบนมาตรฐานเพื่อสร้างเมทริกซ์ที่มีขนาด (2 r + 1 × 2 r + 1) แต่ละค่าในเมทริกซ์นั้นจะมีค่า ( x , y ) ที่ขึ้นอยู่กับระยะทางที่แน่นอนในแต่ละทิศทางจากศูนย์กลางและจะใช้ในการคำนวณG ( x , y ) โดยที่สูตรจีคือ

สูตร

ตัวอย่างเช่นถ้าr = 2 เราต้องการสร้างเมทริกซ์ขนาด 5 x 5 ก่อนอื่นเมทริกซ์ของค่า ( x , y ) คือ

(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กับแต่ละ ( 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

ตามปกติในการเบลอภาพเมทริกซ์นี้จะถูกทำให้เป็นมาตรฐานโดยการหาผลรวมของค่าทั้งหมดในเมทริกซ์นั้นและหารด้วยมัน สำหรับความท้าทายนี้ไม่จำเป็นและค่าดิบที่คำนวณโดยสูตรคือผลลัพธ์ที่ควรมี

กฎระเบียบ

  • นี่คือเพื่อให้โค้ดที่สั้นที่สุดชนะ
  • อินพุต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
@ ไฟล์ฉันคิดว่ามันจะง่ายกว่านี้ถ้าคุณได้รับคำสั่งที่แน่นอน (เช่นทศนิยม 3 ตำแหน่ง)
orlp

คำตอบ:


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 ไบต์
Greg Martin

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

ใช้กฎที่คุณอาจใช้ hardcode 3.14 และ 2.72 ที่ราคา 1 ไบต์


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)

ลองที่นี่ !

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จริงเหรอ
orlp
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.