1. 程式人生 > >影象處理與影象識別筆記(二)影象變換

影象處理與影象識別筆記(二)影象變換

在本章節中,將介紹幾種常用的影象變換的方法,即利用數學公式將影象變換成另一種具有特定物理意義的影象,通過新的影象,我們可以觀察出原影象的某些特性,且可以對原影象進行濾波、壓縮等影象處理的操作,包括傅立葉變換、沃爾什變換等。

一、影象傅立葉變換基本原理與實現

傅立葉變換,是將時域訊號轉換為頻域訊號的變換方法,將時域訊號分解為頻率不同的正弦波訊號的方法,也就是說,任何一個訊號都是若干個正弦訊號所疊加。通過傅立葉變換,我們就可以得到訊號的頻率特性,是高頻成分多一點,還是低頻成分多一點,每個成分的幅值和相位是多少(頻譜圖和相點陣圖)。

影象是離散的二維訊號,可以通過二維傅立葉變換實現到頻域的轉換,轉換前的影象矩陣是由實陣列成的,轉換後的頻域矩陣是複數陣,變換公式如下所示, x

, y x,y 是影象陣的座標, u , v u,v 是頻域陣的座標,兩者沒有一一對應的關係,頻域陣中每一個點都是對影象陣中每一個畫素點進行了運算的。

我們關注的是通過傅立葉變換獲得影象的頻譜圖與相點陣圖,計算方法如下,

     

接下來我們用python程式碼來實現傅立葉變換,得到影象的頻譜圖與相點陣圖,實驗影象是Lena。

計算頻譜圖的程式碼如下,

import cv2
import numpy as np
import matplotlib.pyplot as plt
import pylab
img = cv2.imread('Lena.jpg',0)
f = np.fft.fft2(img)	#傅立葉變換
fshift = np.fft.fftshift(f) 	#將零頻點移到影象中央
s1 = np.log(np.abs(f))	 #先進行絕對值運算,然後取對數,限制數值範圍
s2= np.log(np.abs(fshift))
plt.subplot(121),plt.imshow(s1,'gray'),plt.title('original')
plt.subplot(122),plt.imshow(s2,'gray'),plt.title('center')
pylab.show()

得到結果,第一幅圖是原始傅立葉變換的結果,我們可以這樣理解這幅圖片,中心是高頻部分,四周是低頻部分,橫軸是原圖片橫向方向的傅立葉頻譜,縱向是原圖片縱向方向的傅立葉頻譜,為是頻譜具有一致性與可觀性,我們將零頻點,也就是四個角上的點,移到頻譜圖的中心得到第二幅圖,得到的頻譜圖中心是低頻部分,四周是高頻部分。圖中高亮的點代表成分多的某一頻率,灰暗的點代表成分少的某一頻率。如果一幅圖片高頻部分多是高亮,代表影象尖銳,變化劇烈,邊界分明且兩邊畫素差距極大;反之,圖片低頻部分高亮,高頻部分灰暗,代表圖片平緩、柔和。
觀察實驗影象的頻譜結果,中心點高亮,低頻部分佔據成分大,圖片總體表現的平緩。

接下來我們來實現相位的部分,實現程式碼如下,

import cv2
import numpy as np
import matplotlib.pyplot as plt
import pylab
img = cv2.imread('Lena.jpg',0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f) 
xw = np.angle(f);	#np.angle()函式求相位,arctan(虛部/實部)
xw_shift =np.angle(fshift)
plt.subplot(121),plt.imshow(xw,'gray'),plt.title('original')
plt.subplot(122),plt.imshow(xw_shift,'gray'),plt.title('center')
pylab.show()

得到結果,圖中的點代表頻譜圖中對應頻率的相位值。

二、影象傅立葉變換的應用

1、傅立葉變換在影象濾波中的應用
經過傅立葉變換後的影象中間部分為低頻部分,越靠外頻率越高,因此,我們可以選擇所需要的高頻或是低頻進行濾波。高頻反映影象中的細節,低頻反映影象中的整體概貌。
低通濾波程式碼如下,

import cv2
import numpy as np
import matplotlib.pyplot as plt
import pylab

def LPF(img,radius = 50): 	#定義低通濾波函式,radius:低通半徑,半徑越小,低通效果越明顯,圖片越模糊
	rows,cols = img.shape
	mrows = int(rows/2)
	mcols = int(cols/2)
	mask = np.zeros((rows,cols),np.uint8)	#建立掩碼
	mask[mrows-radius:mrows+radius,mcols-radius:mcols+radius] = 1
	return mask	
	
def main():
	img = cv2.imread('Lena.jpg',0)
	f = np.fft.fft2(img)
	fshift = np.fft.fftshift(f) 
	fshift = fshift*LPF(img) 	#低通濾波,即與掩碼相乘,過濾掉頻率高的部分
	#逆變換
	f_ishift = np.fft.ifftshift(fshift)
	img_back = np.fft.ifft2(f_ishift)
	img_back = np.abs(img_back)
	plt.imshow(img_back,'gray'),plt.title('radius=50')
	pylab.show()

if __name__=="__main__":
	main()

結果如下,

高通濾波程式碼如下,

import cv2
import numpy as np
import matplotlib.pyplot as plt
import pylab

def HPF(img,radius= 50): #高通濾波函式,radius:高通半徑,半徑越大,高通效果越明顯,圖片越尖銳
	rows,cols = img.shape
	mrows = int(rows/2)
	mcols = int(cols/2)
	mask = np.zeros((rows,cols),np.uint8)	#建立掩碼
	mask[:,:] = 1
	mask[mrows-radius:mrows+radius,mcols-radius:mcols+radius] = 0
	return mask	

def main():
	img = cv2.imread('Lena.jpg',0)
	f = np.fft.fft2(img)
	fshift = np.fft.fftshift(f) 
	fshift = fshift*HPF(img,1) 	#高通濾波,即與掩碼相乘,過濾掉頻率高的部分
	#逆變換
	f_ishift = np.fft.ifftshift(fshift)	
	img_back = np.fft.ifft2(f_ishift)
	img_back = np.abs(img_back)
	plt.imshow(img_back,'gray'),plt.title('radius=50')
	pylab.show()
	
if __name__=="__main__":
	main()

結果如下,

對比結果可以發現,低通濾波讓圖片變得更加模糊,過濾掉了圖片中邊緣的、尖銳的部分;高通濾波讓圖片變得更加尖銳,過濾掉了圖片中平緩的部分,留下邊緣的、尖銳的部分。

2、傅立葉變換在影象壓縮中的應用
原理很簡單,將高頻係數設定為0,壓縮效果如下,

     

未完待續