【问题标题】:How to use Gabor filter with Sobel and DFT filter outputs如何将 Gabor 滤波器与 Sobel 和 DFT 滤波器输出一起使用
【发布时间】:2015-01-19 13:27:15
【问题描述】:

按照this article 图像增强的主要思想,我将在图像上使用 Gabor 过滤器来增强它。目标是获取输入图像的方向和频率,然后将它们用于 Gabor 滤波。 首先,我将图像转换为灰度,然后为了获得方向图像,我使用了 Sobel 滤波器,对于频率图像,我使用了 DFT 滤波器。我的代码类似于 OpenCV 文档示例。

对于索贝尔:

http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.html

并将这部分添加到上面链接中的代码中以获取方向图像:

cv::Mat calculateOrientations(cv::Mat gradientX, cv::Mat gradientY)
{
    // Create container element
    cv::Mat orientation = cv::Mat(gradientX.rows, gradientX.cols, CV_32F);

    // Calculate orientations of gradients --> in degrees
    // Loop over all matrix values and calculate the accompagnied orientation
    for (int i = 0; i < gradientX.rows; i++)
    {
        for (int j = 0; j < gradientX.cols; j++)
        {
            // Retrieve a single value
            float valueX = gradientX.at<float>(i, j);
            float valueY = gradientY.at<float>(i, j);
            // Calculate the corresponding single direction, done by applying the arctangens function
            float result = cv::fastAtan2(valueX, valueY);
            // Store in orientation matrix element
            orientation.at<float>(i, j) = result;
        }
    }   

    return orientation;
}

对于 DFT:

http://docs.opencv.org/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.html

然后,我存储这两个过滤器的输出,并将它们作为输入参数传递给我的 Gabor 过滤器。我的 Gabor 过滤器的输入图像是我的灰度图像的二进制掩码。对于这部分,我的代码如下:

cv::Mat filter(cv::Mat inputImg, cv::Mat orientationImg, cv::Mat frequency, double theta_x, double theta_y)
{
    cv::Mat gaborResult = cv::Mat::zeros(inputImg.rows, inputImg.cols, inputImg.type());

    for (int i = 0; i < inputImg.rows; i++)
    {
        for (int j = 0; j < inputImg.cols; j++)
        {
            float xTheta = i*cos(orientationImg.at<float>(i, j)) + j*sin(orientationImg.at<float>(i, j));
            float yTheta = -i*sin(orientationImg.at<float>(i, j)) + j*cos(orientationImg.at<float>(i, j));

            float num1 = (xTheta * xTheta) / (theta_x * theta_x);
            float num2 = (yTheta * yTheta) / (theta_y * theta_y);

            float res = exp((-1 / 2) * (num1 + num2)) * cos(2 * pi * frequency.at<float>(i, j) * xTheta);
            gaborResult.at<float>(i, j) = res;
        }
    } 

    cv::Mat result = mult(inputImg, gaborResult);
    return result;
}

cv::Mat mult(cv::Mat inputImage, cv::Mat gaborResult)
{

    cv::Mat enhancedImg = cv::Mat::zeros(inputImage.rows, inputImage.cols, inputImage.type());;
    float sum = 0.0;

    for (int i = 0; i < inputImage.rows; i++)
    {
        for (int j = 0; j < inputImage.cols; j++)
        {
            enhancedImg.at<float>(i, j) = gaborResult.at<float>(i, j) * inputImage.at<float>(i, j);
        }
    }

    return enhancedImg;
}

正如文章所暗示的,参数theta_x 和theta_y 是4.0。 orientationImg 和 frequency 分别来自 Sobel 和 DFT 运算。 我做了一个像素级的 Gabor 过滤,如上所示。但是,输出的图像很奇怪,甚至没有接近我的增强目标。

这是 Sobel 和 DFT 滤波器的原始输入图像:

这是 Gabor 过滤器的输入二进制掩码:

这是我的 Gabor 过滤器的最终输出:

显然我在这里没有正确使用 Gabor 过滤器。我在互联网上搜索了很多关于这个主题的内容,但没有一个能解决我的问题。他们中的大多数都强调获取一个 Gabor 内核并将其用于整个图像,这在我的情况下是不同的。有人可以更好地了解改进我的代码/找出我的错误吗?先感谢您。

【问题讨论】:

    标签: c++ image opencv image-processing filter


    【解决方案1】:

    看起来像非标准化的浮点输出。 尝试将其标准化为区间 [0,1]。

    cv::normalize(src,dst,0,1,cv::NORM_MINMAX);
    

    【讨论】:

    • 我已经尝试过这种方法,但它并没有解决我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 2011-07-04
    • 2017-06-20
    • 2019-12-02
    • 2014-07-14
    • 1970-01-01
    • 2023-03-19
    相关资源
    最近更新 更多