在HTML5 canvas裏用卷積核進行圖像處理

卷積

什麼是卷積?

就跳過一些用專業屬於描述專業術語看完懵逼的解釋了,
語文成績不好的我嘗試從字面解釋什麼是卷積...
,理解成一種壓縮;,乘積,積累;
卷積須要一個卷積核,一般是3x3或5x5的方陣,
例如這樣git

// 一個3x3卷積核
0 0 0
0 1 0
0 0 0

咱們要怎麼用卷積核處理數據呢?
下面是一個例子:github

// 下面是一堆排成方陣的數據
// 這是咱們的數據源
1 3 5 1 3 5 1 3 5
4 5 6 1 3 5 1 3 5
4 5 6 1 3 5 1 3 5
4 5 6 1 3 5 1 3 5

咱們將要用卷積核「掃描並處理」每個數據,
例如要處理第二行第二列的5canvas

1 3 5     0 0 0
4 5 6  *  0 1 0
4 5 6     0 0 0

咱們把5周圍的數字抽出來,而後把兩個方陣位置相同的數字相乘而後相加,
得出5,這是固然的,由於這個卷積核作的就是輸出原數據😂數組

-1 -1 -1
-1  8 -1
-1 -1 -1

一樣的原理,試試另外一個不一樣的卷積核網絡

1 3 5     -1 -1 -1
4 5 6  *  -1  8 -1
4 5 6     -1 -1 -1

咱們獲得的是ssh

1*-1 + 3*-1 + 5*-1
+ 4*-1 + 5*8  + 6*-1
+ 4*-1 + 5*-1 + 6*-1
= 6

而後用得出來的6放入原來5的位置,就是這樣「掃描並處理」每個數據學習

邊緣怎麼辦?

  • 常數填充
  • 複製邊緣像素

忽然的深度拓展

卷積在深度學習中十分重要,下面是一個可視化CNN(卷積神經網絡)的卷積過程
http://scs.ryerson.ca/~aharle...測試

canvas

<canvas>是一個可使用腳本(一般爲JavaScript)來繪製圖形的 HTML 元素.它能夠用於繪製圖表、製做圖片構圖或者製做簡單的(以及不那麼簡單的)動畫。

canvas 繪製圖片

ctx.drawImage(image, x, y)

clipboard.png

canvas 轉換爲 ImageData

ctx.getImageData(sx, sy, sw, sh);
// 返回 ImageData

ImageData 數據是 Uint8ClampedArray ,它描述了一個一維數組,包含以 RGBA 順序的數據,數據使用 0 至 255(包含)的整數表示。
因此每個點都會表示爲:動畫

// 這樣僅僅是一個像素點的數據
R   G   B   A
255 255 0 255

卷積 + ImageData = ?

圖像歸根到底就是一大堆的顏色點矩陣,咱們徹底能夠把顏色點代替上面的數字矩陣處理,
不一樣的卷積覈對圖片的處理結果以下(圖片來自維基百科)
圖片來自維基百科this

卷積就是如此神奇😂

在 canvas 中實現卷積處理

如下是一個 JavaScript 對 canvas 輸出的 ImageData 進行卷積的實例:

/* 
 * 參數中的 kernel 就是卷積核方陣,不過順着排列成了一個九位的數組
 * 像是這樣 [-1, -1, -1, -1, 8, -1, -1, -1, -1]
 * offset 對RGBA數值直接增長,表現爲提升亮度
 * 下面的for循環
 * y 表明行,x 表明列,c 表明RGBA
 */
convolutionMatrix(input, kernel, offset = 0) {
  let ctx = this.outputCtx
  let output = ctx.createImageData(input)
  let w = input.width,
    h = input.height
  let iD = input.data,
    oD = output.data
  for (let y = 1; y < h - 1; y += 1) {
    for (let x = 1; x < w - 1; x += 1) {
      for (let c = 0; c < 3; c += 1) {
        let i = (y * w + x) * 4 + c
        oD[i] =
          offset +
          (kernel[0] * iD[i - w * 4 - 4] +
            kernel[1] * iD[i - w * 4] +
            kernel[2] * iD[i - w * 4 + 4] +
            kernel[3] * iD[i - 4] +
            kernel[4] * iD[i] +
            kernel[5] * iD[i + 4] +
            kernel[6] * iD[i + w * 4 - 4] +
            kernel[7] * iD[i + w * 4] +
            kernel[8] * iD[i + w * 4 + 4]) /
            this.divisor
      }
      oD[(y * w + x) * 4 + 3] = 255
    }
  }
  ctx.putImageData(output, 0, 0)
}

成品代碼

https://github.com/ssshooter/...

測試網址,附帶彩蛋嘻嘻嘻😘

https://ssshooter.github.io/c...

相關文章
相關標籤/搜索