簡體   English   中英

JavaScript 數組的 2D 卷積

[英]2D Convolution for JavaScript Arrays

我對 JavaScript 相當陌生。 我正在嘗試實現http://www.songho.ca/dsp/convolution/convolution.html for C in JavaScript for a web app 中描述的 2D 卷積。

function conv_2d(kernel, array){
    var result = uniform_array(array.length, uniform_array(array[0].length, 0));
    var kRows = kernel.length;
    var kCols = kernel[0].length;
    var rows = array.length;
    var cols = array[0].length;
    // find center position of kernel (half of kernel size)
    var kCenterX = Math.floor(kCols/2);
    var kCenterY = Math.floor(kRows/2);
    var i, j, m, n, mm, nn;

    for(i=0; i < rows; ++i){          // for all rows
        for(j=0; j < cols; ++j){          // for all columns
            for(m=0; m < kRows; ++m){         // for all kernel rows
                for(n=0; n < kCols; ++n){        // for all kernel columns
                    // index of input signal, used for checking boundary
                    var ii = i + (m - kCenterY);
                    var jj = j + (n - kCenterX);
                    // ignore input samples which are out of bound
                    if(ii >= 0 && ii < rows && jj >= 0 && jj < cols){
                        result[i][j] += array[ii][jj] * kernel[m][n];
                    };
                };
            };
        };
    };
    return result;
};

function uniform_array(len, value) {
    let arr = new Array(len); for (let i=0; i<len; ++i) arr[i] = value;
    return arr;
}

現在,我試圖查看我做錯了什么,但我找不到錯誤。 我所知道的是,對同一對矩陣應用 2D 卷積,javascript 中的結果給了我輸出矩陣中每一行的所有行的總和。 我發現與 C++ 中的輸出相比:

JavaScript 輸出:

0: (9) [75, 150, 225, 300, 375, 450, 525, 600, 425]
1: (9) [75, 150, 225, 300, 375, 450, 525, 600, 425]
2: (9) [75, 150, 225, 300, 375, 450, 525, 600, 425]
3: (9) [75, 150, 225, 300, 375, 450, 525, 600, 425]
4: (9) [75, 150, 225, 300, 375, 450, 525, 600, 425]
5: (9) [75, 150, 225, 300, 375, 450, 525, 600, 425]
6: (9) [75, 150, 225, 300, 375, 450, 525, 600, 425]
7: (9) [75, 150, 225, 300, 375, 450, 525, 600, 425]
8: (9) [75, 150, 225, 300, 375, 450, 525, 600, 425]

C++ 輸出(正確):

     6    12    18    24    30    36    42    48    34
     9    18    27    36    45    54    63    72    51
     9    18    27    36    45    54    63    72    51
     9    18    27    36    45    54    63    72    51
     9    18    27    36    45    54    63    72    51
     9    18    27    36    45    54    63    72    51
     9    18    27    36    45    54    63    72    51
     9    18    27    36    45    54    63    72    51
     6    12    18    24    30    36    42    48    34

這個結果來自一個統一的 3x3 核和一個矩陣的卷積,矩陣是:

0: (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
1: (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
2: (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
3: (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
4: (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
5: (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
6: (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
7: (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
8: (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]

任何幫助將不勝感激!

這看起來對嗎? 我更改了 uniform_array 以使其創建新數組,而不是每一行都指向相同的數組。

 const array = [ [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], ]; const kernel = [ [1,1,1], [1,1,1], [1,1,1], ]; function uniform_array(len, value) { let arr = new Array(len); for (let i=0; i<len; ++i) arr[i] = Array.isArray(value) ? [...value] : value; return arr; } function conv_2d(kernel, array){ var result = uniform_array(array.length, uniform_array(array[0].length, 0)); var kRows = kernel.length; var kCols = kernel[0].length; var rows = array.length; var cols = array[0].length; // find center position of kernel (half of kernel size) var kCenterX = Math.floor(kCols/2); var kCenterY = Math.floor(kRows/2); var i, j, m, n, ii, jj; for(i=0; i < rows; ++i){ // for all rows for(j=0; j < cols; ++j){ // for all columns for(m=0; m < kRows; ++m){ // for all kernel rows for(n=0; n < kCols; ++n){ // for all kernel columns // index of input signal, used for checking boundary ii = i + (m - kCenterY); jj = j + (n - kCenterX); // ignore input samples which are out of bound if(ii >= 0 && ii < rows && jj >= 0 && jj < cols){ result[i][j] += array[ii][jj] * kernel[m][n]; }; }; }; }; }; return result; }; conv_2d(kernel, array).forEach(row => console.log(row.join(' ')));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM