最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于JavaScript實(shí)現(xiàn)線性漸變的高斯模糊效果

 更新時(shí)間:2024年01月31日 08:23:03   作者:慕仲卿  
這篇文章主要為大家詳細(xì)介紹了高斯模糊算法以及線性漸變的高斯模糊算法的原理,并通過(guò)一個(gè)小demo展示了如何實(shí)現(xiàn)y方向上線性漸變的高斯模糊效果,需要的可以了解下

本文首先介紹了高斯模糊算法然后敘述了線性漸變的高斯模糊算法的原理,最后通過(guò)一個(gè)小demo展示了如何實(shí)現(xiàn)y方向上線性漸變的高斯模糊效果。

1. 高斯模糊算法

高斯模糊是圖像處理中一種常用的模糊技術(shù),它通過(guò)數(shù)學(xué)上的高斯函數(shù)來(lái)實(shí)現(xiàn)對(duì)圖像的平滑處理。這種模糊效果看起來(lái)像是圖像被輕微地“散開”,能夠有效地減少圖像噪聲和細(xì)節(jié),從而產(chǎn)生一種柔和的視覺效果。高斯模糊原理詳細(xì)說(shuō)明如下:

高斯函數(shù)

高斯函數(shù)(或高斯分布)是一種鐘形的、平滑的曲線,其數(shù)學(xué)表達(dá)式為:

其中,σ是標(biāo)準(zhǔn)差,決定了曲線的寬度。在圖像處理中,高斯函數(shù)用于創(chuàng)建一個(gè)稱為“高斯核”的權(quán)重矩陣。

高斯核

高斯核是一個(gè)二維數(shù)組,用于根據(jù)高斯函數(shù)的值來(lái)給圖像中的每個(gè)像素及其鄰域像素分配權(quán)重。核的中心值最大,表示對(duì)當(dāng)前像素點(diǎn)的權(quán)重最高,而遠(yuǎn)離中心的像素權(quán)重逐漸減小。

模糊過(guò)程

在進(jìn)行高斯模糊時(shí),算法會(huì)遍歷圖像的每個(gè)像素點(diǎn),并對(duì)每個(gè)像素及其周圍的像素應(yīng)用高斯核。具體操作如下:

  • 遍歷像素點(diǎn): 對(duì)圖像中的每個(gè)像素點(diǎn)進(jìn)行遍歷。
  • 應(yīng)用高斯核: 對(duì)于每個(gè)像素點(diǎn),將其鄰域內(nèi)的像素值與高斯核中對(duì)應(yīng)位置的權(quán)重相乘,并對(duì)結(jié)果求和。
  • 更新像素值: 將上述步驟得到的加權(quán)和作為新的像素值。這樣,每個(gè)像素點(diǎn)的新值是其本身及鄰域像素值的加權(quán)平均。

模糊效果

應(yīng)用高斯模糊后,由于鄰域像素的加權(quán)平均作用,圖像中的每個(gè)像素都會(huì)與周圍像素融合,從而產(chǎn)生平滑和模糊的效果。這種模糊處理可以減少圖像的細(xì)節(jié)和噪聲,使圖像看起來(lái)更加柔和。

應(yīng)用場(chǎng)景

高斯模糊在許多領(lǐng)域都有應(yīng)用,包括但不限于:

  • 圖像美化: 使圖像看起來(lái)更柔和、自然。
  • 去除噪聲: 減少圖像的隨機(jī)噪聲。
  • 圖像分割: 在圖像處理的預(yù)處理階段,為了更好地進(jìn)行邊緣檢測(cè)或者特征提取。

高斯模糊的關(guān)鍵在于合理選擇高斯核的大?。?sigma;\sigmaσ值),這直接影響到模糊的程度和效果。

2. 有梯度的高斯模糊效果的實(shí)現(xiàn)

要在y方向上實(shí)現(xiàn)有梯度的高斯模糊,可以通過(guò)動(dòng)態(tài)調(diào)整高斯核的標(biāo)準(zhǔn)差(σ值)來(lái)實(shí)現(xiàn)。具體來(lái)說(shuō),隨著y坐標(biāo)的變化,逐漸增加或減少σ值,從而在垂直方向上產(chǎn)生漸變的模糊效果。

1. 動(dòng)態(tài)調(diào)整σ值

