I’ve recently been brought into an older codebase using OpenCV 3.2.0. Some of the newer features requested (and bug fixes desired) meant that we had to upgrade, so I’ve gone through the task of upgrading to 4.5.2.
Of course now some tests are failing and I can’t understand why…I’ve boiled down the issue to the following:
- When converting a 3-ch 8x1 Mat from BGR2GRAY (1-ch), OpenCV 3.2.0 gives me a different result to other version of OpenCV.
Here’s my test program:
int main()
{
auto test = [](int cols) {
// Create a 3-ch Mat 1xN filled with [1.0, 1.0, 1.0]
cv::Mat original = cv::Mat::zeros(1, cols, CV_32FC3) + cv::Scalar(1.0, 1.0, 1.0);
// Set the element at position (0, 0) to [0.75, 0.75, 0.75]
original.at<cv::Vec3f>(0, 0) = cv::Vec3f(0.75, 0.75, 0.75);
std::cout << "Size: " << original.size() << " | Type: 32FC3 | [0,0]: " << original.col(0).row(0) << std::endl;
// Create a placeholder 1-ch Mat of Nx1 and call `cvtColor` to convert from BGR (3-ch) to grayscale (1-ch)
const cv::Mat image_32FC1(1, cols, CV_32FC1);
cv::cvtColor(original, image_32FC1, cv::COLOR_BGR2GRAY, 1);
std::cout << "Size: " << image_32FC1.size() << " | Type: 32FC1 | [0,0]: " << image_32FC1.col(0).row(0) << std::endl;
};
test(8);
}
When run on OpenCV 3.2.0 I get the following result:
Size: [8 x 1] | Type: 32FC3 | [0,0]: [0.75, 0.75, 0.75]
Size: [8 x 1] | Type: 32FC1 | [0,0]: [0.75]
When run on any other version of OpenCV (including 3.x) I get the following result:
Size: [8 x 1] | Type: 32FC3 | [0,0]: [0.75, 0.75, 0.75]
Size: [8 x 1] | Type: 32FC1 | [0,0]: [0.75000006]
Notice in the second line the conversion from 3-ch to 1-ch has given us a different result (0.75000006). A lot of the tests in the system fail because they’re not expecting the additional precision.
So my questions are:
- Why am I getting a different result between 3.2.0 and other versions?
- Why do other versions have that additional precision?
- Oddly, if you change the dimensions of the Mat to 7x1 (
test(7);
), the issue disappears and the precision truncates to 0.75. It seems to only happen for Mats 1xN (where N >= 8)
Other information:
- The build of 3.2.0 was built by me, but I haven’t enabled any options like FAST-MATH
- I’ve tested against the following versions of OpenCV, and all but 3.2.0 give the second result
- OpenCV 3.2.0 was the previous version used by the project (self built)
- OpenCV 3.4.12 was the most recent OpenCV v3 I could easily find (conan)
- OpenCV 4.1.2 was an early version of OpenCV v4 I could easily find (conan)
- OpenCV 4.5.2 is the new version we’ve just upgraded to (self built)
- I’ve uploaded a copy of
getBuildInformation()
from my v3.2.0 build here: OpenCV 3.2.0 Build Info - Pastebin.com
Thanks for your help.