11.1概述和原理
低頻指的是圖像的傅里葉變換“中心位置”附近的區(qū)域。 低頻信息表示圖像中灰度值緩慢變化的區(qū)域 。
高頻隨著到“中心位置”距離的增加而增加, 即傅里葉變換中心位置的外圍區(qū)域, 這里的“中心位置”指的是傅里葉變換所對(duì)應(yīng)的幅度譜最大值的位置。高頻信息則正好相反, 表示灰度值變化迅速的部分, 如邊緣。
頻率域?yàn)V波器在程序或者數(shù)學(xué)運(yùn)算中的呈現(xiàn)可以理解為一個(gè)矩陣。下面所涉及的常用的低通、 高通、 帶通、 帶阻 等濾波的關(guān)鍵步驟, 就是通過(guò)一定的準(zhǔn)則構(gòu)造該矩陣的。

算法步驟:
- 第一步: 輸入圖像矩陣I。
- 第二步: 圖像矩陣的每一個(gè)像素值乘以
(-1) r+c得到矩陣I′,I′ =I.*(-1) r+c, 其中r和c代表當(dāng)前像素值在矩陣中的位置索引。 - 第三步: 因?yàn)閳D像矩陣的寬和高均為7, 為了利用傅里葉變換的快速算法, 對(duì)I′補(bǔ)0, 使用命令
getOptimalDFTSize(7)得到一個(gè)不小于7且可以分解為2p ×3q ×5r的最小整數(shù), 計(jì)算結(jié)果為8。 所以在矩陣I′的右側(cè)和下側(cè)各補(bǔ)一行0, 記為f - 第四步: 利用傅里葉變換的快速算法得到復(fù)數(shù)矩陣F。
- 第五步: 構(gòu)建頻率域?yàn)V波器
Filter。 頻率域?yàn)V波器本質(zhì)上是一個(gè)和第四步得到的快速 傅里葉變換矩陣F 具有相同行數(shù)、 列數(shù)的復(fù)數(shù)矩陣, 一般情況下為實(shí)數(shù)矩陣 - 第六步: 將第四步得到的快速傅里葉變換矩陣F 和第五步得到的頻率域?yàn)V波器
Filter的對(duì)應(yīng)位置相乘(矩陣的點(diǎn)乘) 。 當(dāng)然,如果濾波器是一個(gè)實(shí)數(shù)矩陣,那么在代碼實(shí)現(xiàn)中,將傅里葉變換的實(shí)部和虛部分別與頻率域?yàn)V波器進(jìn)行點(diǎn)乘即可,即F filter =F.*Filter,因?yàn)檫@里構(gòu)造的濾波器是一個(gè)全是1的矩陣, 所以F filter =F。 - 第七步: 對(duì)第六步得到的點(diǎn)乘矩陣
F filter進(jìn)行傅里葉逆變換,得到復(fù)數(shù)矩陣F′。 - 第八步: 取復(fù)數(shù)矩陣F′的實(shí)部。
- 第九步: 與第二步類似, 將第八步得到的矩陣乘以
(-1) r+c。 - 第十步:進(jìn)行裁剪, 取該實(shí)部矩陣的左上角, 尺寸和原圖相同。 裁剪得到的結(jié)果, 即為頻率域?yàn)V波的結(jié)果。
11.2、低通濾波器和高通濾波器
11.2.1、低通濾波器
1、理想低通濾波器

2、巴特沃斯低通濾波器

3、高斯低通濾波器