對(duì)于圖像中的每一行,根據(jù)其y坐標(biāo)動(dòng)態(tài)計(jì)算σ值。可以設(shè)計(jì)一個(gè)函數(shù),使σ值從圖像頂部到底部線性增加或減少。

2. 生成高斯核

針對(duì)每一行的σ值,生成對(duì)應(yīng)的高斯核。由于每行的σ值不同,所以每行的高斯核也將不同。

3. 應(yīng)用高斯模糊

使用生成的高斯核對(duì)每一行進(jìn)行模糊處理。具體來(lái)說(shuō),對(duì)于圖像中的每個(gè)像素,使用其所在行的高斯核進(jìn)行加權(quán)平均計(jì)算,得到新的像素值。

4. 實(shí)現(xiàn)梯度效果

由于每行的模糊程度隨σ值變化,因此整個(gè)圖像在垂直方向上將呈現(xiàn)出漸變的高斯模糊效果。

5. 偽代碼

function applyGradientGaussianBlur(ctx, width, height) {
    const copy = ctx.getImageData(0, 0, width, height);
    const copyData = copy.data;

    for (let y = 0; y < height; y++) {
        const sigma = calculateSigmaForRow(y, height);
        const kernel = getGaussianKernel(sigma);
        // 應(yīng)用高斯模糊到這一行...
    }

    ctx.putImageData(copy, 0, 0);
}

function calculateSigmaForRow(row, height) {
    const maxSigma = 5;  // 假設(shè)最大sigma值為5
    return maxSigma * (row / height); // 使sigma值隨y坐標(biāo)線性增加
}

function getGaussianKernel(sigma) {
    // 根據(jù)sigma值生成高斯核...
}

這個(gè)函數(shù)會(huì)根據(jù)y坐標(biāo)的變化來(lái)調(diào)整σ值,并為每一行生成相應(yīng)的高斯核,從而實(shí)現(xiàn)在y方向上的漸變高斯模糊效果。

3. 構(gòu)建測(cè)試框架

為了對(duì)比采用線性漸變的高斯模糊效果,需要搭建一個(gè)簡(jiǎn)單的html文件用來(lái)對(duì)比應(yīng)用前后的效果:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>高斯模糊示例</title>
    <style>
        body {
            display: flex;
            flex-direction: row;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f0f0f0;
        }

        canvas {
            border: 1px solid black;
        }
    </style>
</head>

<body>
    <div style="margin-right: 50px;">
        <h1>模糊之后</h1>
        <canvas id="canvas"></canvas>
    </div>
    <div>
        <h1>模糊之前</h1>
        <canvas id="canvas2"></canvas>
    </div>


    <script>
        window.onload = function () {
            const canvas = document.getElementById('canvas');
            const canvas2 = document.getElementById('canvas2');
            const ctx = canvas.getContext('2d');
            const ctx2 = canvas2.getContext('2d');
            const img = new Image();
            img.src = 'demo.jpg'; // 替換為你的圖片路徑
            img.onload = function () {
                ...
            };
        };




        function applyGaussianBlur(ctx, width, height, pos) {
            ...
        }

        function calculateSigmaForRow(row, height) {
            ...
        }

        function getGaussianKernel(size, sigma) {
            ...
        }

    </script>
</body>

</html>

4. 詳細(xì)解釋

這段代碼實(shí)現(xiàn)了一個(gè)帶有漸變高斯模糊效果的圖像處理示例。下面分別對(duì)代碼中的關(guān)鍵部分進(jìn)行解釋:

img.onload 回調(diào)函數(shù)

當(dāng)圖像加載完成后,這個(gè)回調(diào)函數(shù)被觸發(fā)。它首先設(shè)置畫布的尺寸以匹配圖像的尺寸。接著,它通過(guò)一個(gè)循環(huán),分塊地將圖像繪制到畫布上,同時(shí)應(yīng)用不同程度的模糊效果。這種逐漸增加模糊度的效果通過(guò)調(diào)整 ctx.filter 屬性來(lái)實(shí)現(xiàn)。

            img.onload = function () {
                canvas.width = img.width;
                canvas.height = img.height;
                canvas2.width = img.width;
                canvas2.height = img.height;
                
                // ctx.drawImage(img, 0, 0);
                // 分10份逐份繪制
                const numOfParts = 200;
                const pos = 3 / 2;
                const parts = 20;
                const partHeight = img.height / numOfParts;

                for (let i = 0; i < numOfParts; i++) {
                    if(i>numOfParts/pos){
                        ctx.filter = `blur(${1.5*(i/parts - numOfParts/pos/parts)}px)`;
                        console.log('i/parts: ', i/parts - numOfParts/pos/parts)
                    } else {
                        ctx.filter = `blur(${0}px)`;
                    }
                    
                    ctx.drawImage(img, 0, i * partHeight, img.width, partHeight, 0, i * partHeight, img.width, partHeight);

                }
                ctx2.drawImage(img, 0, 0);

                applyGaussianBlur(ctx, img.width, img.height, pos);
            };

