Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

It is a type mismatch.

The first matrix cv::Mat img which is loaded from the file, is a 2D matrix of type cv::Vec3b. This means each pixel is stored as a tuple of 3 bytes (which has the same memory layout as uchar[3], or cv::Vec<uchar, 3>.

The template <T> Mat.at<T>() function does not perform any conversion at all. That means you have to use the correct type for the template argument. If the type is not correct, the result is undefined.

The following line of code,
Vec3f intensity = img.at<vec3f>(i,j);
tells C++ to reinterpret the next 12 bytes (3 * sizeof(float)) as the bit patterns for IEEE-754 single-precision float, and return their values.

However, the matrix img is actually an array of bytes, so the interpretation will return meaningless values.

Due to the way C++ and OpenCV are designed, Mat.at<T> does not give a compiler warning or error when it is used in the wrong way.

The only allowed way to get the pixel value from Mat img is
cv::Vec3f intensity = img.at<cv::vec3b>(i,j);
Notice that at<T>(i, j) is called with the same type as Mat img, and then an implicit type conversion from cv::Vec3b to cv::Vec3f occurs.