OpenCV中的同态过滤

时间:2013-11-22 22:26:11

标签: c++ image opencv filter

我正在尝试使用高斯LPF编写用于同态滤波的代码,但结果我在最后对整个黑色图像进行了整理。代码的书面过滤器部分适用于其他应用程序!

#include "stdafx.h"
#include <opencv2/core/core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;

int main()
{
    // Variables ========================================================================================
    int D0_GHPF = 80; // Gaussian HPF cut-off deviation
    // ==================================================================================================
    // Getting the frequency and magnitude of image =====================================================
    cv::Mat image = cv::imread("test2.tif", CV_LOAD_IMAGE_GRAYSCALE);
    if( image.empty())
        return -1;

    image.convertTo(image, CV_32F);
    image += 1;
    log(image,image);
    cv::Mat padded1;                          
    int m1 = cv::getOptimalDFTSize( image.rows );
    int n1 = cv::getOptimalDFTSize( image.cols );
    cv::copyMakeBorder(image, padded1, 0, m1 - image.rows, 0, n1 - image.cols, cv::BORDER_CONSTANT, cv::Scalar::all(0));

    cv::Mat image_planes[] = {cv::Mat_<float>(padded1), cv::Mat::zeros(padded1.size(), CV_32F)};
    cv::Mat image_complex;
    cv::merge(image_planes, 2, image_complex);         

    cv::dft(image_complex, image_complex);
    cv::split(image_complex, image_planes);

    // starting with this part we have the real part of the image in planes[0] and the imaginary in planes[1]
    cv::Mat image_phase;
    cv::phase(image_planes[0], image_planes[1], image_phase);
    cv::Mat image_mag;
    cv::magnitude(image_planes[0], image_planes[1], image_mag);

    // Shifting the DFT
    image_mag = image_mag(cv::Rect(0, 0, image_mag.cols & -2, image_mag.rows & -2));
    int cx = image_mag.cols/2;
    int cy = image_mag.rows/2;


    cv::Mat q0(image_mag, cv::Rect(0, 0, cx, cy));
    cv::Mat q1(image_mag, cv::Rect(cx, 0, cx, cy));
    cv::Mat q2(image_mag, cv::Rect(0, cy, cx, cy));
    cv::Mat q3(image_mag, cv::Rect(cx, cy, cx, cy));

    cv::Mat tmp;
    q0.copyTo(tmp);
    q3.copyTo(q0);
    tmp.copyTo(q3);

    q1.copyTo(tmp);
    q2.copyTo(q1);
    tmp.copyTo(q2);

    // Creating GHPF ====================================================================================
    cv::Mat GHPF(image_mag.size(), CV_32F, 255);

    float tempVal = float((-1.0)/float(pow(float(D0_GHPF),2)));
    for (int i=0; i < GHPF.rows; i++)
        for (int j=0; j < GHPF.cols; j++)
        {
            float dummy2 = float(pow(float(i - cy), 2) + pow(float(j - cx), 2));
            dummy2 = (2.0 - 0.25) * (1.0 - float(exp(float(dummy2 * tempVal)))) + 0.25;
            GHPF.at<float>(i,j) = 255 * dummy2;
        }
    cv::normalize(GHPF, GHPF, 0, 1, CV_MINMAX);
    cv::imshow("test", GHPF);
    cv::waitKey(0);
    // Applying GHPF filter ==================================================================================
    cv::Mat GHPF_result(image_mag.size(), CV_32F);
    cv::multiply(image_mag, GHPF, GHPF_result);

    // reversing the shift ==============================================================================
    cv::Mat q0_GHPF(GHPF_result, cv::Rect(0, 0, cx, cy));
    cv::Mat q1_GHPF(GHPF_result, cv::Rect(cx, 0, cx, cy));
    cv::Mat q2_GHPF(GHPF_result, cv::Rect(0, cy, cx, cy));
    cv::Mat q3_GHPF(GHPF_result, cv::Rect(cx, cy, cx, cy));

    cv::Mat tmp_GHPF;
    q0_GHPF.copyTo(tmp_GHPF);
    q3_GHPF.copyTo(q0_GHPF);
    tmp_GHPF.copyTo(q3_GHPF);

    q1_GHPF.copyTo(tmp_GHPF);
    q2_GHPF.copyTo(q1_GHPF);
    tmp_GHPF.copyTo(q2_GHPF);

    // Reconstructing the image with new GHPF filter ====================================================
    cv::Mat GHPFresult_planes[2];
    cv::polarToCart(GHPF_result, image_phase,GHPFresult_planes[0], GHPFresult_planes[1]);

    cv::Mat GHPFresult_complex;
    cv::merge(GHPFresult_planes,2,GHPFresult_complex);

    //calculating the iDFT for GHPF
    cv::Mat GHPF_inverseTransform;
    cv::dft(GHPFresult_complex, GHPF_inverseTransform, cv::DFT_INVERSE|cv::DFT_REAL_OUTPUT);

    exp(GHPF_inverseTransform,GHPF_inverseTransform);
    cv::normalize(GHPF_inverseTransform, GHPF_inverseTransform, 0, 1, CV_MINMAX);
    cv::imshow("GHPF Reconstructed", GHPF_inverseTransform);
    cv::waitKey(0);
}

该理论基于冈萨雷斯第3版的数字图像处理章节

1 个答案:

答案 0 :(得分:1)

好吧,我也很难用同态过滤。 我发现你的代码在exp:#INF

时出现了问题
cv::normalize(GHPF_inverseTransform, GHPF_inverseTransform, 0, 1, CV_MINMAX);
cv::exp(GHPF_inverseTransform, GHPF_inverseTransform); 
cv::normalize(GHPF_inverseTransform, GHPF_inverseTransform, 0,255, CV_MINMAX);
像这样,会发生一些不同的事情。 然后

cv::normalize(GHPF_inverseTransform, GHPF_inverseTransform, 0, 0.000001, CV_MINMAX);
cv::exp(GHPF_inverseTransform, GHPF_inverseTransform); 
cv::normalize(GHPF_inverseTransform, GHPF_inverseTransform, 100,255, CV_MINMAX);

这次我可以清楚地看到图像(好吧,但它看起来像是来自我的世界的图像) 所以我复制了另一个GHPF,它运作得很好。

所以我猜你的GHPF还有问题。 (对不起我的英语不好:p)