OpenCV C ++:DFT带通滤波后的图像显示强度降低

时间:2018-07-04 13:01:02

标签: c++ opencv image-processing filtering fft

我正在尝试设计一个带通滤波器,以去除输入图像中的一些低频成分和高频噪声:

input_image

我想消除图像左侧较大的暗点,逐行显示亮的信息很有用,应在过滤后保留。

这是经过过滤的图像:

filtered_image

滤镜似乎已消除了暗点,但问题是明亮像素的强度明显降低了,这不是我想要的,我想保持亮行与暗背景之间的对比度。

我在频域图像过滤方面经验不足。去除低频信号后,我不知道这个结果是否正常?该代码段已附加。

void fft_filtering(cv::Mat img_gray, cv::Mat img_alpha) {
    int M = GetOptimalDftSize(img_gray.rows);
    int N = GetOptimalDftSize(img_gray.cols);
    cv::Mat img_gray_padded;
    cv::Mat planes[2];
    cv::copyMakeBorder(img_gray, img_gray_padded, 0, M - img_gray.rows, 0,
            N - img_gray.cols, cv::BORDER_CONSTANT, cv::Scalar::all(0));
    planes[0] = cv::Mat_<float>(img_gray_padded);
    planes[1] = cv::Mat::zeros(img_gray_padded.size(), CV_32F);
    cv::Mat img_complex;
    cv::merge(planes, 2, img_complex);
    cv::dft(img_complex, img_complex);

    cv::Mat filter(img_complex.size(), CV_32F);
    int f3_inpixel, f2_inpixel, f1_inpixel;
    CreateGaussianFilter(filter, img_alpha, FilterType::kBandPass, f3_inpixel, f2_inpixel, f1_inpixel);

    // Apply filter
    shiftDFT(img_complex);
    cv::mulSpectrums(img_complex, filter, img_complex, 0);
    shiftDFT(img_complex);

    // Do inverse DFT on the filtered image
    cv::idft(img_complex, img_complex);
    // Split into planes and extract plane 0 as output image
    cv::split(img_complex, planes);
    cv::Mat img_out;
    cv::normalize(planes[0], img_out, 0, 1, CV_MINMAX);
    cv::Rect img_roi(0, 0, img_gray.cols, img_gray.rows);
    img_filtered = img_out(img_roi); 
}

void CreateGaussianFilter(cv::Mat& filter, cv::Mat img_alpha, FilterType filter_type,
        float cutoff_f_low_InPixels, float cutoff_f_high_InPixels, float cutoff_f_center_InPixels){
    cv::Mat gf(filter.size(), CV_32F);
    cv::Point centre(filter.cols / 2, filter.rows / 2);
    for(int u = 0; u < gf.rows; u++) {
        for(int v = 0; v < gf.cols; v++) {
            switch (filter_type) {
            case FilterType::kHighPass:
                gf.at<float>(u, v) = 1- GaussianCoeff(u - centre.y, v - centre.x, cutoff_f_low_InPixels);
                break;
            case FilterType::kLowPass:
                gf.at<float>(u, v) = GaussianCoeff(u - centre.y, v - centre.x, cutoff_f_high_InPixels);
                break;
            case FilterType::kBandPass:
                gf.at<float>(u, v) = GaussianCoeff(u - centre.y, v - centre.x, cutoff_f_high_InPixels) -
                GaussianCoeff(u - centre.y, v - centre.x, cutoff_f_low_InPixels);
                break;
            }
        }
    }
    // Keep the center pixel
    gf.at<float>(centre.y, centre.x) = 1.0;

    cv::Mat toMerge[] = {gf, gf};
    merge(toMerge, 2, filter);
}

0 个答案:

没有答案