OpenCV C++(十一)----頻率域?yàn)V波

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)造該矩陣的。

image.png

算法步驟:

  • 第一步: 輸入圖像矩陣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、理想低通濾波器

image.png

2、巴特沃斯低通濾波器

image.png

3、高斯低通濾波器

image.png
//創(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、理想高通濾波器

image.png

2、巴特沃斯高通濾波器

image.png

3、高斯高通濾波器

image.png

顯然, 高通濾波器和低通濾波器滿足這樣的關(guān)系:

hpFilter=1-lpFilter

即1減去通過(guò)createLPFilter得到的矩陣就可以得到高通濾波器 。

11.3、帶通和帶阻濾波器

帶通濾波是指只保留某一范圍區(qū)域的頻率帶。

11.3.1、帶通濾波器

1、理想帶通濾波器

image.png

2、巴特沃斯帶通濾波器

image.png

3、高斯帶通濾波器

image.png

11.3.2、帶阻濾波器

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

1、理想帶阻濾波器

image.png

2、巴特沃斯帶阻濾波器

image.png

3、高斯帶阻濾波器

image.png

顯然, 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ì)算。

image.png
image.png

同態(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波的步驟。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容