Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Computing gradient orientation in c++ using opencv functions

Tags:

opencv

Can anyone help me out with this?

I am trying to calculate gradient orientation using the Sobel operator in OpenCV for gradient in x and y direction. I am using the atan2 function for computing the tangent in radians, which I later convert to degrees, but all the angles I am getting are between 0 and 90 degrees.

My expectation is to get angles between 0 and 360 degrees. The image I am using is grayscale. The code segment is here below.

Mat PeripheralArea;
Mat grad_x, grad_y;  // this is the matrix for the gradients in x and y directions
int off_set_y = 0, off_set_x = 0;
int scale = 1, num_bins = 8, bin = 0;
int delta=-1 ;
int ddepth = CV_16S;

GaussianBlur(PeripheralArea, PeripheralArea, Size(3, 3), 0, 0, BORDER_DEFAULT);
Sobel(PeripheralArea, grad_y, ddepth, 0, 1,3,scale, delta, BORDER_DEFAULT);
Sobel(PeripheralArea, grad_x, ddepth, 1, 0,3, scale, delta, BORDER_DEFAULT);

for (int row_y1 = 0, row_y2 = 0; row_y1 < grad_y.rows / 5, row_y2 < grad_x.rows / 5; row_y1++, row_y2++) {
    for (int col_x1 = 0, col_x2 = 0; col_x1 < grad_y.cols / 5, col_x2 < grad_x.cols / 5; col_x1++, col_x2++) {
        gradient_direction_radians = (double) atan2((double) grad_y.at<uchar>(row_y1 + off_set_y, col_x1 + off_set_x), (double) grad_x.at<uchar>(row_y2 + off_set_y, col_x2 + off_set_x));
        gradient_direction_degrees = (int) (180 * gradient_direction_radians / 3.1415);
        gradient_direction_degrees = gradient_direction_degrees < 0
                                     ? gradient_direction_degrees+360
                                     : gradient_direction_degrees;

    }

}

Note the off_set_x and off_set_y variable are not part of the computation but to offset to different square blocks for which I eventually want to compute an histogram feature vector

like image 811
Lekan Lanihun Avatar asked Aug 09 '26 01:08

Lekan Lanihun


1 Answers

You have specified that the destination depth of Sobel() is CV_16S. Yet, when you access grad_x and grad_y, you use .at<uchar>(), implying that their elements are 8 bit unsigned quantities, when in fact they are 16 bit signed. You could use .at<short>() instead, but to me it looks like there a number of issues with your code, not the least of which is that there is an OpenCV function that does exactly what you want.

Use cv::phase(), and replace your for loops with

    cv::Mat gradient_angle_degrees;
    bool angleInDegrees = true;

    cv::phase(grad_x, grad_y, gradient_angle_degrees, angleInDegrees);
like image 167
Bull Avatar answered Aug 10 '26 19:08

Bull



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!