本文用的是emgucv4.1,對影象進行離散傅利葉變換,之後使用高斯濾波,再還原濾波後的圖
1、對原圖進行離散變換,之後顯示頻率
//*************************===1、將輸入影象擴充套件到最佳的尺寸,邊界用0補充
int m = cvinvoke.getoptimaldftsize(glmain8uc1.rows);
int n = cvinvoke.getoptimaldftsize(glmain8uc1.cols);
mat padded = new mat();
cvinvoke.copymakeborder(glmain8uc1, padded, 0, m - glmain8uc1.rows, 0, n - glmain8uc1.cols, bordertype.constant);
padded.convertto(padded, depthtype.cv32f); //將padded轉換為cv32f型別,此為傅利葉變換的實部
//*************************===2、建立傅里立葉的實部和虛部
//建立元素值都為0的zeromat,此為傅利葉變換的虛部
mat zeromat = mat.zeros(padded.rows, padded.cols, depthtype.cv32f, 1);
vectorofmat matvector = new vectorofmat(); //建立mat型向量
matvector.push(padded); //將padded壓入matvector中
matvector.push(zeromat); //將zeromat壓入matvector中
//建立channel數為2的mat,用於儲存傅利葉變換的實部和虛部
mat complexi = new mat(padded.size, depthtype.cv32f, 2);
cvinvoke.merge(matvector, complexi); //將matvector中儲存的2個mat,merge到complexi中
//*************************====3、建立mat,用於儲存傅利葉變換的結果
mat fourier = new mat(complexi.size, depthtype.cv32f, 2);
//呼叫傅利葉變換函式dft,進行傅利葉變換
cvinvoke.dft(complexi, fourier, dxttype.forward, complexi.rows);
mat tempfourier = new mat(complexi.size, depthtype.cv32f, 2);
fourier.copyto(tempfourier);
//*************************====4、對結果進行變換顯示
//將複數轉換為幅值,即=>log(1+sqrt(re(dft(i)^2+im(dft(i)^2))
mat magnitudeimage = magnitude(fourier);
cvinvoke.log(magnitudeimage, magnitudeimage);
//若有奇數行或奇數列,則進行頻譜裁剪
magnitudeimage = new mat(magnitudeimage, new rectangle(0, 0, magnitudeimage.cols & -2, magnitudeimage.rows & -2));
//重新排列傅利葉影象中的象限,使得原點位於影象中心
switchquadrants(ref magnitudeimage);
cvinvoke.normalize(magnitudeimage, magnitudeimage, 0, 255, normtype.minmax, depthtype.cv8u);
cvinvoke.imshow("fourier forward", magnitudeimage);
2、對原圖進行離散變換後,使用高斯濾波,再還原影象
//*************************===1、將輸入影象擴充套件到最佳的尺寸,邊界用0補充
int m = cvinvoke.getoptimaldftsize(glmain8uc1.rows);
int n = cvinvoke.getoptimaldftsize(glmain8uc1.cols);
mat padded = new mat();
cvinvoke.copymakeborder(glmain8uc1, padded, 0, m - glmain8uc1.rows, 0, n - glmain8uc1.cols, bordertype.constant);
padded.convertto(padded, depthtype.cv32f); //將padded轉換為cv32f型別,此為傅利葉變換的實部
//*************************===2、建立傅里立葉的實部和虛部
//建立元素值都為0的zeromat,此為傅利葉變換的虛部
mat zeromat = mat.zeros(padded.rows, padded.cols, depthtype.cv32f, 1);
vectorofmat matvector = new vectorofmat(); //建立mat型向量
matvector.push(padded); //將padded壓入matvector中
matvector.push(zeromat); //將zeromat壓入matvector中
//建立channel數為2的mat,用於儲存傅利葉變換的實部和虛部
mat complexi = new mat(padded.size, depthtype.cv32f, 2);
cvinvoke.merge(matvector, complexi); //將matvector中儲存的2個mat,merge到complexi中
//*************************====3、建立mat,用於儲存傅利葉變換的結果
mat fourier = new mat(complexi.size, depthtype.cv32f, 2);
//呼叫傅利葉變換函式dft,進行傅利葉變換
cvinvoke.dft(complexi, fourier, dxttype.forward, complexi.rows);
mat tempfourier = new mat(complexi.size, depthtype.cv32f, 2);
fourier.copyto(tempfourier);
//******************************4、對應的濾波卷積處理
this.switchquadrants(ref tempfourier);
mat gaoshikernel = gmlib.gasmat(tempfourier.size, 55);
cvinvoke.mulspectrums(tempfourier, gaoshikernel, tempfourier, mulspectrumstype.default);
this.switchquadrants(ref tempfourier);
//******************************5、反傅利葉變換
mat fourierinv = new mat(fourier.size, depthtype.cv32f, 2);
//注意,反變換時,必須用這個引數 dxttype.invscale
cvinvoke.dft(tempfourier, fourierinv, dxttype.invscale, tempfourier.rows);
mat maininv32fc1 = magnitude(fourierinv);
mat maininv8uc1 = new mat(maininv32fc1.size, depthtype.cv8u, 1);
cvinvoke.convertscaleabs(maininv32fc1, maininv8uc1, 1.0, 1.0);
cvinvoke.imshow("maininv", maininv8uc1);
3、完整程式在鏈結 離散余弦變換
離散余弦變換 dct for discrete cosine transform 是與傅利葉變換相關的一種變換,它類似於 離散傅利葉變換 dft for discrete fourier transform 但是只使用實數。離散余弦變換相當於乙個長度大概是它兩倍的離散傅利葉變換,這個離散傅利葉變換是...
離散余弦變換
首先膜拜下wikipedia 我們已經知道dft將訊號變換為復指數訊號的線性組合,並且如果時域訊號是偶對稱的,那麼頻域將只有實部 復指數的余弦部分 所以,如果將有限長訊號延拓為偶對稱的,就可以將其變換為余弦訊號的線性組合。以下面的原始訊號作為例子 這個訊號的長度為4。若原始訊號長度為n,那麼延拓後的...
離散余弦變換 DCT
由上面的引用可見,位元速率壓縮基於變換編碼和熵值編碼兩種演算法。前者用於降低熵值,後者將資料變為可降低位元數的有效編碼方式。在mpeg標準中,變換編碼採用的是dct,變換過程本身雖然並不產生位元速率壓縮作用,但是變換後的頻率係數卻非常有利於位元速率壓縮。jpeg影象壓縮演算法 輸入影象被分成8 8或...