我为每个像素提供了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 :(得分:1)
有几种方法可视化方向图:
正如你所建议的那样,你可以逐块绘制它,但是你必须小心“平均”方向。例如,如果您将方向平均为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);
答案 1 :(得分:0)
平均值取决于Sobel内核大小。
最好使用CV_32FC或CV_64FC代替CV_16S来获得结果。
此外,您可以使用cv :: phase方法加速代码。
请在此处查看我的回答:Sobel operator for gradient angle