6、圖像的縮放、翻轉(zhuǎn)、旋轉(zhuǎn)、平移、透視
7、卷積操作:均值濾波、方盒濾波、高斯濾波、中值濾波、雙邊濾波
8、算子操作:sobel算子、scharr算子、拉普拉斯算子、Canny邊緣檢測
9、形態(tài)學(xué)操作:腐蝕、膨脹、開運(yùn)算、閉運(yùn)算、頂帽、黑帽
6、圖像的縮放、翻轉(zhuǎn)、旋轉(zhuǎn)、平移、透視
OpenCV提供了一系列的api,cv.flip、cv.rotate、cv.resize、cv.warpAffine和cv.warpPerspective等,具體算法實(shí)現(xiàn)可查看OpenCV的源碼。原理簡單來說就是要找到像素變換前與變換后的位置坐標(biāo)對應(yīng)關(guān)系。
平移是物體位置的移動。如果知道在(x,y)方向上的位移,則將其設(shè)為(tx, ty),可以創(chuàng)建轉(zhuǎn)換矩陣M,如下所示
圖像旋轉(zhuǎn)角度為θ是通過以下形式的變換矩陣實(shí)現(xiàn)的:
注:證明如下
OpenCV提供了可縮放的旋轉(zhuǎn)以及可調(diào)整的旋轉(zhuǎn)中心,因此可以在任何位置旋轉(zhuǎn)。修改后的變換矩陣為:
其中
可以通過cv2.getRotationMatrix2D來獲得旋轉(zhuǎn)矩陣,不需要手算。
對于透視變換,需要在輸入圖像上有4個(gè)點(diǎn),在輸出圖像上需要相應(yīng)的點(diǎn)。在這四個(gè)點(diǎn)中,其中三個(gè)不應(yīng)共線。然后可以通過函數(shù)cv.getPerspectiveTransform找到變換矩陣。
def AffineTrans():
img = cv2.imread('./images/test.jpg')
# 圖像變換尺寸
# fx軸和fy軸的縮放比例,interpolation插值方式,cv2.INTER_LINEAR #默認(rèn)效果
# cv2.INTER_NEAREST,cv2.INTER_AREA,cv2.INTER_CUBIC
img_resize = cv2.resize(img,None,fx=0.5,fy=0.5,interpolation=cv2.INTER_AREA)
# 圖像翻轉(zhuǎn),flipCode=0:上下翻轉(zhuǎn),大于0左右翻轉(zhuǎn),小于0:上下加左右
img_flip = cv2.flip(img,flipCode=1)
# 圖像旋轉(zhuǎn)
img_rotate = cv2.rotate(img,rotateCode=cv2.ROTATE_90_CLOCKWISE)
h,w,c = img.shape
# 圖像平移
# cv2.warpAffine(src,變換矩陣,輸出圖像大小,)
# 變換矩陣,向右移動100個(gè)像素,向下移動100個(gè)像素
M = np.float32([[1,0,100],
[0,1,100]])
img_warp = cv2.warpAffine(img,M,dsize=(200,500))
# 獲得變換矩陣,(中心點(diǎn),按逆時(shí)針旋轉(zhuǎn),scal:縮放比例)
M_r = cv2.getRotationMatrix2D((300,250),15,1)
img_rotate_ = cv2.warpAffine(img,M_r,(w,h))
# 通過三個(gè)點(diǎn)確定旋轉(zhuǎn)
# 需要原圖三個(gè)點(diǎn)和變換后的三個(gè)點(diǎn)對應(yīng)的坐標(biāo)
src = np.float32([[100,200],[300,200],[200,400]])
dst = np.float32([[200,300],[300,400],[300,500]])
M1 = cv2.getAffineTransform(src,dst)
img_r3 = cv2.warpAffine(img,M1,(w,h))
# 透視變換
src_p = np.float32([[100,100],[700,100],[100,300],[700,300]])
dst_p = np.float32([[0,0],[720,0],[0,320],[720,320]])
M_p = cv2.getPerspectiveTransform(src_p,dst_p)
img_perspect = cv2.warpPerspective(img,M_p,(w,h))
cv2.imshow("imshow", img_r3)
cv2.waitKey(0)
cv2.destroyAllWindows()
7、卷積操作:均值濾波、方盒濾波、高斯濾波、中值濾波、雙邊濾波
圖像濾波,就是在盡量保留圖像細(xì)節(jié)特征的條件下對目標(biāo)圖像的噪聲進(jìn)行抑制,可以把濾波器想象成一個(gè)包含加權(quán)系數(shù)的窗口,當(dāng)使用這個(gè)濾波器平滑處理圖像時(shí),就把這個(gè)窗口放到圖像之上,透過這個(gè)窗口來看我們得到的圖像。
而對濾波處理的要求有兩個(gè),一是不能損壞圖像的輪廓及邊緣等重要信息;二是使圖像清晰視覺效果好。
用神經(jīng)網(wǎng)絡(luò)中的話來說就是用不同的卷積核對圖像進(jìn)行卷積操作,以產(chǎn)生不同的效果。不同的是神經(jīng)網(wǎng)絡(luò)中的卷積核通過訓(xùn)練得到,而圖像濾波是用已知的卷積核對圖像進(jìn)行卷積。
方盒濾波、均值濾波和中值濾波都可以起到平滑圖像,濾去噪聲的功能。 均值濾波采用線性的方法,平均整個(gè)窗口范圍內(nèi)的像素值 ,均值濾波本身存在著固有的缺陷,即它不能很好地保護(hù)圖像細(xì)節(jié),在圖像去噪的同時(shí)也破壞了圖像的細(xì)節(jié)部分,從而使圖像變得模糊,不能很好地去除噪聲點(diǎn)。
均值濾波對高斯噪聲表現(xiàn)較好,對椒鹽噪聲表現(xiàn)較差 。中值濾波采用非線性的方法,它在平滑脈沖噪聲方面非常有效,同時(shí)它可以保護(hù)圖像尖銳的邊緣,選擇適當(dāng)?shù)狞c(diǎn)來替代污染點(diǎn)的值,所以處理效果好,對椒鹽噪聲表現(xiàn)較好,對高斯噪聲表現(xiàn)較差。
假設(shè):一個(gè)5*5的卷積核,均值濾波則為:
中值濾波是選取圖像中窗口大小范圍內(nèi)的像素點(diǎn),將這些像素值排序,然后將位于中間位置的像素值作為當(dāng)前像素點(diǎn)的像素值,讓周圍的像素值接近真實(shí)值,從而消除孤立的噪聲點(diǎn)。假設(shè)3x3的串口大小,像素排序后為[1,2,5,5,6,7,8,9,11],取其中的中間值6作為卷積后的結(jié)果值。
注1:方盒濾波是OpenCV中提供的一個(gè)API
方盒濾波卷積核:
參數(shù)a的作用:normalize = true, a = 1/W * H 此時(shí)為均值濾波
normalize = false, a=1 此時(shí)不進(jìn)行均值化,輸出的結(jié)果為25個(gè)元素之和。當(dāng)normalize = true時(shí),方盒濾波 ==平均濾波,一般情況下都使用均值濾波,所以在使用時(shí)直接調(diào)用均值濾波API
注2:高斯噪聲和椒鹽噪聲
高斯噪聲,顧名思義是指服從高斯分布(正態(tài)分布)的一類噪聲,通常是因?yàn)椴涣颊彰骱透邷匾鸬?a href="http://m.xsypw.cn/v/tag/117/" target="_blank">傳感器噪聲。
椒鹽噪聲,通常是由圖像傳感器,傳輸信道,解壓處理等產(chǎn)生的黑白相間的亮暗點(diǎn)噪聲(椒-黑,鹽-白)。
高斯濾波就是將為正態(tài)分布(“高斯分布”)的卷積核對圖像進(jìn)行卷積操作。
要產(chǎn)生一個(gè)高斯濾波模板,以模板的中心位置為坐標(biāo)原點(diǎn)進(jìn)行取樣。模板在各個(gè)位置的坐標(biāo),如下圖所示(x軸水平向右,y軸豎直向下),用數(shù)值代替上面(x, y),假定中心點(diǎn)的坐標(biāo)為(0, 0),那么距離它周圍的八個(gè)點(diǎn)的坐標(biāo)如下:
更遠(yuǎn)的點(diǎn),依次類推,為了計(jì)算權(quán)重矩陣,需要設(shè)定σ的值,假定σ=1.5,則模糊半徑為1的權(quán)重矩陣如下:
這九個(gè)點(diǎn)的權(quán)重綜合等于 0.4787147,如果只計(jì)算這 9 個(gè)點(diǎn)的加權(quán)平均,還必須讓他們的權(quán)重之和等于1,因此上面的九個(gè)值還要分別除以 0.4787147,得到最終的權(quán)重矩陣:
卷積后,中心點(diǎn)的值不一定最大,但是其比重是最大的,兩邊的值可能比較大,但是其比重較小。中心點(diǎn)的值與周圍的加權(quán)平均了所以圖像變模糊了。
雙邊濾波是 結(jié)合圖像的空間鄰近度和像素值相似度的一種折中處理,同時(shí)考慮空域信息和灰度相似性,可以保留邊緣,同時(shí)可以對邊緣內(nèi)的區(qū)域進(jìn)行平滑處理 。雙邊濾波器顧名思義比高斯濾波多了一個(gè)高斯方差sigma-d,它是基于空間分布的高斯濾波函數(shù),所以在邊緣附近,離的較遠(yuǎn)的像素不會太多影響到邊緣上的像素值,這樣就保證了邊緣附近像素值的保存。但是由于保存了過多的高頻信息,對于彩色圖像里的高頻噪聲,雙邊濾波器不能夠干凈的濾掉,只能夠?qū)τ诘皖l信息進(jìn)行較好的濾波。
公式中可以看到,因?yàn)檫吘壐浇幕叶戎挡畋容^大,所以如果遇到邊緣附近,灰度信息的權(quán)重比較大,所以中心點(diǎn)權(quán)重比較大,保留了邊緣信息。
def Convolution():
img = cv2.imread('./images/test.jpg')
# 卷積核測試
kernel_blur = np.ones([3,3],np.float32)/9
kernel1 = np.array([[-1,-1,-1],[-1,8,-1],[-1,-1,-1]])
kernel2 = np.array([[-2,1,0],[-1,1,1],[0,1,2]])
kernel3 = np.array([[0,-1,0],[-1,5,-1],[0,-1,0]])
new_img = cv2.filter2D(img,-1,kernel3)
# 方盒濾波、均值濾波
img_box = cv2.boxFilter(img,-1,(5,5),normalize=True)
img_blur = cv2.blur(img,(5,5))
# 高斯濾波 sigma越大越模糊標(biāo)準(zhǔn)差越大,ksize越大越模糊,適合雪花點(diǎn)
img_gauss = cv2.GaussianBlur(img,ksize=(3,3),sigmaX=5)
# 中值濾波,適合椒鹽噪聲
img_median = cv2.medianBlur(img,ksize=3)
# 雙邊濾波,灰度值兩邊進(jìn)行高斯模糊嗎,即保留邊緣信息進(jìn)行局部優(yōu)化
# sigmaColor:計(jì)算像素信息的sigma,sigmaSpace計(jì)算空間信息的sigma
img_bilateral = cv2.bilateralFilter(img,d=7,sigmaColor=10,sigmaSpace=20)
cv2.imshow("imshow", img_bilateral)
cv2.waitKey(0)
cv2.destroyAllWindows()
-
圖像處理
+關(guān)注
關(guān)注
27文章
1300瀏覽量
56896 -
開源
+關(guān)注
關(guān)注
3文章
3408瀏覽量
42714 -
計(jì)算機(jī)視覺
+關(guān)注
關(guān)注
8文章
1700瀏覽量
46133 -
OpenCV
+關(guān)注
關(guān)注
31文章
635瀏覽量
41562
發(fā)布評論請先 登錄
相關(guān)推薦
評論