索贝尔的梯度是什么意思?

时间:2014-04-08 09:51:57

标签: c++ opencv orientation gradient fingerprint

我为每个像素提供了Sobel算子的渐变。在我的情况下320x480。但是我如何将它们与方向联系起来呢?例如,我打算绘制指纹的方向图。那么,我该如何开始?

是通过将渐变划分为块(例如16x24)然后将渐变加在一起并将其跳过384来获得平均渐变?然后从那里使用平均梯度α从块的中心绘制一条线

如果我错了,请纠正我。谢谢。

以下是我用来查找渐变的代码

cv::Mat original_Mat=cv::imread("original.bmp", 1);

cv::Mat grad = cv::Mat::zeros(original_Mat.size(), CV_64F);

cv::Mat grad_x = cv::Mat::zeros(original_Mat.size(), CV_64F); 
cv::Mat grad_y = cv::Mat::zeros(original_Mat.size(), CV_64F);

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

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

short* pixelX = grad_x.ptr<short>(0);
short* pixelY = grad_y.ptr<short>(0);

int count = 0;
int min = 999999;
int max = -1;
int a=0,b=0;

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

    //printf("%d ",directionDEG);
    if(directionDEG < min){min = directionDEG;}
    if(directionDEG > max){max = directionDEG;}


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

}

2 个答案:

答案 0 :(得分:1)

有几种方法可视化方向图:

正如你所建议的那样,你可以逐块绘制它,但是你必须小心“平均”方向。例如,如果您将方向平均为0°和180°会发生什么?

更常见的是,方向简单地映射到灰度值。这将使每个像素的梯度可视化。例如:

int v = (int)(128+directionRAD / CV_PI * 128);

(免责声明:不是100%肯定128,其中一个可能实际上必须是127 ......

或者您可以将x和y渐变幅度分别映射到rg组件,理想情况是将渐变矢量标准化为长度1.假设normX是标准化的x方向上的渐变,其值介于-1和1之间:

int red = (int)((normX + 1)*127.5);
int green= (int)((normY + 1)*127.5);

答案 1 :(得分:0)

平均值取决于Sobel内核大小。

最好使用CV_32FC或CV_64FC代替CV_16S来获得结果。

此外,您可以使用cv :: phase方法加速代码。

请在此处查看我的回答:Sobel operator for gradient angle