Unity 3D : 高斯核
應用 :
同樣是高斯核,但維度不同,就可以做出很多變化,產生很多玩法 :
一維高斯核 : 統計分析
二維高斯核 : 將圖片做高斯模糊
三維高斯核 : 點光源
下圖為 3D 高斯核做的點光源範例 :
說明 :
公式會用到兩個常數 ( μ 與 σ ),這兩個值可以自訂義。
μ ( mu ) : 分布的位置 ( 一般為中心點 )
σ ( sigma ) : 標準差,分布的幅度
由下圖可以看到 σ ( sigma ) 越小幅度越大 :
σ ( sigma ) 也稱作標準差,由下圖可以表示 :
標準差 ± 1 = 34.1 * 2 = 68.2%
標準差 ± 2 = (34.1+13.6) * 2 = 95.4%
標準差 ± 3 = (34.1+13.6+2.1) * 2 = 99.6%
一維高斯核公式 :
同等 :
二維高斯核公式 :
同等 :
三維高斯核公式 :
同等 :
程式碼 :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
void Start()
{
float[] data = GaussTable_1D(5, 1.5f);
float sum = 0;
string txt = "";
for (int x = 0; x < data.Length; x++)
{
txt += data[x].ToString("0.00") + ", ";
sum += data[x];
}
print("1D : \n\n" + txt + "\n");
print("1D Sum : " + sum);
// --------------------------------------
float[,] data2 = GaussTable_2D(5, 1.5f);
sum = 0;
txt = "";
for (int y = 0; y < data2.GetLength(1); y++)
{
for (int x = 0; x < data2.GetLength(0); x++)
{
txt += data2[x, y].ToString("0.00") + ", ";
sum += data2[x, y];
}
txt += "\n";
}
print("2D : \n\n" + txt);
print("2D Sum : " + sum);
// --------------------------------------
float[,,] data3 = GaussTable_3D(5, 1.5f);
sum = 0;
txt = "";
for (int z = 0; z < data3.GetLength(2); z++)
{
for (int y = 0; y < data3.GetLength(1); y++)
{
for (int x = 0; x < data3.GetLength(0); x++)
{
txt += data3[x, y, z].ToString("0.000") + ", ";
sum += data3[x, y, z];
}
txt += "\n";
}
txt += "\n";
txt += "\n";
}
print("3D : \n\n" + txt);
print("3D Sum : " + sum);
}
float[] GaussTable_1D(int size, float sigma)
{
float[] result = new float[size];
float u = (size - 1) / 2f; // 中心點座標
float sum = 0;
for (int x = 0; x < size; x++)
{
result[x] = Mathf.Exp(-(u - x) * (u - x)) / (2 * (sigma * sigma) / (Mathf.Sqrt(2 * Mathf.PI * sigma)));
sum += result[x];
}
for (int x = 0; x < size; x++)
{
result[x] /= sum;
}
return result;
}
float[,] GaussTable_2D(int size, float sigma)
{
float[,] result = new float[size, size];
float u = (size - 1) / 2f; // 中心點座標
float sum = 0;
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
float temp1 = (u - x) * (u - x) + (u - y) * (u - y);
float temp2 = 2 * sigma * sigma;
float temp3 = Mathf.Sqrt(2 * Mathf.PI * sigma * sigma);
float temp4 = Mathf.Exp(-temp1 / temp2) / temp3;
result[x, y] = temp4;
sum += temp4;
}
}
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
result[x, y] /= sum;
}
}
return result;
}
float[,,] GaussTable_3D(int size, float sigma)
{
float[,,] result = new float[size, size, size];
float u = (size - 1) / 2f; // 中心點座標
float sum = 0;
for (int z = 0; z < size; z++)
{
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
float temp1 = (u - x) * (u - x) + (u - y) * (u - y) + (u - z) * (u - z);
float temp2 = 2 * sigma * sigma;
float temp3 = Mathf.Sqrt(2 * Mathf.PI * sigma * sigma * sigma);
float temp4 = Mathf.Exp(-temp1 / temp2) / temp3;
result[x, y, z] = temp4;
sum += temp4;
}
}
}
for (int z = 0; z < size; z++)
{
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
result[x, y, z] /= sum;
}
}
}
return result;
}
}
輸出結果 :
1D :
2D :
3D :
參考 :
资源 | 一文学会统计学中的显著性概念 : http://www.ijiandao.com/2b/baijia/173862.html