applyGaussianBlur 函數(shù)

這個(gè)函數(shù)實(shí)現(xiàn)了高斯模糊算法。它接收一個(gè)繪圖上下文(ctx),圖像的寬度和高度,以及一個(gè)控制模糊范圍的位置參數(shù)(pos)。函數(shù)首先獲取畫布上當(dāng)前的圖像數(shù)據(jù)。然后,它對(duì)每個(gè)像素應(yīng)用高斯模糊,基于高斯核和每個(gè)像素周圍的像素值來(lái)計(jì)算新的像素值。

        function applyGaussianBlur(ctx, width, height, pos) {
            const copy = ctx.getImageData(0, 0, width, height);
            const copyData = copy.data;
            const kernelSize = 16; // 高斯核的固定大小

            for (let y = 0; y > height/pos; y++) {
                // 對(duì)于每一行,根據(jù)行號(hào)計(jì)算sigma值
                const sigma = 5 * calculateSigmaForRow(y, height);
                const kernel = getGaussianKernel(kernelSize, sigma);
                const half = Math.floor(kernelSize / 2);

                for (let x = 0; x < width; x++) {
                    let r = 0, g = 0, b = 0, total = 0;
                    for (let ky = -half; ky <= half; ky++) {
                        for (let kx = -half; kx <= half; kx++) {
                            const px = x + kx;
                            const py = y + ky;
                            if (px >= 0 && px < width && py >= 0 && py < height) {
                                const p = (py * width + px) * 4;
                                const weight = kernel[ky + half][kx + half];
                                r += copyData[p] * weight;
                                g += copyData[p + 1] * weight;
                                b += copyData[p + 2] * weight;
                                total += weight;
                            }
                        }
                    }
                    const pos = (y * width + x) * 4;
                    copyData[pos] = r / total;
                    copyData[pos + 1] = g / total;
                    copyData[pos + 2] = b / total;
                }
            }
            ctx.putImageData(copy, 0, 0);
        }

calculateSigmaForRow 函數(shù)

這個(gè)函數(shù)根據(jù)行號(hào)和圖像高度計(jì)算高斯模糊的 sigma 值。這里使用了一個(gè)簡(jiǎn)單的線性關(guān)系來(lái)確定 sigma 的大小,從而創(chuàng)建一種模糊程度隨位置變化的效果。

        function calculateSigmaForRow(row, height) {
            // 示例:線性增長(zhǎng)的sigma
            // 你可以根據(jù)需要調(diào)整這個(gè)函數(shù)來(lái)改變sigma的計(jì)算方式
            const maxSigma = 15; // 最大sigma值
            return maxSigma * (row / height);
        }

getGaussianKernel 函數(shù)

此函數(shù)生成一個(gè)高斯核,這是實(shí)現(xiàn)高斯模糊的關(guān)鍵。高斯核是一個(gè)二維數(shù)組,表示每個(gè)像素與其周圍像素的權(quán)重。這個(gè)核在 applyGaussianBlur 函數(shù)中用于計(jì)算每個(gè)像素的新值。

        function getGaussianKernel(size, sigma) {
            const kernel = [];
            let sum = 0;
            const half = Math.floor(size / 2);
            for (let y = -half; y <= half; y++) {
                kernel[y + half] = [];
                for (let x = -half; x <= half; x++) {
                    const value = Math.exp(-(x * x + y * y) / (2 * sigma * sigma)) / (2 * Math.PI * sigma * sigma);
                    kernel[y + half][x + half] = value;
                    sum += value;
                }
            }
            // 歸一化核
            for (let y = 0; y < size; y++) {
                for (let x = 0; x < size; x++) {
                    kernel[y][x] /= sum;
                }
            }
            return kernel;
        }

整體思路

