濾鏡

      在〈濾鏡〉中尚無留言

基本名詞

Image Patch: 以某一點為中心,往外的一小區塊,大小如3*3,5*5。如下圖,中心點為藍色的點,其值170為某一Channel的值(如R Channel)。藍色往外一圈, 則為 3*3格,此9格稱為 Image Patch

kernel : 用來與 Image patch進行捲積的值。所以Image patch若為 3*3 格, 則kernel亦必需為 3*3格。下圖為隨易給一個kernel的值

捲積(convolution) : 上述的patch * kernel 值,如
180*-1 + 191*0 + 160*1 + 100*-2 + 170 *0 + 187 *2 + 160*-1 + 125*0 + 193 *1 = 187
計算後,上述藍色格子原本170的值將被 187 取代之。

進行捲積時,是每一個點的每一個Channel 都要進行捲積運算

平滑模糊

圖像在執行更複雜的操作之前,會對圖像進行預處理或調整,減少雜訊或閾值的不必要變化。這就是摸糊的功能。

平均濾波可以將影像模糊化。底下(50,50)為內核大小,若將大小縮小,可以將邊緣細緻化。本代碼使用(50,50)是因為圖檔為高清畫質。如果加大其值,模糊的效果就愈明顯。平滑模糊對每個點的權重都是 1。

import cv2
import pylab as plt
img=cv2.imread('girl.jpg')
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
blur = cv2.blur(img, (50, 50))
plt.subplot(121), plt.imshow(img), plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(blur), plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()

高斯模糊

高斯模糊使用平均像素值與相鄰像素的值來平滑圖像,其平均值具有高斯衰減效應。高斯模糊對每個點的權重都不一樣,愈中間權重愈大,愈往邊角權重愈低。高斯模糊讓圖片的失真度較小,平滑模糊的失真度較大。

高斯模糊可以使用cv2.GaussianBlur函數,參數如下 cv2.GaussianBlur(src, (kernel size), sigmaX, sigmaY, borderType)

src : 原圖
(kernel size) : 如(55,55),其值只能為奇數。若kernel為是(0,0), 致少需指定下一個數字 sigmaX
sigmaX : x軸(水平方向) 的內核標準差。只有 (kernel size)為(0,0)才有作用
sigmaY : y軸(垂直方向) 的內核標準差。只有 (kernel size)為(0,0)才有作用

img=cv2.imread('girl.jpg')
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img2 = cv2.GaussianBlur(img, (55, 55), 0)
plt.subplot(131), plt.imshow(img2), plt.title('GaussianBlur(55,55)')
plt.xticks([]), plt.yticks([])
img2 = cv2.GaussianBlur(img, (0, 0), sigmaX=25, sigmaY=0)
plt.subplot(132), plt.imshow(img2), plt.title('GaussianBlur sigmaX=25')
plt.xticks([]), plt.yticks([])
img3 = cv2.GaussianBlur(img, (0, 0), sigmaX=1, sigmaY=25)
plt.subplot(133), plt.imshow(img3), plt.title('GaussianBlur sigmaY=25')
plt.xticks([]), plt.yticks([])
plt.show()

銳利化

使用cv2.filter2D() 方法進行銳利化

#sharp
@staticmethod
def sharp(src, kernel=np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32)):
return cv2.filter2D(src, -1, kernel=kernel)

底下二個kernel效果差不多,不過也要看不同的圖片才能得知

kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32)
kernel = np.array([[-0.125, -0.125, -0.125, -0.125, -0.125],
[-0.125, 0.25, 0.25, 0.25, -0.125],
[-0.125, 0.25, 1, 0.25, -0.125],
[-0.125, 0.25, 0.25, 0.25, -0.125],
[-0.125, -0.125, -0.125, -0.125, -0.125]], np.float32)

二者差異如下

import numpy as np
import pylab as plt
from MahalCv import MahalCv as cv
img=cv.read('girl.jpg')
img=cv.resize(img, scale=0.2)
cv.pltshow(cv.bgr2rgb(cv.sharp(img, kernel=np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32))), 1, 2, 1)
cv.pltshow(cv.bgr2rgb(cv.sharp(img, kernel = np.array([
[-0.125, -0.125, -0.125, -0.125, -0.125],
[-0.125, 0.25, 0.25, 0.25, -0.125],
[-0.125, 0.25, 1, 0.25, -0.125],
[-0.125, 0.25, 0.25, 0.25, -0.125],
[-0.125, -0.125, -0.125, -0.125, -0.125]], np.float32))), 1, 2, 2)
plt.show()

邊緣偵測

kernel : [[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]]
當周邊的值一樣,經上述 kernel 捲積計算,會得到 (-1*8+8)=0。也就是背影色一樣時,全部歸 0 變成黑色。非背景時,顏色不一致,就會凸顯出來,而形成邊緣檢測。這是由美國艾爾文.索伯(Sobel)及蓋瑞.費德曼(Gary Feldman)於1968年發明的,所以又稱為 Sobel filter

邊緣偵測可以使用cv2.Canny()達成。在偵測邊緣前,若能先把影像灰階化,再模糊化,然後才偵測邊緣,可以達到更好的效果。

import cv2
from MahalCv import MahalCv
image=cv2.imread('buddha.jpg')
image=MahalCv.resize(image, 0.2)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
canny = cv2.Canny(blurred, 30, 150)
#canny = cv2.Canny(gray, 30, 150)
cv2.imshow('Input', image)
cv2.imshow('Result', canny)
cv2.waitKey(0)

底下這張圖,也可用上述程式進行道路車道偵測

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *