我有来自 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 运算符