代碼的主要思想是在圖像的一部分區(qū)域?qū)崿F(xiàn)漸變的高斯模糊效果。這通過(guò)分段繪制圖像并逐步增加模糊程度來(lái)實(shí)現(xiàn)。img.onload 回調(diào)函數(shù)處理圖像的加載和初步處理,而 applyGaussianBlur 函數(shù)則負(fù)責(zé)應(yīng)用高斯模糊算法。calculateSigmaForRowgetGaussianKernel 函數(shù)提供了實(shí)現(xiàn)高斯模糊所需的數(shù)學(xué)計(jì)算。

5. 完整代碼及效果展示

效果展示

完整代碼

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>高斯模糊示例</title>
    <style>
        body {
            display: flex;
            flex-direction: row;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f0f0f0;
        }

        canvas {
            border: 1px solid black;
        }
    </style>
</head>

<body>
    <div style="margin-right: 50px;">
        <h1>模糊之后</h1>
        <canvas id="canvas"></canvas>
    </div>
    <div>
        <h1>模糊之前</h1>
        <canvas id="canvas2"></canvas>
    </div>


    <script>
        window.onload = function () {
            const canvas = document.getElementById('canvas');
            const canvas2 = document.getElementById('canvas2');
            const ctx = canvas.getContext('2d');
            const ctx2 = canvas2.getContext('2d');
            const img = new Image();
            img.src = 'demo.jpg'; // 替換為你的圖片路徑
            img.onload = function () {
                canvas.width = img.width;
                canvas.height = img.height;
                canvas2.width = img.width;
                canvas2.height = img.height;
                
                // ctx.drawImage(img, 0, 0);
                // 分10份逐份繪制
                const numOfParts = 200;
                const pos = 3 / 2;
                const parts = 20;
                const partHeight = img.height / numOfParts;

                for (let i = 0; i < numOfParts; i++) {
                    if(i>numOfParts/pos){
                        ctx.filter = `blur(${1.5*(i/parts - numOfParts/pos/parts)}px)`;
                        console.log('i/parts: ', i/parts - numOfParts/pos/parts)
                    } else {
                        ctx.filter = `blur(${0}px)`;
                    }
                    
                    ctx.drawImage(img, 0, i * partHeight, img.width, partHeight, 0, i * partHeight, img.width, partHeight);

                }
                ctx2.drawImage(img, 0, 0);

                applyGaussianBlur(ctx, img.width, img.height, pos);
            };
        };




        function applyGaussianBlur(ctx, width, height, pos) {
            const copy = ctx.getImageData(0, 0, width, height);
            const copyData = copy.data;
            const kernelSize = 16; // 高斯核的固定大小

            for (let y = 0; y > height/pos; y++) {
                // 對(duì)于每一行,根據(jù)行號(hào)計(jì)算sigma值
                const sigma = 5 * calculateSigmaForRow(y, height);
                const kernel = getGaussianKernel(kernelSize, sigma);
                const half = Math.floor(kernelSize / 2);

                for (let x = 0; x < width; x++) {
                    let r = 0, g = 0, b = 0, total = 0;
                    for (let ky = -half; ky <= half; ky++) {
                        for (let kx = -half; kx <= half; kx++) {
                            const px = x + kx;
                            const py = y + ky;
                            if (px >= 0 && px < width && py >= 0 && py < height) {
                                const p = (py * width + px) * 4;
                                const weight = kernel[ky + half][kx + half];
                                r += copyData[p] * weight;
                                g += copyData[p + 1] * weight;
                                b += copyData[p + 2] * weight;
                                total += weight;
                            }
                        }
                    }
                    const pos = (y * width + x) * 4;
                    copyData[pos] = r / total;
                    copyData[pos + 1] = g / total;
                    copyData[pos + 2] = b / total;
                }
            }
            ctx.putImageData(copy, 0, 0);
        }

        function calculateSigmaForRow(row, height) {
            // 示例:線性增長(zhǎng)的sigma
            // 你可以根據(jù)需要調(diào)整這個(gè)函數(shù)來(lái)改變sigma的計(jì)算方式
            const maxSigma = 15; // 最大sigma值
            return maxSigma * (row / height);
        }

        function getGaussianKernel(size, sigma) {
            const kernel = [];
            let sum = 0;
            const half = Math.floor(size / 2);
            for (let y = -half; y <= half; y++) {
                kernel[y + half] = [];
                for (let x = -half; x <= half; x++) {
                    const value = Math.exp(-(x * x + y * y) / (2 * sigma * sigma)) / (2 * Math.PI * sigma * sigma);
                    kernel[y + half][x + half] = value;
                    sum += value;
                }
            }
            // 歸一化核
            for (let y = 0; y < size; y++) {
                for (let x = 0; x < size; x++) {
                    kernel[y][x] /= sum;
                }
            }
            return kernel;
        }

    </script>
