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%

在这里插入图片描述


一維高斯核公式 :

f ( x ) = 1 2 π σ e − ( μ − x ) 2 2 σ 2 f(x)=\dfrac{1}{\sqrt{2\pi\sigma}}e-\dfrac{(\mu-x)^2}{2\sigma^2} f(x)=2πσ 1e2σ2(μx)2

同等 :

f ( x ) = e x p { − ( μ − x ) 2 2 σ 2 } 2 π σ f(x)=\dfrac{exp\{-\dfrac{(\mu-x)^2}{2\sigma^2}\}}{\sqrt{2\pi\sigma}} f(x)=2πσ exp{2σ2(μx)2}


二維高斯核公式 :

f ( x ) = 1 2 π σ 2 e − ( μ − x ) 2 + ( μ − y ) 2 2 σ 2 f(x)=\dfrac{1}{\sqrt{2\pi\sigma^2}}e-\dfrac{(\mu-x)^2+(\mu-y)^2}{2\sigma^2} f(x)=2πσ2 1e2σ2(μx)2+(μy)2

同等 :

f ( x ) = e x p { − ( μ − x ) 2 + ( μ − y ) 2 2 σ 2 } 2 π σ 2 f(x)=\dfrac{exp\{-\dfrac{(\mu-x)^2+(\mu-y)^2}{2\sigma^2}\}}{\sqrt{2\pi\sigma^2}} f(x)=2πσ2 exp{2σ2(μx)2+(μy)2}


三維高斯核公式 :

f ( x ) = 1 2 π σ 3 e − ( μ − x ) 2 + ( μ − y ) 2 + ( μ − z ) 2 2 σ 2 f(x)=\dfrac{1}{\sqrt{2\pi\sigma^3}}e-\dfrac{(\mu-x)^2+(\mu-y)^2+(\mu-z)^2}{2\sigma^2} f(x)=2πσ3 1e2σ2(μx)2+(μy)2+(μz)2

同等 :

f ( x ) = e x p { − ( μ − x ) 2 + ( μ − y ) 2 + ( μ − z ) 2 2 σ 2 } 2 π σ 3 f(x)=\dfrac{exp\{-\dfrac{(\mu-x)^2+(\mu-y)^2+(\mu-z)^2}{2\sigma^2}\}}{\sqrt{2\pi\sigma^3}} f(x)=2πσ3 exp{2σ2(μx)2+(μy)2+(μz)2}


程式碼 :

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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值