OpenCV C++:使用 converTo 从 CV_32F 转换为 CV8U 会给出意想不到的值

OpenCV C++: Conversion from CV_32F to CV8U using converTo is giving unexpected values

本文关键字:CV8U 意想不到 转换 32F 使用 C++ converTo CV OpenCV      更新时间:2023-10-16
cv::Mat x(2,2,CV_32F);
x.at<float>(0,0)=0.7;
x.at<float>(0,1) = 0.8;
x.at<float>(1,0) = 0.72;
x.at<float>(1,1) = 0.68;
x.convertTo( x, CV_8U, 255, 0  );
std::cout << x.at<int>(0,0)  << std::endl;
std::cout << x.at<int>(0,1)  << std::endl;
std::cout << x.at<float>(1,0)  << std::endl; // I deliberately put <float> just to see what happens
std::cout << x.at<int>(1,1)  << std::endl;

输出为:

-138039790211.54154E-400

我期待这样的输出:

178204184173

我做错了什么?

如果您的垫子现在CV_8U,则必须访问它

x.at<uchar>(1,1)

下一个问题是正确打印出数字,cout,看到一个字符,将尝试打印一个字母,所以你必须把它转换为int:

std::cout << int(x.at<uchar>(0,0))  << std::endl;

然后,如果你的垫子是 2x2,你就无法访问 2,2 的元素,这是越界的,会导致 UB。

(在 C++ 中,我们从 0..n-1 开始索引,对吧?

所以,在这里,更正后的例子:

cv::Mat x(2,2,CV_32F);
x.at<float>(0,0)=0.7;
x.at<float>(1,0) = 0.8;
x.at<float>(0,1) = 0.72;
x.at<float>(1,1) = 0.68;
Mat y;
x.convertTo( y, CV_8U, 255, 0  );
cout << int(y.at<uchar>(0,0))  << std::endl;
cout << int(y.at<uchar>(1,0))  << std::endl;
cout << int(y.at<uchar>(0,1))  << std::endl;
cout << int(y.at<uchar>(1,1))  << std::endl;
cerr << x << endl;
cerr << y << endl;

178
204
184
173
[0.69999999, 0.72000003;
  0.80000001, 0.68000001]
[178, 184;
  204, 173]