</body>

</html>

以上就是基于JavaScript實(shí)現(xiàn)線性漸變的高斯模糊效果的詳細(xì)內(nèi)容,更多關(guān)于JavaScript高斯模糊的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JavaScript NaN和Infinity特殊值 [譯]

    JavaScript NaN和Infinity特殊值 [譯]

    本文要講的是兩個(gè)特殊值,NaN和Infinity,返回這兩個(gè)值的操作通常都應(yīng)該返回正常的數(shù)字
    2012-09-09
  • JavaScript canvas實(shí)現(xiàn)環(huán)形漸變進(jìn)度條

    JavaScript canvas實(shí)現(xiàn)環(huán)形漸變進(jìn)度條

    這篇文章主要為大家詳細(xì)介紹了JavaScript canvas實(shí)現(xiàn)環(huán)形漸變進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 微信小程序常用賦值方法小結(jié)

    微信小程序常用賦值方法小結(jié)

    這篇文章主要介紹了微信小程序常用賦值方法,結(jié)合實(shí)例形式總結(jié)了微信小程序局部變量、全局變量及data對(duì)象屬性賦值相關(guān)操作技巧,需要的朋友可以參考下
    2019-04-04
  • 在新窗口打開超鏈接的方法小結(jié)

    在新窗口打開超鏈接的方法小結(jié)

    有時(shí)候我們想讓用戶在新窗口打開網(wǎng)站,因?yàn)槟J(rèn)當(dāng)前窗口打開,很多情況下,用戶并不喜歡
    2013-04-04
  • js的window.showModalDialog及window.open用法實(shí)例分析

    js的window.showModalDialog及window.open用法實(shí)例分析

    這篇文章主要介紹了js的window.showModalDialog及window.open用法,實(shí)例分析了window.showModalDialog與window.open方法的定義、功能與使用技巧,需要的朋友可以參考下
    2015-01-01
  • javascript中數(shù)組方法匯總

    javascript中數(shù)組方法匯總

    本文給大家詳細(xì)匯總了一下javascript中的數(shù)組方法,十分的全面細(xì)致,有需要的小伙伴可以參考下。
    2015-07-07
  • JavaScript?Canvas實(shí)現(xiàn)圖片局部放大鏡效果

    JavaScript?Canvas實(shí)現(xiàn)圖片局部放大鏡效果

    這篇文章主要為大家詳細(xì)介紹了如何使用JavaScript?Canvas實(shí)現(xiàn)圖片局部放大鏡效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03
  • 微信小程序獲取用戶信息并保存登錄狀態(tài)詳解

    微信小程序獲取用戶信息并保存登錄狀態(tài)詳解

    這篇文章主要介紹了微信小程序獲取用戶信息并保存登錄狀態(tài),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • 源碼分析Django的message組件

    源碼分析Django的message組件

    這篇文章主要介紹了源碼分析Django的message組件,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • JS實(shí)現(xiàn)加載和讀取XML文件的方法詳解

    JS實(shí)現(xiàn)加載和讀取XML文件的方法詳解

    這篇文章主要介紹了JS實(shí)現(xiàn)加載和讀取XML文件的方法,結(jié)合實(shí)例形式分析了javascript針對(duì)xml文件的加載與讀取相關(guān)實(shí)現(xiàn)步驟與操作技巧,需要的朋友可以參考下
    2017-04-04

最新評(píng)論

谷城县| 洪江市| 日照市| 清苑县| 廉江市| 枝江市| 木兰县| 太仓市| 哈巴河县| 九寨沟县| 开原市| 宜阳县| 宁德市| 武宁县| 永泰县| 旅游| 永川市| 嘉黎县| 石狮市| 苍梧县| 临汾市| 沙田区| 和政县| 成安县| 任丘市| 阿图什市| 临澧县| 新邵县| 简阳市| 德格县| 米易县| 广东省| 舞阳县| 师宗县| 威远县| 开远市| 巴塘县| 宁津县| 咸宁市| 灌南县| 宝兴县|