//創(chuàng)建三種常見(jiàn)的低通濾波器
enum FILTER_TYPE {
ILP_FILTER = 0,
BLP_FILTER = 1,
GLP_FILTER = 2
};
Mat creatLPFilter(Size size, Point center, float radius, FILTER_TYPE type, int n)
{
Mat lpFilter = Mat::zeros(size, CV_32FC1);
int rows = size.height;
int cols = size.width;
if (radius <= 0)
{
return lpFilter;
}
//構(gòu)建理想低通濾波器
if (type == ILP_FILTER)
{
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
float norm2 = pow(abs(float(r - center.y)), 2) + pow(abs(float(c - center.x)), 2);
if (sqrt(norm2) < radius)
{
lpFilter.at<float>(r,c) = 1;
}
else
{
lpFilter.at<float>(r, c) = 0;
}
}
}
}
//構(gòu)建巴特沃斯低通濾波器
if (type == BLP_FILTER)
{
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
lpFilter.at<float>(r, c) = float(1.0 / (1.0 + pow(sqrt(pow(r - center.y, 2.0) + pow(c - center.x, 2.0)) / radius, 2.0*n)));
}
}
}
//構(gòu)建高斯低通濾波器
if (type == GLP_FILTER)
{
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
lpFilter.at<float>(r, c) = float(exp(-(pow(r - center.y, 2.0) + pow(c - center.x, 2.0)) / (2 * pow(radius, 2.0))));
}
}
}
return lpFilter;
}
Mat I;//輸入的圖像矩陣
Mat F;//圖像的快速傅里葉變換
Point maxLoc;//傅里葉譜的最大值的坐標(biāo)
int radius = 20;//截?cái)囝l率
const int Max_RADIUS = 100;//設(shè)置的最大的截?cái)囝l率
Mat lpFilter;//低通濾波器
int lpType = 0;//低通濾波器的類型
const int MAX_LPTYPE = 2;
Mat F_lpFilter;//低通傅里葉變換
Mat flpSpectrum;//低通傅里葉變換的傅里葉譜的灰度級(jí)
Mat result;//低通濾波后的效果
string lpFilterspectrum = "低通傅里葉譜";//顯示窗口的名稱
void callback_lpFilter(int, void*);
int main()
{
//step1:讀入圖像矩陣
Mat I = imread("Koala.jpg", CV_LOAD_IMAGE_GRAYSCALE);
if (!I.data)
{
return -1;
}
//數(shù)據(jù)類型轉(zhuǎn)換為浮點(diǎn)型
Mat fI;
I.convertTo(fI, CV_32FC1, 1.0, 0.0);
//step2:每一個(gè)數(shù)乘于(-1)^(r+c)
for (int r = 0; r < fI.rows; r++)
{
for (int c = 0; c < fI.cols; c++)
{
if ((r + c) % 2)
{
fI.at<float>(r, c) *= -1;
}
}
}
//step3:補(bǔ)零;step4:快速傅里葉變換
fft2Image(fI, F);
//傅里葉譜
Mat amplSpec;
amplitudeSpectrum(F, amplSpec);
//傅里葉譜的灰度級(jí)顯示
Mat spectrum = graySpectrum(amplSpec);
//找到傅里葉譜的最大值的坐標(biāo)
minMaxLoc(spectrum, NULL, NULL, NULL, &maxLoc);
//低通濾波
namedWindow(lpFilterspectrum, WINDOW_AUTOSIZE);
createTrackbar("低通類型", lpFilterspectrum, &lpType, MAX_LPTYPE, callback_lpFilter);
createTrackbar("半徑", lpFilterspectrum, &radius, Max_RADIUS, callback_lpFilter);
callback_lpFilter(0, 0);
waitKey(0);
return 0;
}
void callback_lpFilter(int, void*)
{
//step5:構(gòu)建低通濾波器
lpFilter = creatLPFilter(F.size(), maxLoc, radius, lpType, 2);
//step6:低通濾波器和圖像的快速傅里葉變換點(diǎn)乘
F_lpFilter.create(F.size(), F.type());
for (int r = 0; r < F_lpFilter.rows; r++)
{
for (int c = 0; c < F_lpFilter.cols; c++)
{
//分別取出當(dāng)前位置的快速傅里葉變換和理想低通濾波器的值
Vec2f F_rc = F.at<Vec2f>(r, c);
float lpFilter_rc = lpFilter.at<float>(r, c);
//低通濾波器和圖像的快速傅里葉變換的對(duì)應(yīng)位置相乘
F_lpFilter.at<Vec2f>(r, c) = F_rc * lpFilter_rc;
}
}
//低通傅里葉變換的傅里葉譜
amplitudeSpectrum(F_lpFilter, flpSpectrum);
//低通傅里葉譜的灰度級(jí)顯示
flpSpectrum = graySpectrum(flpSpectrum);
//step7、8:對(duì)低通濾波器變換執(zhí)行傅里葉逆變換,并只取實(shí)部
dft(F_lpFilter, result, DFT_SCALE + DFT_INVERSE + DFT_REAL_OUTPUT);
//step9:同乘以(-1)^(x+y)
for (int r = 0; r < result.rows; r++)
{
for (int c = 0; c < result.cols; c++)
{
if ((r + c) % 2)
{
result.at<float>(r, c) *= -1;
}
}
}
//注意將結(jié)果轉(zhuǎn)換為CV_8U類型
result.convertTo(result, CV_8UC1, 1.0, 0);
//step10:截取左上部分,其大小和輸入圖像的大小相同
result = result(Rect(0, 0, I.cols, I.rows)).clone();
}
11.2.2、高通濾波器
1、理想高通濾波器

