Opencv-Python 學習之旅 - 4

Image Processing in OpenCV

Posted by Bobson Lin on Sunday, December 16, 2018

影像平滑


阿洲的程式教學 | OpenCV教學 - 影像平滑 引述:
有時我們收到的影像雜訊過多,這時需要進行平滑化去除雜訊,不過為了去除雜訊,可能造成影像對比度下降,好的品質可能需要大量的處理時間,所以通常根據實際需求,選擇一個適合的手法,常見的有四種平滑方式,分別是平均平滑、高斯平滑、中值濾波、雙邊濾波,OpenCV對於這四種平滑方式皆有支援,只要呼叫即可使用。


由濾波方式可分兩種,線性濾波和非線性濾波:
* 線性濾波:有一個有固定參數的核心,常見的有平均平滑和高斯平滑。
* 非線性濾波:沒有一個有固定參數的核心,常見的有中值濾波和雙邊濾波。


OpenCV functions:
* 平均平滑: cv2.filter2Dcv2.blur
* 高斯平滑: cv2.GaussianBlur
* 中值濾波: cv2.medianBlur
* 雙邊濾波: cv2.bilateralFilter

import cv2
import numpy as np
from matplotlib import pyplot as plt


def draw_on_plot(pos, src, title):
    plt.subplot(pos), plt.imshow(src), plt.title(title)
    plt.xticks([]), plt.yticks([])


img = cv2.imread('data/opencv-logo-white.png')

draw_on_plot(241, img, 'Original')

kernel = np.ones((3, 3), np.float32)/25
dst = cv2.filter2D(img, -1, kernel)
draw_on_plot(242, dst, 'Averaging 3x3')

kernel = np.ones((5, 5), np.float32)/25
dst = cv2.filter2D(img, -1, kernel)
draw_on_plot(243, dst, 'Averaging 5x5')

kernel = np.ones((7, 7), np.float32)/25
dst = cv2.filter2D(img, -1, kernel)
draw_on_plot(244, dst, 'Averaging 7x7')

blur = cv2.blur(img, (5, 5))
draw_on_plot(245, blur, 'Blurred')

gaussian_blur = cv2.GaussianBlur(img, (5, 5), 0)
draw_on_plot(246, gaussian_blur, 'Gaussian Blurred')

median_blur = cv2.medianBlur(img, 5)
draw_on_plot(247, gaussian_blur, 'Median Blurred')

bilateral_filter = cv2.bilateralFilter(img, 9, 75, 75)
draw_on_plot(248, bilateral_filter, 'Bilateral Filter')

plt.show()
  • 影像平滑又可以理解為消除雜訊,利用低通濾波器,維持圖片低頻部份,削減高頻部份。(高低頻是指影像鄰近區域內數值變化大或小)
  • 濾波器(或稱遮罩)通常是奇數的方形矩陣(3x3、5x5…);遮罩尺寸越大,平滑(模糊)效果會越明顯。
  • 輸出的中央值由鄰近區域的數值配合濾波器計算後得出。
  • 相關 API 文檔 Image Filtering
  • 結果: smoothing_image

形態學


阿洲的程式教學 | OpenCV教學 - 侵蝕、膨脹引述:
形態學主要用於二值化後的影像,根據使用者的目的,用來凸顯影像的形狀特徵,像邊界和連通區域等…

import cv2
import numpy as np

from matplotlib import pyplot as plt


def draw_on_plot(pos, src, title):
    plt.subplot(pos), plt.imshow(src, cmap='gray'), plt.title(title)
    plt.xticks([]), plt.yticks([])


img = cv2.imread('data/j.png', 0)
kernel = np.ones((5, 5), np.uint8)
erosion = cv2.erode(img, kernel, iterations=1)
dilation = cv2.dilate(img, kernel, iterations=1)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

draw_on_plot(241, img, 'Original')
draw_on_plot(242, erosion, 'Erosion')
draw_on_plot(243, dilation, 'Dilation')
draw_on_plot(244, opening, 'Opening')
draw_on_plot(245, closing, 'Closing')
draw_on_plot(246, gradient, 'Gradient')
draw_on_plot(247, tophat, 'Top hat')
draw_on_plot(248, blackhat, 'Black hat')

plt.show()
  • 侵蝕(erosion)為消融物體的邊界(消除圖像的一些雜訊);膨脹(dilation)為增強(擴大)所偵測到的邊界。
  • 開運算是先侵蝕後膨脹(可用於指紋分析),閉運算是先膨脹後侵蝕(可用於圖像修復)。
  • 侵蝕:鄰近區域內有黑色像素,則將中間值變為黑色。
  • 膨脹:鄰近區域內有白色像素,則將中間值變為白色。
  • 相關 API 文檔 Image Filtering
  • 結果: morphological_transform

你也可以瞧瞧…

參考

系列文
待補