CV_8U和CV_32F之间有什么区别,在它们之间转换时我应该担心什么

What are the differences between CV_8U and CV_32F and what should I worry about when converting between them?

本文关键字:CV 之间 什么 转换 担心 我应该 区别 8U 32F      更新时间:2023-10-16

我有一些代码出了问题,我怀疑这是因为我在错误的数据类型上操作或在它们之间转换得很差。

它混合了CV_8U类型的cv::Mat对象(这是在用cv::imread读取jpg为灰度时创建的),CV_32FCV_32S

这些数据类型之间的区别是什么?在它们之间转换时我需要确保什么?

CV_8U是无符号8位/像素-即一个像素可以有0-255的值,这是大多数图像和视频格式的正常范围。

CV_32F是float -像素可以有0-1.0之间的任何值,这对于一些数据计算集很有用-但它必须转换成8位来保存或通过将每个像素乘以255来显示。

CV_32S是每个像素的带符号32位整数值-对于您在像素上进行整数数学再次有用,但再次需要转换为8位以保存或显示。这比较棘手,因为您需要决定如何将更大范围的可能值(+/- 20亿!)转换为0-255

基本上它们只是描述了各个组件是什么:

  • CV_8U: 1字节无符号整数(unsigned char).

  • CV_32S: 4字节有符号整数(int).

  • CV_32F: 4字节浮点数(float).

你必须记住的是,你不能只是把它们从一个转换到另一个(否则它可能不会做你想要的),特别是在不同大小的类型之间。

所以一定要确保使用真正的转换函数在它们之间进行转换,比如cv::convertcv::Mat::convertTo。不要只是尝试使用cv::Mat::at<float>cv::Mat_<float>来访问CV_8U类型的cv::Mat元素。

或者,如果您只想转换单个元素,而不想创建其他类型的新矩阵,则使用适当的函数(在示例中为cv::Mat::at<unsigned char>)访问元素并将结果转换为float

同样,组件的数量也存在差异,CV_8UC3类型的cv::MatCV_8UC1类型的图像不同,通常不应该由cv::Mat::at<unsigned char>访问,而应该由cv::Mat::at<cv::Vec3b>访问。

编辑:看到Martin的回答,你可能已经意识到这一切,他的解释更符合你一直在寻找的