圖像卷積
卷積如圖:
卷積就是循環對圖像跟一個核逐個元素相乘再求和得到另外一副圖像的操作,比如結果圖中第一個元素5是怎麼算的呢?原圖中3×3的區域與3×3的核逐個元素相乘再相加:
5=1×1+2×0+1×0+0×0+1×0+1×0+3×0+0×0+2×2
具體計算方式如圖,計算完成就向右移動一格
padding
3×3的核對一副6×6的圖像進行卷積,得到的是4×4的圖
事實上,原圖爲n×n,卷積核爲f×f,最終結果圖大小爲(n-f+1) × (n-f+1)。
OpenCV中有好幾種填充方式,都使用cv2.copyMakeBorder()函數實現
其中默認方式和固定值方式最常用,我們詳細說明一下:
添加邊框
cv2.copyMakeBorder()用來給圖片添加邊框,它有下面幾個參數:
- src:要處理的原圖
- top, bottom, left, right:上下左右要擴展的像素數
- borderType:邊框類型,這個就是需要關注的填充方式,詳情請參考:BorderTypes
[BorderTypes]:
-
BORDER_CONSTANT
iiiiii|abcdefgh|iiiiiii with some specified i,需要指定 ’ i ’ 即就是邊沿像素用i替換。 -
BORDER_REPLICATE
aaaaaa|abcdefgh|hhhhhhh,複製邊界像素 -
BORDER_REFLECT
fedcba|abcdefgh|hgfedcb ,反射覆制邊界像素 -
BORDER_WRAP
cdefgh|abcdefgh|abcdefg 用另一邊的像素來補償填充 -
BORDER_REFLECT_101
gfedcb|abcdefgh|gfedcba 以邊界爲對稱軸反射覆制像素 -
BORDER_TRANSPARENT
uvwxyz|abcdefgh|ijklmno,應該是透明邊框的意思吧 -
BORDER_REFLECT101
與BORDER_REFLECT_101相同 -
BORDER_DEFAULT
與BORDER_REFLECT_101相同,爲默認填充方式 -
BORDER_ISOLATED
不看ROI之外部分
import cv2
img = cv2.imread('doge.jpg',0)
print(img)
cv2.imshow("origin",img)
cons = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_CONSTANT, value=0)
print(cons)
cv2.imshow("BORDER_CONSTANT",cons)
cv2.waitKey(0)
固定
值填充
import cv2
img = cv2.imread('doge.jpg',0)
print(img)
cons = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_CONSTANT, value=0)
print(cons)
cv2.imshow("aaa",cons)
cv2.waitKey(0)
默認邊框類型
import cv2
img = cv2.imread('doge.jpg',0)
print(img)
cv2.imshow("origin",img)
cons = cv2.copyMakeBorder(img, 100, 100, 100, 100, cv2.BORDER_DEFAULT)
print(cons)
cv2.imshow("BORDER_DEFAULT",cons)
cv2.waitKey(0)
同理再進行左右兩邊的填充,最後把四個頂點補充上就好了,頂點是對角線填充的:
一般情況下默認方式更加合理,因爲邊界的像素值更加接近。具體應視場合而定。
OpenCV進行卷積
import cv2
import numpy as np
img = cv2.imread('lena.jpg')
# 定義卷積核
kernel = np.ones((3, 3), np.float32) / 10
# 卷積操作,-1表示通道數與原圖相同
dst = cv2.filter2D(img, -1, kernel)
cv2.imshow('lena', img)
cv2.imshow('lena/10', dst)
cv2.waitKey(0)
OpenCV中用cv2.filter2D()實現卷積操作,比如我們的核是下面這樣(3×3區域像素的和除以10):