本專欄主要介紹若是經過OpenCv-Python進行圖像處理,經過原理理解OpenCv-Python的函數處理原型,在具體狀況中,針對不一樣的圖像進行不一樣等級的、不一樣方法的處理,以達到對圖像進行去噪、銳化等一系列的操做。同時,但願觀看本專欄的小夥伴能夠理解到OpenCv進行圖像處理的強大哦,若有轉載,請註明出處(原文連接和做者署名),感謝各位小夥伴啦!python
前文參考:
《OpenCv視覺之眼》Python圖像處理一 :Opencv-python的簡介及Python環境搭建
《OpenCv視覺之眼》Python圖像處理二 :Opencv圖像讀取、顯示、保存基本函數原型及使用
《OpenCv視覺之眼》Python圖像處理三 :Opencv圖像屬性、ROI區域獲取及通道處理
《OpenCv視覺之眼》Python圖像處理四 :Opencv圖像灰度處理的四種方法及原理
《OpenCv視覺之眼》Python圖像處理五 :Opencv圖像去噪處理之均值濾波、方框濾波、中值濾波和高斯濾波
《OpenCv視覺之眼》Python圖像處理六 :Opencv圖像傅里葉變換和傅里葉逆變換原理及實現
編程
上一章節,林君學長介紹了圖像的傅里葉變換和逆變換,圖傅里葉變換和逆變換並非對圖像處理的目的,只是圖像處理過程的中間步驟,而咱們須要經過圖像的傅里葉變換獲得圖像的頻域圖,而後對圖像的頻域進行操做,例如構造高通濾波和低通濾波對圖像頻域進行過濾,而後再經過傅里葉逆變換將頻域圖還原爲時域圖進行顯示,達到圖像去噪、圖像輪廓提取、圖像銳化的目的。dom
本次博客,林君學長主要介紹在傅里葉變換的基礎上,如何構造高通濾波和低通濾波來進行圖像簡單輪廓提取和圖像去噪,高通和低通濾波的主要難點理解就是傅里葉變換和逆變換,上次博客已經介紹過,而對於高通和低通濾波的構造仍是比較簡單的,一塊兒學習吧!
函數
[Python圖像處理七] :Opencv圖像處理之高通濾波和低通濾波原理及構造
1、高通濾波
- 高通濾波通常用來提取圖像輪廓
一、高通濾波簡介
高通濾波(high-pass filter) 是一種過濾方式,規則爲高頻信號能正常經過,而低於設定臨界值的低頻信號則被阻隔、減弱。可是阻隔、減弱的幅度則會依據不一樣的頻率以及不一樣的濾波程序(目的)而改變。它有的時候也被叫作低頻去除過濾(low-cut filter)學習
二、圖像高通濾波原理
1)、圖像高通濾波原理首先應該瞭解高通濾波應該除掉的是什麼濾波,高通濾波,意思就是讓高頻部分經過,留下低頻部分;而衍生到圖像上面來理解,一張圖片的像素通常來講,在輪廓的地方像素值高,而在其餘部分像素值低,例如一張圖像上面的人像,人像的輪廓之因此咱們可以看出來就是由於與周圍像素值相差過大,頻率高,周圍像素值低,頻率低,造成像素差,從而咱們肉眼能夠分辨;
2)、而對於傅里葉變換來講,它將一張圖像高頻部分顯示在外圍,而低頻部分顯示在中間;所以,高通濾波就是將傅里葉變換以後的頻譜圖的中間部分過濾;過濾方法就是將中間部分區域的低頻對應的像素值給設置爲0,設置爲黑色,以下圖所示:
而這個黑色區域就是須要咱們構造的區域,尺寸是經過咱們自定義的,接下來,瞭解如何構造高通濾波吧!
ui
注意:該出是將低頻處對應的像素值設置爲黑色,而不是將頻域圖的中間部分變黑,相反的,頻域圖而言,像素值越低,頻率越低,中間部分也就越亮spa
三、圖像高通濾波構造
1)、構造高通濾波函數.net
import cv2 as cv import numpy as np from matplotlib import pyplot as plt #高通濾波構造 def highPassFiltering(img,size):#傳遞參數爲傅里葉變換後的頻譜圖和濾波尺寸 h, w = img.shape[0:2]#獲取圖像屬性 h1,w1 = int(h/2), int(w/2)#找到傅里葉頻譜圖的中心點 img[h1-int(size/2):h1+int(size/2), w1-int(size/2):w1+int(size/2)] = 0#中心點加減濾波尺寸的一半,恰好造成一個定義尺寸的濾波大小,而後設置爲0 return img
2)、步驟一:讀取一張圖像,轉化爲灰度圖,而後經過傅里葉變換獲得頻譜圖,而後調用高通濾波函數進行過濾,最後進行傅里葉逆變換觀察結果設計
這裏傅里葉變換咱們直接用Numpy的傅里葉變換,用法比較簡單code
#Numpy庫的傅里葉變換 plt.rcParams['font.sans-serif'] = ['SimHei'] #顯示中文 #讀取圖像 img = cv.imread('my.jpg',0) #傅里葉變換 f = np.fft.fft2(img) #將左上角低頻部分移動到中間 fshift = np.fft.fftshift(f) #調用高通濾波函數 img1=highPassFiltering(fshift,80) #複數化整,方便觀察頻譜圖 res = np.log(np.abs(img1)) #傅里葉逆變換 ishift = np.fft.ifftshift(img1) iimg = np.fft.ifft2(ishift) iimg = np.abs(iimg) #展現結果 plt.subplot(131), plt.imshow(img,'gray'), plt.title('原圖像') plt.axis('off') plt.subplot(132), plt.imshow(res,'gray'), plt.title('高通濾波') plt.axis('off') plt.subplot(133), plt.imshow(iimg,'gray'), plt.title('高通濾波結果') plt.axis('off') plt.show()
咱們能夠看到,經過調節尺寸的大小,咱們能夠提取明顯度不一樣的圖像輪廓,對於高通濾波的尺寸大小,主要看實際操做中對圖像的要求而設置
注意:該出是將低頻處對應的像素值設置爲黑色,而不是將頻域圖的中間部分變黑,相反的,頻域圖而言,像素值越低,頻率越低,中間部分也就越亮
3)、以上咱們是對灰度圖像進行高通濾波處理,那麼不少小夥伴會疑惑,如何對彩色圖像進行高通濾波處理呢?步驟也是一樣如此,只不過,咱們須要用到的傅里葉變換爲彩色圖像的傅里葉變換而已,上次博客林君學長也已經講過哦,只不過,在現實的圖像處理中,傅里葉變換通常是針對灰度圖像而言,由於對弈灰度圖像,有較好的頻域,比較可觀的頻域圖像,通常的圖像圖像不論是提取輪廓、仍是閾值化都是轉化爲灰度圖像進行處理的哈,完整代碼以下:
#彩色圖像的高通濾波 import cv2 import numpy as np import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] #顯示中文 #自定義傅里葉變換功能函數 def dft(img): #獲取圖像屬性 H,W,channel=img.shape #定義頻域圖,從公式能夠看出爲求出結果爲複數,所以,須要定義爲複數矩陣 F = np.zeros((H, W,channel), dtype=np.complex) # 準備與原始圖像位置相對應的處理索引 x = np.tile(np.arange(W), (H, 1)) y = np.arange(H).repeat(W).reshape(H, -1) #經過公式遍歷 for c in range(channel): for u in range(H): for v in range(W): F[u, v, c] = np.sum(img[..., c] * np.exp(-2j * np.pi * (x * u / W + y * v / H))) / np.sqrt(H * W) return F #傅里葉反變換 def idft(G): H, W, channel = G.shape #定義空白時域圖像 out = np.zeros((H, W, channel), dtype=np.float32) # 準備與原始圖像位置相對應的處理索引 x = np.tile(np.arange(W), (H, 1)) y = np.arange(H).repeat(W).reshape(H, -1) #經過公式遍歷 for c in range(channel): for u in range(H): for v in range(W): out[u, v, c] = np.abs(np.sum(G[..., c] * np.exp(2j * np.pi * (x * u / W + y * v / H)))) / np.sqrt(W * H) # 剪裁 out = np.clip(out, 0, 255) out = out.astype(np.uint8) return out #高通濾波構造 def highPassFiltering(img,size):#傳遞參數爲傅里葉變換後的頻譜圖和濾波尺寸 h, w = img.shape[0:2]#獲取圖像屬性 h1,w1 = int(h/2), int(w/2)#找到傅里葉頻譜圖的中心點 img[h1-int(size/2):h1+int(size/2), w1-int(size/2):w1+int(size/2)] = 0#中心點加減濾波尺寸的一半,恰好造成一個定義尺寸的濾波大小,而後設置爲0 return img #讀取圖像 img=cv2.imread("my.jpg") #進行圖像裁剪,加快傅里葉運算速率。將原始尺寸縮放爲100*100的尺寸 img = cv2.resize(img, (100, 100), interpolation=cv2.INTER_CUBIC) #BGR轉換爲RGB顯示格式,方便經過matplotlib進行圖像顯示 img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #調用傅里葉變換函數 result =dft(img) #將傅里葉頻譜圖從左上角移動到中心位置 fshift = np.fft.fftshift(result) img1=highPassFiltering(fshift,30) #將複數轉爲浮點數進行傅里葉頻譜圖顯示 fimg = np.log(np.abs(img1))#複數轉爲整數,方便顯示傅里葉頻譜圖 #將傅里葉頻譜圖從中心還原到左上角位置 ishift = np.fft.ifftshift(img1) #調用傅里葉逆變換函數 result2=idft(ishift) #圖像顯示 plt.subplot(131), plt.imshow(img), plt.title('原圖像') plt.axis('off') plt.subplot(132), plt.imshow(fimg), plt.title('高通濾波') plt.axis('off') plt.subplot(133), plt.imshow(result2), plt.title('高通濾波結果') plt.axis('off') plt.show()
能夠看到,高通濾波以後的結果,周圍是存在BGR三通道的像素值的,這對咱們須要達到目的也就是輪廓提取是干擾的,所以,在大多數狀況下,高通濾波和低通濾波針對的對象都是灰度圖像,對灰度圖像提取輪廓!
1、低通濾波
- 低通濾波通常用做圖像去噪(模糊)
一、低通濾波簡介
低通濾波能夠簡單的認爲:設定一個頻率點,當信號頻率高於這個頻率時不能經過,在數字信號中,這個頻率點也就是截止頻率,當頻域高於這個截止頻率時,則所有賦值爲0。由於在這一處理過程當中,讓低頻信號所有經過,因此稱爲低通濾波。低經過濾的概念存在於各類不一樣的領域,諸如電子電路,數據平滑,聲學阻擋,圖像模糊等領域常常會用到。在數字圖像處理領域,從頻域看,低通濾波能夠對圖像進行平滑去噪處理。
二、低通濾波原理
1)、低通濾波顧名思義就是低頻能夠經過,過濾掉高頻部分,而對於圖像的噪聲,包括椒鹽噪聲和高斯噪聲,他們的頻率都是比較高的例如像素值爲255,那麼低通濾波就會將這些噪聲過濾,但低通濾波並無識別功能,圖像中有些區域的像素一樣爲255,同理,低通濾波也會將其徹底過濾,所以,經過這個原理,咱們就能夠簡單瞭解,低通濾波其實就是將頻域圖中心部分保留,將外圍部分過濾,衍生到圖像中就是將高頻區域對應的像素值設置爲0,黑色,低頻區域對應的像素值不改變
2)、那麼如何實現呢?就須要和原圖如出一轍大小的黑色圖像,將中間區域設置爲白色,而後與頻譜圖一 一對應相乘,這樣獲得的結果就是中間部分不改變而過濾掉邊上部分,以下圖所示:
經過該原理,就能夠構造圖像的低頻濾波了,一塊兒來看吧!
注意:該出是將高頻處對應的像素值設置爲黑色,而不是將頻域圖的周圍變黑,相反的,頻域圖而言,像素值越高,頻率越高,周圍部分也就越亮
三、圖像低通濾波構造
1)、構造圖像低頻濾波函數
#低通濾波構造 import cv2 as cv import numpy as np from matplotlib import pyplot as plt def lowPassFiltering(img,size):#傳遞參數爲傅里葉變換後的頻譜圖和濾波尺寸 h, w = img.shape[0:2]#獲取圖像屬性 h1,w1 = int(h/2), int(w/2)#找到傅里葉頻譜圖的中心點 img2 = np.zeros((h, w), np.uint8)#定義空白黑色圖像,和傅里葉變換傳遞的圖尺寸一致 img2[h1-int(size/2):h1+int(size/2), w1-int(size/2):w1+int(size/2)] = 1#中心點加減濾波尺寸的一半,恰好造成一個定義尺寸的濾波大小,而後設置爲1,保留低頻部分 img3=img2*img #將定義的低通濾波與傳入的傅里葉頻譜圖一一對應相乘,獲得低通濾波 return img3
2)、讀取圖像添加噪聲並灰度化,進行傅里葉變換後調用低通濾波函數,而後經過傅里葉逆變換還原觀察圖像變化
#Numpy庫的傅里葉變換 plt.rcParams['font.sans-serif'] = ['SimHei'] #顯示中文 #讀取圖像 img = cv.imread('my.jpg') h, w = img.shape[0:2]#獲取圖像屬性 #加噪聲 for i in range(3000): #添加3000個噪聲點 x = np.random.randint(0, h) y = np.random.randint(0, w) img[x,y] = 255 #圖像灰度化 img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #傅里葉變換 f = np.fft.fft2(img) #將左上角低頻部分移動到中間 fshift = np.fft.fftshift(f) #調用低通濾波函數 img1=lowPassFiltering(fshift,100) #複數化整,方便觀察頻譜圖 res = np.log(np.abs(img1)) #傅里葉逆變換 ishift = np.fft.ifftshift(img1) iimg = np.fft.ifft2(ishift) iimg = np.abs(iimg) #展現結果 plt.subplot(131), plt.imshow(img,'gray'), plt.title('原圖像') plt.axis('off') plt.subplot(132), plt.imshow(res,'gray'), plt.title('低通濾波') plt.axis('off') plt.subplot(133), plt.imshow(iimg,'gray'), plt.title('低通濾波結果') plt.axis('off') plt.show()
注意:該出是將高頻處對應的像素值設置爲黑色,而不是將頻域圖的周圍變黑,相反的,頻域圖而言,像素值越高,頻率越高,周圍部分也就越亮
上圖可能不是太明顯,這是因爲jupyter經過matplotlib顯示圖像不是太大,並且設置的1行3張,當咱們只對比原圖和低通濾波結果時,就會發現仍是很明顯的,以下所示:
經過上圖能夠知道,圖像的噪聲基本去掉,也就是說,低通濾波消除噪聲的強度取決於你構造低通濾波的尺寸大小,尺寸越大,消除越很差,圖像越清晰;尺寸越小,消除越好,圖像越模糊
3)、一樣的,彩色圖像低通濾波無心義,但這裏給一個顯示結果,不要陷入太深哦;值得注意的是,彩色圖像低通濾波的構造方法有點不同,由於彩色是3通道圖,所以,在構造低通濾波時,應該將濾波模板設置爲3通道img2 = np.zeros((h, w,3), np.uint8),彩色圖像低通濾波完整代碼以下所示:
#彩色圖像低通濾波 #彩色圖像的高通濾波 import cv2 import numpy as np import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] #顯示中文 #自定義傅里葉變換功能函數 def dft(img): #獲取圖像屬性 H,W,channel=img.shape #定義頻域圖,從公式能夠看出爲求出結果爲複數,所以,須要定義爲複數矩陣 F = np.zeros((H, W,channel), dtype=np.complex) # 準備與原始圖像位置相對應的處理索引 x = np.tile(np.arange(W), (H, 1)) y = np.arange(H).repeat(W).reshape(H, -1) #經過公式遍歷 for c in range(channel): for u in range(H): for v in range(W): F[u, v, c] = np.sum(img[..., c] * np.exp(-2j * np.pi * (x * u / W + y * v / H))) / np.sqrt(H * W) return F #傅里葉反變換 def idft(G): H, W, channel = G.shape #定義空白時域圖像 out = np.zeros((H, W, channel), dtype=np.float32) # 準備與原始圖像位置相對應的處理索引 x = np.tile(np.arange(W), (H, 1)) y = np.arange(H).repeat(W).reshape(H, -1) #經過公式遍歷 for c in range(channel): for u in range(H): for v in range(W): out[u, v, c] = np.abs(np.sum(G[..., c] * np.exp(2j * np.pi * (x * u / W + y * v / H)))) / np.sqrt(W * H) # 剪裁 out = np.clip(out, 0, 255) out = out.astype(np.uint8) return out #低通濾波構造 def lowPassFiltering(img,size):#傳遞參數爲傅里葉變換後的頻譜圖和濾波尺寸 h, w = img.shape[0:2]#獲取圖像屬性 h1,w1 = int(h/2), int(w/2)#找到傅里葉頻譜圖的中心點 img2 = np.zeros((h, w,3), np.uint8)#定義空白黑色圖像,和傅里葉變換傳遞的圖尺寸一致 img2[h1-int(size/2):h1+int(size/2), w1-int(size/2):w1+int(size/2)] = 1#中心點加減濾波尺寸的一半,恰好造成一個定義尺寸的濾波大小,而後設置爲1,保留低頻部分 img3=img2*img #將定義的低通濾波與傳入的傅里葉頻譜圖一一對應相乘,獲得低通濾波 return img3 #讀取圖像 img=cv2.imread("my.jpg") h, w = img.shape[0:2]#獲取圖像屬性 #加噪聲 for i in range(3000): #添加3000個噪聲點 x = np.random.randint(0, h) y = np.random.randint(0, w) img[x,y,:] = 255 #進行圖像裁剪,加快傅里葉運算速率。將原始尺寸縮放爲100*100的尺寸 img = cv2.resize(img, (100, 100), interpolation=cv2.INTER_CUBIC) #BGR轉換爲RGB顯示格式,方便經過matplotlib進行圖像顯示 img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #調用傅里葉變換函數 result =dft(img) #將傅里葉頻譜圖從左上角移動到中心位置 fshift = np.fft.fftshift(result) img1=lowPassFiltering(fshift,30) #將複數轉爲浮點數進行傅里葉頻譜圖顯示 fimg = np.log(np.abs(img1))#複數轉爲整數,方便顯示傅里葉頻譜圖 #將傅里葉頻譜圖從中心還原到左上角位置 ishift = np.fft.ifftshift(img1) #調用傅里葉逆變換函數 result2=idft(ishift) #圖像顯示 plt.subplot(131), plt.imshow(img), plt.title('原圖像') plt.axis('off') plt.subplot(132), plt.imshow(fimg), plt.title('低通濾波') plt.axis('off') plt.subplot(133), plt.imshow(result2), plt.title('低通濾波結果') plt.axis('off') plt.show()
上面能夠看出,彩色圖像的低通濾波處理去噪效果比較明顯啦,就是圖像模糊較快,多用於圖像平滑、去噪!
注意:在尺寸的設計中,不要超過圖像的原尺寸,不然沒有效果哦,以上代碼本身將原圖縮小成100x100尺寸的,只爲了加快代碼運行速度哦,你們記得對照修改!
以上就是本次博客的所有內容,遇到問題的小夥伴記得留言評論,學長看到會爲你們進行解答的,這個學長不太冷!
趁咱們都還年輕bai,多走幾步路,多欣賞下沿途du的風景,zhi不要急於抵達目的地而錯過了流年裏溫暖dao的人和物;趁咱們都還年輕,多說些浪漫的話語,多作些幼稚的事情,不要嫌人笑話錯過了生命中最美好的片斷和場合;趁咱們都還年輕,把距離縮短,把時間延長。趁咱們都還年輕,多作些咱們想要作的任何事
陳一月的又一天編程歲月^ _ ^