索贝尔的梯度是什么意思



我有来自 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.";
    }
}

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

正如您所建议的,您可以逐块绘制它,但是您必须小心"平均"方向。例如,如果平均方向 0° 和 180°,会发生什么情况?

更常见的是,方向只是映射到灰色值。这将可视化每个像素的渐变。例如:

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

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

或者,您可以将 x 和 y 梯度幅度分别映射到r分量和g分量,理想情况下是在将梯度向量归一化为长度 1 之后。假设 normX 是 x 方向上的归一化梯度,值介于 -1 和 1 之间:

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

平均取决于 Sobel 内核大小。

最好

使用CV_32FC或CV_64FC而不是CV_16S来获得结果。

您也可以使用 cv::p hase 方法加快代码速度。

在这里看到我的答案: 渐变角的 Sobel 运算符

相关内容

  • 没有找到相关文章

最新更新