У меня есть градиенты от оператора Собеля для каждого пикселя. В моем случае 320х480. Но как я могу связать их с ориентацией? Например, я планирую нарисовать карту ориентации для отпечатков пальцев. Итак, как мне начать?
Является ли это делением градиентов на блоки (например, 16×24), затем сложением градиентов и погружением их на 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
…
Или вы можете отобразить значения градиента х и у на r
а также g
компоненты, соответственно, в идеале после нормализации вектора градиента до длины 1. Предполагая, normX
быть нормализованным градиентом в направлении х со значениями от -1 до 1:
int red = (int)((normX + 1)*127.5);
int green= (int)((normY + 1)*127.5);
Усреднение зависит от размера ядра Собеля.
Для результатов будет лучше использовать CV_32FC или CV_64FC вместо CV_16S.
Также вы можете ускорить ваш код, используя метод cv :: phase.
см мой ответ здесь: Оператор Собеля для угла градиента