Hello,

I am trying to port the method gradient (Matlab) to C++ with OpenCV:

I tested this in matlab:

Input:

 A =
1     3
4     2

[dx dy] = gradient(A, 4, 4)


Output:

dx =
0.5000    0.5000
-0.5000   -0.5000
dy =
0.7500   -0.2500
0.7500   -0.2500


I followed this example :

And I implemented this code:

float A[2][2] = {{1.0,3.0},{4.0,2.0}};



But grad doesn't have the same result. The problem is in the gradient method and its second and third parameter ( gradient(A,4,4)) which specify the 'spacing'. Is it correct this code? How I can specify this spacing in this example?

Update

gradient(A,4,4). These 4s are used to specify the kernel size to calculate the derivative for each number.

It was returning matrices with values to 0. I tested a matrix 3x3 (because Sober works with a ksize=3) and now, I returns values !=0...

edit retag close merge delete

Sort by » oldest newest most voted

I implemented a custom function to not use the Sobel operation and emulate the gradient operation, it works:

pair<Mat,Mat> gradient(Mat & img, float spaceX, float spaceY) {

return retValue;
}

/// Internal method to get numerical gradient for x components.
/// @param[in] mat Specify input matrix.
/// @param[in] spacing Specify input space.
static Mat gradientX(Mat & mat, float spacing) {

/*  last row */
int maxCols = mat.cols;
int maxRows = mat.rows;

/* get gradients in each border */
/* first row */
Mat col = (-mat.col(0) + mat.col(1))/(float)spacing;

col = (-mat.col(maxCols-2) + mat.col(maxCols-1))/(float)spacing;

/* centered elements */
Mat centeredMat = mat(Rect(0,0,maxCols-2,maxRows));
Mat offsetMat = mat(Rect(2,0,maxCols-2,maxRows));
Mat resultCenteredMat = (-centeredMat + offsetMat)/(((float)spacing)*2.0);

}

/// Internal method to get numerical gradient for y components.
/// @param[in] mat Specify input matrix.
/// @param[in] spacing Specify input space.
static Mat gradientY(Mat & mat, float spacing) {

/*  last row */
const int maxCols = mat.cols;
const int maxRows = mat.rows;

/* get gradients in each border */
/* first row */
Mat row = (-mat.row(0) + mat.row(1))/(float)spacing;

row = (-mat.row(maxRows-2) + mat.row(maxRows-1))/(float)spacing;

/* centered elements */
Mat centeredMat = mat(Rect(0,0,maxCols,maxRows-2));
Mat offsetMat = mat(Rect(0,2,maxCols,maxRows-2));
Mat resultCenteredMat = (-centeredMat + offsetMat)/(((float)spacing)*2.0);

}

more

Hey Carlos, I'm using your code but I want to compare the results with the ones I obtained using MATLAB. In my main function, I have:

int i, k;
Mat img;
img.convertTo(img, CV_64F); //Convert image to double precision (in MATLAB we have to use im2double before calling the gradient function)
cout << gradX[i][k] << " ";
}
cout << endl;
}


But I get an error when I run the code (when I try to print the values). What am I doing wrong? I know this is an easy question but I just started to develop code in c++ a few days ago. Thanks for your help.

more

Official site

GitHub

Wiki

Documentation