为了账号安全,请及时绑定邮箱和手机立即绑定

JavaScript 数组的 2D 卷积

JavaScript 数组的 2D 卷积

MYYA 2023-07-06 14:54:15
我对 JavaScript 还很陌生。我正在尝试在 Web 应用程序的 JavaScript 中实现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]
查看完整描述

1 回答

?
森栏

TA贡献1810条经验 获得超5个赞

这看起来合适吗?我更改了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(' ')));


查看完整回答
反对 回复 2023-07-06
  • 1 回答
  • 0 关注
  • 99 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信