0

I have the gradients from the Sobel operator for each pixel. In my case 320x480. But how can I relate them with the orientation? For an example, I'm planning to draw an orientation map for fingerprints. So, how do I start?

Is it by dividing the gradients into blocks (example 16x24) then adding the gradients together and diving it by 384 to get the average gradients? Then from there draw a line from the center of the block using the average gradient?

Correct me if i'm wrong. Thank you.

Here are the codes that i used to find gradients

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.";
    }

}
user3396218
  • 255
  • 2
  • 8
  • 20

2 Answers2

1

There are several ways to visualize an orientation map:

As you suggested, you could draw it block-wise, but then you would have to be careful about "averaging" the directions. For example, what happens if you average the directions 0° and 180°?

More commonly, the direction is simply mapped to a grey value. This would visualize the gradient per pixel. For example as:

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

(Disclaimer: not 100% sure about the 128, one of them might actually have to be a 127...

Or you could map the x and y gradient magnitudes to the rand gcomponents, respectively, ideally after normalizing the gradient vector to length 1. Assuming normX to be the normalized gradient in the x direction with values between -1 and 1:

int red = (int)((normX + 1)*127.5);
int green= (int)((normY + 1)*127.5);
anderas
  • 5,744
  • 30
  • 49
  • thanks but i'm still confused. What's the v for? i get the value range from 0-256. Grayscale? How may i use this info to draw the lines? – user3396218 Apr 08 '14 at 10:33
  • v is a grey value. If you generate a new image by calculating each pixel value like this, you will get an image where each pixel represents the direction of the gradient at that pixel. This is just an alternative to drawing lines and (in my experience) more commonly used. – anderas Apr 08 '14 at 10:41
  • @andreas, I used imwrite and got the image but it looks like this http://i.imgur.com/Cssqmux.png which is nothing like the original http://i.imgur.com/5PRemmw.png I'm trying to make it this way http://i.imgur.com/SwQfkHR.png. Is there any way? – user3396218 Apr 08 '14 at 10:59
  • This looks like a problem with your code. Have you had a look at http://answers.opencv.org/question/9493/fingerprint-orientation-map-through-gradient/ ? – anderas Apr 08 '14 at 11:41
  • do u have any idea what's wrong wif my code? Yeah I seen that before. From your link, can I now average the 5x5 block orientation values and then draw the lines for each block? Will that get the orientation map? – user3396218 Apr 08 '14 at 12:01
0

Averaging depends on Sobel kernel size.

It'll be better to use CV_32FC or CV_64FC instead of CV_16S for results.

Also you can speed up your code using cv::phase method.

see my answer here: Sobel operator for gradient angle

Community
  • 1
  • 1
Andrey Smorodov
  • 10,649
  • 2
  • 35
  • 42
  • thanks. The angles obtained from your method is the same with my method right? May u enlighten me on how I can proceed to plot the map from here? – user3396218 Apr 08 '14 at 12:05
  • I think the HOG visuzlizer should be the most suitable: (take a look here) http://www.juergenwiki.de/work/wiki/doku.php?id=public:hog_descriptor_computation_and_visualization – Andrey Smorodov Apr 08 '14 at 13:14
  • You can also plot not all but the maximal bin or average (N strongest) bins and plot the result for each block. – Andrey Smorodov Apr 08 '14 at 13:24