2、巴特沃斯高通濾波器

3、高斯高通濾波器

顯然, 高通濾波器和低通濾波器滿足這樣的關(guān)系:
hpFilter=1-lpFilter
即1減去通過(guò)createLPFilter得到的矩陣就可以得到高通濾波器 。
11.3、帶通和帶阻濾波器
帶通濾波是指只保留某一范圍區(qū)域的頻率帶。
11.3.1、帶通濾波器
1、理想帶通濾波器

2、巴特沃斯帶通濾波器

3、高斯帶通濾波器

11.3.2、帶阻濾波器
與帶通濾波相反, 帶阻濾波是指撤銷或者消弱指定范圍區(qū)域的頻率帶。
1、理想帶阻濾波器

2、巴特沃斯帶阻濾波器

3、高斯帶阻濾波器

顯然, 1減去帶通濾波就可以得到相應(yīng)的帶阻濾波。
11.4、自定義濾波器
有一種通過(guò)交互式的方式, 構(gòu)建自定義濾波, 便于消除指定的頻率。 自定義濾波器通常用于消除結(jié)構(gòu)化噪聲或者目標(biāo)。
11.5、同態(tài)濾波
同態(tài)濾波是一種減少低頻增加高頻,從而減少光照變化并銳化邊緣或者細(xì)節(jié)的濾波方法。
對(duì)于一幅圖像f(x,y),可以表示為照射分量i(x,y)和反射分量r(x,y)的乘積。
其中0<i(x,y)<∞,0<r(x,y)<1。
i(x,y)描述景物的照明,變化緩慢,處于低頻成分。
r(x,y)描述景物的細(xì)節(jié),變化較快,處于高頻成分。
因?yàn)樵撔再|(zhì)是乘性的,所以不能直接使用傅里葉變換對(duì)i(x,y)和r(x,y)進(jìn)行控制,因此可以先對(duì)f(x,y)取對(duì)數(shù),分離i(x,y)和r(x,y)。令z(x,y) = ln f(x,y) = ln i(x,y) + ln r(x,y)。由于f(x,y)的取值范圍為[0, L-1],為了避免出現(xiàn)ln(0)的情況,故采用ln ( f(x,y) + 1 ) 來(lái)計(jì)算。


同態(tài)濾波與頻率域?yàn)V波的不同之處是, 它在最開(kāi)始對(duì)輸入的圖像矩陣進(jìn)行對(duì)數(shù)運(yùn) 算, 在最后一步進(jìn)行對(duì)數(shù)運(yùn)算的逆運(yùn)算, 即指數(shù)運(yùn)算, 其中間步驟就是頻率域?yàn)V波的步驟。