【发布时间】:2012-01-12 16:59:32
【问题描述】:
我有一些代码正在运行,我怀疑这是因为我在操作错误类型的数据或在它们之间转换不佳。
它混合了 CV_8U 类型的 cv::Mat 对象(这是在使用 cv::imread 将 jpg 读取为灰度时创建的)、CV_32F 和 CV_32S。
这些数据类型之间有什么区别,在它们之间转换时我需要确定什么?
【问题讨论】:
我有一些代码正在运行,我怀疑这是因为我在操作错误类型的数据或在它们之间转换不佳。
它混合了 CV_8U 类型的 cv::Mat 对象(这是在使用 cv::imread 将 jpg 读取为灰度时创建的)、CV_32F 和 CV_32S。
这些数据类型之间有什么区别,在它们之间转换时我需要确定什么?
【问题讨论】:
CV_8U 是无符号的 8 位/像素 - 即一个像素的值可以是 0-255,这是大多数图像和视频格式的正常范围。
CV_32F 是浮点数 - 像素可以有 0-1.0 之间的任何值,这对于某些数据集计算很有用 - 但它必须转换为 8 位才能通过将每个像素乘以 255 来保存或显示。
CV_32S 是每个像素的有符号 32 位整数值 - 对像素进行整数数学运算同样有用,但再次需要转换为 8 位才能保存或显示。这比较棘手,因为您需要决定如何将更大范围的可能值(+/- 20 亿!)转换为 0-255
【讨论】:
CV_8U 和CV_8UC1 呢? CV_8U 不是也只有一个频道吗?
基本上,它们只是描述各个组件是什么:
CV_8U:1 字节无符号整数 (unsigned char)。
CV_32S:4 字节有符号整数 (int)。
CV_32F:4 字节浮点数 (float)。
您必须始终牢记的是,您不能只是将它们从一个转换到另一个(或者它可能不会做您想要的),尤其是在不同大小的类型之间。
因此,请始终确保使用真正的转换函数在它们之间进行转换,例如 cv::convert 或 cv::Mat::convertTo。不要只是尝试访问例如的元素。 cv::Mat 的 CV_8U 类型使用例如cv::Mat::at<float> 或 cv::Mat_<float>。
或者,如果您只想转换单个元素并且不想创建其他类型的新矩阵,请使用适当的函数(在示例中为 cv::Mat::at<unsigned char>)访问元素并将结果转换为 float .
同样,组件数量之间也存在差异,CV_8UC3 类型的 cv::Mat 与 CV_8UC1 类型的图像不同,并且应该(通常)不应该由 cv::Mat::at<unsigned char> 访问,而是由 @ 987654339@.
编辑:看到 Martin 的回答,您可能已经知道这一切,而他的解释正是您一直在寻找的。p>
【讨论】: