OpenCV C ++: отфильтрованное по DFT изображение с пониженной интенсивностью - PullRequest
0 голосов
/ 04 июля 2018

Я пытаюсь создать полосовой фильтр для удаления некоторых низкочастотных компонентов и высокочастотного шума из входного изображения:

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);
}
...