###### tags: `OpenCV`,`影像處理`, # OpenCV 基礎篇-影像逐位元邏輯運算,濾波(filter) **OpenCV常見的位元運算方法** | 函數名稱 | 基本含義 | | -------- | -------- | |cv2.bitwise_and()|逐位元與(and) | |cv2.bitwise_or() |逐位元或(or) | |cv2.bitwise_xor()|逐位元互斥 | |cv2.bitwise_not()| 逐位元 | | 運算元1 | 運算元2 | 結果 | 規則 | | -------| -------- | --- | -------- | | 0 | 0 | 0 | and(0,0)=0 | | 0 | 1 | 0 | and(0,1)=0 | | 1 | 0 | 0 | and(1,0)=0 | | 1 | 1 | 1 | and(1,1)=1 | | 數值 | 十進位值 | 二進位值 | | ---- | -------- | -------- | | 數值1 | 198 | 1100 0110 | | 數值2 | 219 | 1101 1011 | | 逐位元與運算結果 | 194 | 1100 0010 | | 2的次方 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | | ---- | ---- | --- | --- | --- | --- | --- | --- | -- | | 數值 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 ==>198 = 128+64+4+2=2的7次方+2的6次方+2的3次方+2的2次方 **與特殊值0和255逐位元與運算** | 逐位元與運算 | 二進位值 |十進位值|二進位值 | 十進位值 | | -----------| -------- | --- | ---- | --------| | 數值N | 1101 1011 | 219 | 1101 1011 | 219 | |特殊值(0或255)| 0000 0000 | 0 | 1111 1111 | 255 | | 運算結果 | 0000 0000 | 0 | 1101 1011 | 219 | :bulb:**說明** 數值219與數值0逐位元運算與得==>0 數值219與數值255逐位元運算與結果保持不變 ```python= import cv2 import numpy as np a=np.random.randint(0,255,(5,5),dtype=np.uint8) b=np.zeros((5,5),dtype=np.uint8) #設定b為mask,mask為0或255的相同矩陣 b[0:3,0:3]=255 b[4,4]=255 c=cv2.bitwise_and(a,b) print("a=\n",a) print("b=\n",b) print("c=\n",c) ``` 結果如下: ![](https://i.imgur.com/i7a3hfK.jpg) **圖像平滑處理** * “平滑處理”(smoothing)也稱“模糊處理”(bluring) * 是一項簡單且使用頻率很高的圖像處理方法 * 用途有很多,最常見的是用來減少圖像上的噪點或者失真 * 美肌處理 **影像濾波(Image Filter)** * 就是在盡量保留圖像細節特徵的條件下對目標圖像的噪聲進行抑制 **均值濾波(Mean Filtering)** * 均值濾波(低通濾波)是典型的線性濾波算法 ![](https://i.imgur.com/gnjMyDF.jpg) 其中紅色區域的像素值均值濾波處理過程為: ( (197+25+106+156+159)+ (149+40+107+5+71)+ (163+198+226+223+156)+(222+37+68+193+157)+ (42+72+250+41+75) ) / 25 = 125.52 其中5*5的矩陣稱為核Kernel **cv2.blur** blur(src, ksize, dst=None, anchor=None, borderType=None) src 表待處理的輸入圖像 ksize 表示模糊內核大小。比如(1,15)表示生成的模糊內核是一個1*15的矩陣 dst 表示輸出與src相同大小和類型的圖像 anchor參數 borderType參數可忽略 核大小多以(寬度,高度)來表示,常用(3,3)或(5,5)表示 ![](https://i.imgur.com/ghZVe9z.jpg) ```python= import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('babynew.jpg') #我家女兒剛滿月時的照片 result = cv2.blur(img, (3, 3)) result1 = cv2.blur(img, (7, 7))#kernal越大實際越糊 #使用plt show圖 plt.rcParams['figure.figsize'] = [200, 100] plt.rcParams['font.size'] = 150 img2 = cv2.cvtColor(img , cv2.COLOR_BGR2RGB) plt.subplot(1,3,1) plt.imshow(img2) plt.xticks([]), plt.yticks([]) plt.title('origin image BGR') #Original r2 = cv2.cvtColor(result , cv2.COLOR_BGR2RGB) plt.subplot(1,3,2) plt.imshow(r2) plt.xticks([]), plt.yticks([]) plt.title('blur image k3') #kernal 3 r3 = cv2.cvtColor(result1 , cv2.COLOR_BGR2RGB) plt.subplot(1,3,3) plt.imshow(r3) plt.xticks([]), plt.yticks([]) plt.title('blur image k7') #kernal 7 ``` ![](https://i.imgur.com/F2sGXsL.jpg) **均值濾波(Mean Filtering)** 優點:效率高缺點 缺點:它不能很好地保護圖像細節 在圖像去噪的同時也破壞了圖像的細節,從而使圖像變得模糊,不能很好地去除噪聲點,特別是椒鹽噪聲(白噪聲)。 **椒鹽噪聲(Salt Pepper Noise)** 椒鹽噪聲也稱為脈衝雜訊,是圖像中經常見到的一種雜訊, 它是一種隨機出現的白點或者黑點 **高斯濾波(高斯模糊)(Gaussian Filtering)** 簡而言之,非均一,有權重比例之分 <可參考維基百科 https://zh.wikipedia.org/zh-tw/%E9%AB%98%E6%96%AF%E6%A8%A1%E7%B3%8A> 下面兩張圖可以簡單呈現權重比例的分配,及運算概念 ![](https://i.imgur.com/fJhuzsC.jpg) ![](https://i.imgur.com/WsmEkQK.jpg) ![](https://i.imgur.com/sM26Av2.jpg) ![](https://i.imgur.com/SzjF2Ou.jpg) **雙邊濾波(Bilateral filter)** 除了像素在空間中位置遠近程度的影響,還考慮了像素亮度相近程度的影響。 特色: 雙邊濾波在濾波的同時能保證一定的邊緣信息,比高斯濾波更好的邊緣保留特性。 opencv提供的雙線性濾波器的加權計算包含2個部分 一部分叫做space-related bilateral filter coefficients空域參數,空域參數採用高斯核來計算。 一個是color-related bilateral filter coefficients 顏色域參數,顏色域參數是基於像素與中心像素的亮度的差值的加權,相似的像素賦給較大的權值,不相似的賦給較小的權值,處理完的圖像更像一個水彩畫,可用於圖像分割,但是運行較慢。 ![](https://i.imgur.com/tCrHp2g.jpg) **cv2.bilateralFilter** bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None) src:待處理的輸入圖像 d參數:表示在過濾期間使用的每個像素鄰域的直徑 sigmaColor:參數表示色彩空間的標準方差,一般盡可能大。 較大的參數值意味著像素鄰域內較遠的顏色會混合在一起,而產生更大面積的半相等顏色。 如果sigmaColor沒輸入,則sigmaColor由sigmaSpace計算得出。 sigmaSpace參數表示坐標空間的標準方差(像素單位),一般盡可能小。 參數值越大意味著只要它們的顏色足夠接近,越遠的像素都會相互影響。 當d > 0時,它指定鄰域大小而不考慮sigmaSpace。d與sigmaSpace成正比。 ```python= import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('babynew.jpg') blurResult = cv2.blur(img, (5, 5)) #均值濾波 gaussianBlurResult = cv2.GaussianBlur(img, (5, 5), 0) #高斯濾波 bilateralResult = cv2.bilateralFilter(img, d=0, sigmaColor=50 ,sigmaSpace=10) #雙邊濾波 plt.rcParams['figure.figsize'] = [200, 100] plt.rcParams['font.size'] = 150 img2 = cv2.cvtColor(img , cv2.COLOR_BGR2RGB) plt.subplot(1,4,1) plt.imshow(img2) plt.xticks([]), plt.yticks([]) plt.title('origin image BGR') blurResult2 = cv2.cvtColor(blurResult , cv2.COLOR_BGR2RGB) plt.subplot(1,4,2) plt.imshow(blurResult2) plt.xticks([]), plt.yticks([]) plt.title('blur image ') gaussianBlurResult2 = cv2.cvtColor(gaussianBlurResult , cv2.COLOR_BGR2RGB) plt.subplot(1,4,3) plt.imshow(gaussianBlurResult2) plt.xticks([]), plt.yticks([]) plt.title('gaussianBlurResult image ') bilateralResult2 = cv2.cvtColor(bilateralResult , cv2.COLOR_BGR2RGB) plt.subplot(1,4,4) plt.imshow(bilateralResult2) plt.xticks([]), plt.yticks([]) plt.title('bilateralResult image ') ``` ![](https://i.imgur.com/wEcXR55.jpg) **這毫無疑問就是美肌開下去啦** 高斯濾波看起來比較協調 雙邊濾波看筆來邊緣就很明顯 **再拿之前惡搞小孩在美金圖片來試試** ```python= import cv2 import numpy as np import matplotlib.pyplot as plt newnew_photo=cv2.imread("result_dollar_new.bmp",0) blurResult = cv2.blur(newnew_photo, (5, 5)) gaussianBlurResult = cv2.GaussianBlur(newnew_photo, (5, 5), 0) bilateralResult = cv2.bilateralFilter(newnew_photo, d=0, sigmaColor=40, sigmaSpace=5) plt.rcParams['figure.figsize'] = [200, 100] plt.rcParams['font.size'] = 150 img = cv2.cvtColor(newnew_photo , cv2.COLOR_BGR2RGB) plt.subplot(1,4,1) plt.imshow(img) plt.xticks([]), plt.yticks([]) plt.title('origin image BGR') blurResult2 = cv2.cvtColor(blurResult , cv2.COLOR_BGR2RGB) plt.subplot(1,4,2) plt.imshow(blurResult2) plt.xticks([]), plt.yticks([]) plt.title('blur image ') gaussianBlurResult2 = cv2.cvtColor(gaussianBlurResult , cv2.COLOR_BGR2RGB) plt.subplot(1,4,3) plt.imshow(gaussianBlurResult2) plt.xticks([]), plt.yticks([]) plt.title('gaussianBlurResult image ') bilateralResult2 = cv2.cvtColor(bilateralResult , cv2.COLOR_BGR2RGB) plt.subplot(1,4,4) plt.imshow(bilateralResult2) plt.xticks([]), plt.yticks([]) plt.title('bilateralResult image ') ``` **灰階照片就沒彩色照片效果來的明顯** ![](https://i.imgur.com/TjV1wu2.jpg) **中值濾波函數(MedianBlur)** 中值濾波是一種非線性數字濾波器技術,經常用於去除圖像或者其他信號中的噪聲,是處理椒鹽噪聲的常用降噪算法。 在使用鄰域平均法去噪的同時,也會讓邊界變得模糊。而中值濾波是非線性的圖像處理方法,在去噪的同時可以兼顧到邊界信息的保留。 **cv2.medianBlur** medianBlur(src, ksize, dst=None) src參數表示待處理的輸入圖像。 size參數表示濾波窗口尺寸,必須是奇數並且大於1。 比如這裡是5,中值濾波器就會使用5×5的範圍來計算。 dst參數表示輸出與src相同大小和類型的圖像。 **有請Lena** ```python= #評比哪個濾波對於處理白噪聲最優秀 import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('lenaNoise.png')#有請白噪聲的lena blurResult = cv2.blur(img, (5, 5)) #均值濾波 gaussianBlurResult = cv2.GaussianBlur(img, (5, 5), 0)#高斯濾波 bilateralResult = cv2.bilateralFilter(img, d=0, sigmaColor=100, sigmaSpace=15)#雙邊濾波 medianResult = cv2.medianBlur(img, 5)#中值濾波 plt.rcParams['figure.figsize'] = [150, 200] plt.rcParams['font.size'] = 150 img2 = cv2.cvtColor(img , cv2.COLOR_BGR2RGB) plt.subplot(2,3,1) plt.imshow(img2) plt.xticks([]), plt.yticks([]) plt.title('origin image BGR') blurResult2 = cv2.cvtColor(blurResult , cv2.COLOR_BGR2RGB) plt.subplot(2,3,2) plt.imshow(blurResult2) plt.xticks([]), plt.yticks([]) plt.title('blur image ') gaussianBlurResult2 = cv2.cvtColor(gaussianBlurResult , cv2.COLOR_BGR2RGB) plt.subplot(2,3,3) plt.imshow(gaussianBlurResult2) plt.xticks([]), plt.yticks([]) plt.title('gaussianBlurResult image ') bilateralResult2 = cv2.cvtColor(bilateralResult , cv2.COLOR_BGR2RGB) plt.subplot(2,3,4) plt.imshow(bilateralResult2) plt.xticks([]), plt.yticks([]) plt.title('bilateralResult image ') medianResult2 = cv2.cvtColor(medianResult , cv2.COLOR_BGR2RGB) plt.subplot(2,3,5) plt.imshow(medianResult2) plt.xticks([]), plt.yticks([]) plt.title('medianResult image ') ``` 登愣~~~~~~ ![](https://i.imgur.com/FKq6QcL.jpg) ![](https://i.imgur.com/krEXKyG.jpg) 結論就是連我ㄚ罵都看的出來啊!! **中值濾波完勝,把lena處理的好美ㄚ**