簡單影象處理——傅立葉變換
阿新 • • 發佈:2019-01-04
學過訊號處理的都應該知道傅立葉變換
把時域上的訊號處理為頻域上的訊號疊加
對於在空間域上的數字影象,我們也能通過傅立葉變換轉換為頻域類的訊號
在實現某些影象處理的時候,頻域類的處理比空間域更簡單
好啦,我們來看看二維離散訊號的傅立葉變換
數字影象的二維離散傅立葉變換所得的結果的頻域成分如圖所示,左上角是直流成分,變換結果四個角周圍對應於低頻成分,中央部分對應於高頻部分。
為了便於觀察,我們常常使直流成分出現在視窗的中央,可採取換位方法,變換後中心為低頻,向外是高頻
我們來看看具體例項
import cvdef FFT(image,flag = 0):
w = image.width
h
iTmp = cv.CreateImage((w,h),cv.IPL_DEPTH_32F,1)
cv.Convert(image,iTmp)
iMat = cv.CreateMat(h,w,cv.CV_32FC2)
mFFT = cv.CreateMat(h,w,cv.CV_32FC2)
for i in range(h):
for j in range(w):
if flag == 0:
num =-1if (i+j)%2==1else1else:
num =1
iMat[i,j]
cv.DFT(iMat,mFFT,cv.CV_DXT_FORWARD)
return mFFT
def FImage(mat):
w = mat.cols
h = mat.rows
size = (w,h)
iAdd = cv.CreateImage(size,cv.IPL_DEPTH_8U,1)
for i in range(h):
for j in range(w):
iAdd[i,j] = mat[i,j][1]/h + mat[i,j][0]/h
return iAdd
image = cv.LoadImage('
mAfterFFT = FFT(image)
mBeginFFT = FFT(image,1)
iAfter = FImage(mAfterFFT)
iBegin = FImage(mBeginFFT)
cv.ShowImage('image',image)
cv.ShowImage('iAfter',iAfter)
cv.ShowImage('iBegin',iBegin)
cv.WaitKey(0) 這裡我們直接用了OpenCV的DFT演算法來做傅立葉變換
我們來看看效果吧
中間是沒有換位前,後面是換位後
在函式FFT中第二個引數是控制換位的
預設是換位的
按照此式計算,得到的傅立葉變換就是換位後的
現在我們來看看得到的頻域圖到底有什麼用吧
在分析影象訊號的頻率特性時,對於一幅影象,直流分量表示預想的平均灰度,低頻分量代表了大面積背景區域和緩慢變化部分,高頻部分代表了它的邊緣,細節,跳躍部分以及顆粒噪聲
在前面我們實現了影象在空域的模糊和銳化
其實在頻域,我們也能方便的實現影象的銳化和模糊
我們擷取頻率的低頻分量,對其作傅立葉反變換,得到的就是模糊後的影象
我們擷取頻率的高頻分量,對其作傅立葉反變換,得到的就是銳化後的影象
我們來編寫程式實現
import cvdef FFT(image,flag = 0):
w = image.width
h = image.height
iTmp = cv.CreateImage((w,h),cv.IPL_DEPTH_32F,1)
cv.Convert(image,iTmp)
iMat = cv.CreateMat(h,w,cv.CV_32FC2)
mFFT = cv.CreateMat(h,w,cv.CV_32FC2)
for i in range(h):
for j in range(w):
if flag == 0:
num =-1if (i+j)%2==1else1else:
num =1
iMat[i,j] = (iTmp[i,j]*num,0)
cv.DFT(iMat,mFFT,cv.CV_DXT_FORWARD)
return mFFT
def IFFT(mat):
mIFFt = cv.CreateMat(mat.rows,mat.cols,cv.CV_32FC2)
cv.DFT(mat,mIFFt,cv.CV_DXT_INVERSE)
return mIFFt
def Restore(mat):
w = mat.cols
h = mat.rows
size = (w,h)
iRestore = cv.CreateImage(size,cv.IPL_DEPTH_8U,1)
for i in range(h):
for j in range(w):
num =-1if (i+j)%2==1else1
iRestore[i,j] = mat[i,j][0]*num/(w*h)
return iRestore
def FImage(mat):
w = mat.cols
h = mat.rows
size = (w,h)
# iReal = cv.CreateImage(size,cv.IPL_DEPTH_8U,1)# iIma = cv.CreateImage(size,cv.IPL_DEPTH_8U,1) iAdd = cv.CreateImage(size,cv.IPL_DEPTH_8U,1)
for i in range(h):
for j in range(w):
# iReal[i,j] = mat[i,j][0]/h# iIma[i,j] = mat[i,j][1]/h iAdd[i,j] = mat[i,j][1]/h + mat[i,j][0]/h
return iAdd
def Filter(mat,flag = 0,num =10):
mFilter = cv.CreateMat(mat.rows,mat.cols,cv.CV_32FC2)
for i in range(mat.rows):
for j in range(mat.cols):
if flag == 0:
mFilter[i,j] = (0,0)
else:
mFilter[i,j] = mat[i,j]
for i in range(mat.rows/2-num,mat.rows/2+num):
for j in range(mat.cols/2-num,mat.cols/2+num):
if flag == 0:
mFilter[i,j] = mat[i,j]
else:
mFilter[i,j] = (0,0)
return mFilter
image = cv.LoadImage('lena.jpg',0)
mFFT = FFT(image)
mIFFt = IFFT(mFFT)
iAfter = FImage(mFFT)
mLP = Filter(mFFT)
mIFFt1=IFFT(mLP)
iLP = FImage(mLP)
iRestore = Restore(mIFFt1)
mHP = Filter(mFFT,1)
mIFFt2 = IFFT(mHP)
iHP = FImage(mHP)
iRestore2 = Restore(mIFFt2)
cv.ShowImage('image',image)
cv.ShowImage('iAfter',iAfter)
cv.ShowImage('iLP',iLP)
cv.ShowImage('iHP',iHP)
cv.ShowImage('iRestore',iRestore)
cv.ShowImage('iRestore2',iRestore2)
cv.WaitKey(0) 執行效果如下
我們用一個矩形框,把頻域最中心的低頻部分過濾出來,反變換得到影象模糊後的樣子
把頻域最中心的高頻部分過濾出來,反變換得到影象銳化後的樣子
我們來看看一些規則影象的頻域影象
那個方形和菱形是隨手畫的,不是很標準,所以有很多幹擾
左邊是原圖
中間的普通的頻率變換
右邊的是對其進行對數擴充套件後的結果。在前面的灰度變換中,我們已經講過了灰度變換
參考資料: