本文介绍了从索贝尔确定图像梯度方向?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用openCV的Sobel方法的结果确定图像渐变方向。

I am attempting to determine the image gradient direction using the results from openCV's Sobel method.

我明白这应该是一项非常简单的任务。我从这里复制了许多资源和答案的方法,但无论我做什么,结果方向总是在0到57度之间(我希望范围是0-360)。

I understand this should be a very simple task. I have copied the methods from a number of resources and answers from here but whatever I do the resultant directions are always between 0 - 57 degrees (I would expect the range to be from 0-360).

我相信所有深度都是正确的。我已经尝试使用16S数据以及8U数据来计算方向。

I believe all the depths are correct. I have tried calculating the direction using the 16S data as well as 8U data.

我只是看不出我出错的地方?任何人都可以发现我的错误吗?

I just can't see where I'm going wrong? Can anyone spot my mistake?

void getGradients(IplImage* original, cv::Mat* gradArray)
{
    cv::Mat original_Mat(original, true);

    // Convert it to gray
    cv::cvtColor( original_Mat, original_Mat, CV_RGB2GRAY );
    //cv::blur(original_Mat, original_Mat, cv::Size(7,7));

    /// Generate grad_x and grad_y
    cv::Mat grad_x = cv::Mat::zeros(original->height, original->width, CV_16S); 
    cv::Mat grad_y = cv::Mat::zeros(original->height, original->width, CV_16S);

    cv::Mat abs_grad_x = cv::Mat::zeros(original->height, original->width, CV_8U);
    cv::Mat abs_grad_y = cv::Mat::zeros(original->height, original->width, CV_8U);;

    /// Gradient X
    cv::Sobel(original_Mat, grad_x, CV_16S, 1, 0, 3);
    cv::convertScaleAbs( grad_x, abs_grad_x );

    /// Gradient Y
    cv::Sobel(original_Mat, grad_y, CV_16S, 0, 1, 3);
    cv::convertScaleAbs( grad_y, abs_grad_y );

    uchar* pixelX = abs_grad_x.data;
    uchar* pixelY = abs_grad_y.data;
    uchar* grad1 = gradArray[0].data;
    uchar* grad2 = gradArray[1].data;
    uchar* grad3 = gradArray[2].data;
    uchar* grad4 = gradArray[3].data;
    uchar* grad5 = gradArray[4].data;
    uchar* grad6 = gradArray[5].data;
    uchar* grad7 = gradArray[6].data;
    uchar* grad8 = gradArray[7].data;
    int count = 0;
    int min = 999999;
    int max = 0;

    for(int i = 0; i < grad_x.rows * grad_x.cols; i++) 
    {
            int directionRAD = atan2(pixelY[i], pixelX[i]);
            int directionDEG = directionRAD / PI * 180;

            if(directionDEG < min){min = directionDEG;}
            if(directionDEG > max){max = directionDEG;}

            if(directionDEG >= 0 && directionDEG <= 45)         { grad1[i] = 255; count++;}         
            if(directionDEG >= 45 && directionDEG <= 90)        { grad2[i] = 255; count++;}         
            if(directionDEG >= 90 && directionDEG <= 135)       { grad3[i] = 255; count++;}         
            if(directionDEG >= 135 && directionDEG <= 190)      { grad4[i] = 255; count++;}         
            if(directionDEG >= 190 && directionDEG <= 225)      { grad5[i] = 255; count++;}         
            if(directionDEG >= 225 && directionDEG <= 270)      { grad6[i] = 255; count++;}     
            if(directionDEG >= 270 && directionDEG <= 315)      { grad7[i] = 255; count++;}
            if(directionDEG >= 315 && directionDEG <= 360)      { grad8[i] = 255; count++;}

            if(directionDEG < 0 || directionDEG > 360)
            {
                cout<<"Weird gradient direction given in method: getGradients.";
            }               
    }
}


推荐答案

您正在使用整数运算,因此您对弧度和度数的计算会因截断而受到严重影响。

You're using integer arithmetic so your calculations for radians and degrees are suffering badly from truncation.

此外 atan2 -PI 到 + PI ,所以如果你想要一个在0..360范围内的度数值,你需要添加180度校正:

Also atan2 gives a result in the range -PI to +PI, so if you want a value in degrees in the range 0..360 you'll need to add a 180 degree correction:

        double directionRAD = atan2(pixelY[i], pixelX[i]);
        int directionDEG = (int)(180.0 + directionRAD / M_PI * 180.0);

注意使用 double 而不是 int for directionRAD

Note the use of double rather than int for directionRAD.

专业提示:学会使用一个调试器来逐步调试代码,随时检查变量 - 这样就可以比在StackOverflow上等待响应更容易修复这样的简单错误。

Pro tip: learn to use a debugger to step through you code, inspecting variables as you go - that will make fixing simple bugs like this a lot easier than waiting for responses on StackOverflow.

这篇关于从索贝尔确定图像梯度方向?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-12 03:04