The difference of " *mat.ptr<float>(i,j)" and "*mat.ptr(i,j)"?

58 views Asked by At

I'm attempting to modify values in an Opencv::Mat using the code below:

void gaussian_high_pass_kernel(cv::Mat& gaussianBlur, float sigma) 
{ 
    float d0 = sigma; 
    for (int i = 0; i < scr.rows; i++) 
    {   
        for (int j = 0; j < scr.cols; j++) 
        {       
            float d = pow(float(i - scr.rows / 2), 2) + pow(float(j - scr.cols / 2), 2);                                
            *gaussianBlur.ptr(i, j) = 1 - expf(-d / (2 * d0 * d0));     
        } 
    }  
}

There appears to be a bug in the line *gaussianBlur.ptr(i, j) = 1 - expf(-d / (2 * d0 * d0));. It didn't work as I expected, failing to assign the new value to gaussianBlur[i,j]. Instead, all values in the cv::Mat gaussianBlur end up as -4.31596e+08.

However, when I modify this line to *gaussianBlur.ptr<float>(i,j) = 1 - expf(-d / (2 * d0 * d0));, it works correctly. I'd like to understand the difference between these two approaches.

Could someone explain why directly accessing the elements using *gaussianBlur.ptr(i, j) doesn't yield the expected result, while explicitly specifying the data type with *gaussianBlur.ptr<float>(i,j) resolves the issue? Any insights or explanations would be greatly appreciated. Thank you!

1

There are 1 answers

2
DrBobs On

The difference between *gaussianBlur.ptr(i, j) and *gaussianBlur.ptr(i, j) lies in the data type interpretation.

When you use *gaussianBlur.ptr(i, j), the pointer is treated as a generic pointer to the data, and the type information is not explicitly specified. The compiler needs to infer the type based on the type of the matrix (gaussianBlur), and it may not always deduce the correct type, leading to unexpected results.

On the other hand, when you use *gaussianBlur.ptr(i, j), you are explicitly telling the compiler to interpret the data at the specified location as a float. This ensures that the correct type is used for interpretation, preventing any ambiguity in type conversion.

In your case, if the matrix gaussianBlur is of type CV_32F (32-bit floating-point), explicitly using *gaussianBlur.ptr(i, j) ensures that the correct type is used, and the assignment works as expected.

In summary, explicit type specification with *gaussianBlur.ptr(i, j) is a good practice to avoid potential issues related to type inference, especially when working with matrices of different data types. It provides clarity to the compiler about how to interpret the data, leading to more predictable and error-free code.