matlab練習程序(柏林噪聲)


關於噪聲生成,我們可以使用rand(256)這樣的函數生成256*256大小的隨機噪聲,這樣的噪聲我們稱為白噪聲。

不過白噪聲過於隨機,有時候並不能反映真實的噪聲,比如山丘,紋理等不那么“隨機”的起伏。

因此有人開發了柏林噪聲,該噪聲在圖形學中的地形,雲彩或火焰生成等方法中經常使用。

下面介紹下算法過程:

1. 首先定義網格大小和待生成圖像的大小。

2. 對網格每一個頂點生成隨機方向向量,就是下圖紅色的向量。

3. 遍歷圖像每一個像素,計算該像素到該像素所在網格四個頂點組成的向量d,就是下圖右邊藍色的向量。

4. 計算網格頂點隨機方向向量與3中求得的向量d的點積,得到方向權重。

5. 利用平滑函數對dx、dy平滑,得到比例系數sx、sy。平滑函數要符合f(0) = 0,f(0.5)=0.5,f(1)=1的方程,最好滿足二階導數連續。

6. 根據方向權重與平滑函數得到的系數對當前像素賦值。

matlab代碼如下:

clear all;close all;clc;

n = 256;        %噪聲圖像大小
cellsize = 10;  %網格大小,不同的大小會產生不同尺度的噪聲

G = rand(2,n/cellsize+2,n/cellsize+2)-0.5; %每個網格頂點的隨機方向向量

img = zeros(n);
for i=1:n
    for j=1:n

        indi = i/cellsize+1;        
        indj = j/cellsize+1;
        
        floori = floor(indi);
        floorj = floor(indj);
        
        d00 = [indi indj] - [floori floorj];        %計算當前點到當前網格四個角點距離
        d10 = [indi indj] - [floori+1 floorj];
        d01 = [indi indj] - [floori floorj+1];
        d11 = [indi indj] - [floori+1 floorj+1];
        
        s = sum(G(:,floori,floorj).*d00');          %當前網格四個角點方向向量對當前點的方向權重
        t = sum(G(:,floori+1,floorj).*d10');
        u = sum(G(:,floori,floorj+1).*d01');
        v = sum(G(:,floori+1,floorj+1).*d11');
        
        dx = indi - floori;
        dy = indj - floorj;
        
        sy = 6*dy.^5-15*dy.^4+10*dy.^3;   %符合f(0) = 0,f(0.5)=0.5,f(1)=1的方程,滿足二階導數連續
        sx = 6*dx.^5-15*dx.^4+10*dx.^3;   %用於描述網格內的起伏
        
        a = s + (t-s)*sx;
        b = u + (v-u)*sx;

        img(i,j) = a + (b-a)*sy;
    end
end
imshow(img,[])

網格25生成的圖像:

網格10生成的圖像:

最后不同網格尺度生成的噪聲也能夠進行疊加,得到更多種類的噪聲。

參考:

https://blog.csdn.net/candycat1992/article/details/50346469

http://www.twinklingstar.cn/2015/2581/classical-perlin-noise/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM