圖片濾波

圖片濾波

什麼是濾波

濾波是將信號中特定波段頻率濾除的操作,是抑制和防止干擾的一項重要措施。是根據觀察某一隨機過程的結果,對另一與之有關的隨機過程進行估計的概率理論與方法。

圖片和波如何結合

在不考慮透明度的情況下,圖片可以由rgb構成,如果把rgb單獨抽出來,可以得到3組由(0-255)構成的數組。再把這3組數組在座標系中顯示的話,可以得到3條連續的線。通過觀察線的頻率,可以看出圖片顏色的平滑度。如果線段斜率越小說明該線段內的顏色越平滑,反之則反差越大。

如何濾波

方法一:使用AudioContext

濾波這種術語,一般會用在音頻處理上,通過修改音頻的頻率從而達到修改聲音的表現。例如AudioContext就有提供濾波函數createBiquadFilter ,其內部提供了一系列的濾波算法,例如高通濾波highpass ,低通濾波lowpass 。所以我們可以利用它的api去處理圖片。

圖1
圖2
上圖出處:圖像與濾波

從上圖可以看出曲線波動的地方就是圖片邊緣處,色差越大,波動越大。

方法二:通過卷積算法

什麼是卷積

這裏對卷積的理解有點抽象,所以直接跳過

卷積應用於圖片

定義

用一個模板和一幅圖像進行卷積,對於圖像上的一個點,讓模板的原點和該點重合,然後模板上的點和圖像上對應的點相乘,然後各點的積相加,就得到了該點的卷積值。對圖像上的每個點都這樣處理。由於大多數模板都是對稱的,所以模板不旋轉。卷積是一種積分運算,用來求兩個曲線重疊區域面積。可以看作加權求和,可以用來消除噪聲、特徵增強。

卷積運算圖

卷積運算圖
此圖出處:onvolutional Neural Networks - Basics

卷積運算圖-圖2
此圖出處:如何理解卷積
通過上面兩張圖中,中間層的是卷積核(模版),可以看出其計算規則。而不同的濾波方式有對應的卷積核。
其實不難看出每個像素點的卷積計算其實都是和自身周圍的像素進行計算而得到新的像素值。

卷積核

卷積核一般爲奇數寬高的矩陣,一般爲33,55。矩陣越大計算量越大

對應算法實現

function convolution (pixels:ImageData, weights:number[]) {
  const side = Math.round(Math.sqrt(weights.length))
  const halfSide = Math.floor(side / 2)
  const src = pixels.data
  const canvasWidth = pixels.width
  const canvasHeight = pixels.height
  const temporaryCanvas = document.createElement('canvas')
  const temporaryCtx = temporaryCanvas.getContext('2d')!
  const outputData = temporaryCtx.createImageData(canvasWidth, canvasHeight)

  for (let y = 0; y < canvasHeight; y++) {
    for (let x = 0; x < canvasWidth; x++) {
      const dstOff = (y * canvasWidth + x) * 4
      let sumReds = 0
      let sumGreens = 0
      let sumBlues = 0

      for (let kernelY = 0; kernelY < side; kernelY++) {
        for (let kernelX = 0; kernelX < side; kernelX++) {
          const currentKernelY = y + kernelY - halfSide
          const currentKernelX = x + kernelX - halfSide

          if (currentKernelY >= 0 &&
              currentKernelY < canvasHeight &&
              currentKernelX >= 0 &&
              currentKernelX < canvasWidth) {
            const offset = (currentKernelY * canvasWidth + currentKernelX) * 4
            const weight = weights[kernelY * side + kernelX]

            sumReds += src[offset] * weight
            sumGreens += src[offset + 1] * weight
            sumBlues += src[offset + 2] * weight
          }
        }
      }

      outputData.data[dstOff] = sumReds
      outputData.data[dstOff + 1] = sumGreens
      outputData.data[dstOff + 2] = sumBlues
      outputData.data[dstOff + 3] = 255
    }
  }
  return outputData
}

低通濾波

低通濾波去掉了高頻信息,即細節信息,留下的低頻信息代表了概貌。常用的例子,比如美圖秀秀的磨皮,去掉了臉部細節信息(痘坑,痘印,暗斑等)。

