1 | initial version |
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) {
Mat gradY = gradientY(img,spaceY);
Mat gradX = gradientX(img,spaceX);
pair<Mat,Mat> retValue(gradX,gradY);
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) {
Mat grad = Mat::zeros(mat.cols,mat.rows,CV_32F);
/* 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.copyTo(grad(Rect(0,0,1,maxRows)));
col = (-mat.col(maxCols-2) + mat.col(maxCols-1))/(float)spacing;
col.copyTo(grad(Rect(maxCols-1,0,1,maxRows)));
/* 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);
resultCenteredMat.copyTo(grad(Rect(1,0,maxCols-2, maxRows)));
return grad;
}
/// 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) {
Mat grad = Mat::zeros(mat.cols,mat.rows,CV_32F);
/* 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.copyTo(grad(Rect(0,0,maxCols,1)));
row = (-mat.row(maxRows-2) + mat.row(maxRows-1))/(float)spacing;
row.copyTo(grad(Rect(0,maxRows-1,maxCols,1)));
/* 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);
resultCenteredMat.copyTo(grad(Rect(0,1,maxCols, maxRows-2)));
return grad;
}