高通濾波

高通濾波會過濾低頻信息,保留高頻信息。上面我們說過斜率越高說明顏色差異越大這裏往往是圖片邊緣部分,也表示頻率越高。所以只保留高頻信號的話,說明只保留了圖片的邊緣部分。所以高通濾波往往用做邊緣處理。

不同的濾波對應卷積核

均值濾波(加權平均模糊)
const weights = [
	1/9, 1/9, 1/9,
	1/9, 1/9, 1/9,
	1/9, 1/9, 1/9,
]

從上面的卷積核可以看出該卷積核的值之和爲1,所以的目標是將目標像素點的值取周圍的平均數,所以用該卷積核處理圖片的結果會是模糊該圖片,不過因爲使用的是均值,所以圖片不會很自然。一般使用高斯模糊濾波用作處理圖片模糊。

高斯濾波

高斯模糊就是在均值濾波的基礎上使用正態分佈,通俗講就是9宮格內的數值之和還是1,不過它們不是簡單的均分了而是具有權重。越靠近中心的值會越大,所以高斯模糊相對均值模糊會和原圖更加貼切。

正態分佈的二維函數如下圖:
二維正態分佈

根據上面的公式可推導出的高斯矩陣方法:

function createGaussWeights (radius:number, sigma:number) {
  const gaussMatrix = []
  let gaussSum = 0
  radius = Math.floor(radius) || 3
  sigma = sigma || radius / 3
  const a = 1 / 2 * Math.PI * (sigma ** 2)
  const b = -1 / (2 * (sigma ** 2))
  let i = 0
  // 生成高斯矩陣
  for (let y = radius; y >= -radius; y--) {
    for (let x = -radius; x <= radius; x++) {
      const g = a * Math.exp(b * (x ** 2 + y ** 2))
      gaussMatrix[i++] = g
      gaussSum += g
    }
  }
  // 歸一化
  for (let i = 0, len = gaussMatrix.length; i < len; i++) {
    gaussMatrix[i] /= gaussSum
  }
  return gaussMatrix
}

下圖是3*3,模糊半徑1.5的高斯模糊矩陣
高斯模糊矩陣

高斯模糊屬於什麼濾波?

這裏高斯模糊和均值濾波都屬於低通濾波,爲什麼呢?
因爲它們的本質就是將目標像素取周圍像素的平均值,所以邊緣的差異性會降低。我們上面說過頻率越高說明顏色差異越大,反過來顏色差異降低的話,頻率也就降低了,相當於過濾了高頻部分了。讓圖片更加平滑

highpass高通濾波
const weights = [
	-1, -1, -1,
	-1, 8, -1,
	-1, -1, -1,
]

這個是高通濾波的卷積核,可以看出是中間爲正數,其餘8個爲-1,它們之和爲0,經過該濾波器,可以看出如果中間的值比四周的大,則會得到放大期和周圍的差值,相反比四周的小的話,則得到的是負數,即黑色。這樣就會得到圖片的邊緣圖。

laplacian拉普拉斯濾波
const weights = [
	0, -1, 0,
	-1, 4, -1,
	0, -1, 0,
]

拉普拉斯濾波也屬於高通濾波,不過它比較的像素點是上下左右四個,不過最終還是能得到圖片的邊緣效果

應用場景

識別滑塊圖形驗證碼

操作步驟如下

  • 使用高斯模糊去除圖片噪點
  • 使用高通濾波獲取滑塊位置的邊緣
  • 調節圖片亮度,過濾無用邊緣,方便後面計算
  • 掃描圖片像素點,篩選出亮度>10且連續最多的x座標

製作各式各樣濾鏡的圖片

  • 高斯模糊
  • 圖片銳化(高通濾波)
  • 圖片浮雕(浮雕濾波器)
  • 運動模糊
// 浮雕濾波器
[
-1, -1, 0,
-1, 0, 1,
0, 1, 1
]

// 運動模糊
[
1/3, 0, 0,
0, 1/3, 0,
0, 0, 1/3, 
]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章