OpenCV - 浮点数据类型和强度范围在 0-255 内的 RGB 通道
Posted
技术标签:
【中文标题】OpenCV - 浮点数据类型和强度范围在 0-255 内的 RGB 通道【英文标题】:OpenCV - RGB Channels in Float Data Type and Intensity Range within 0-255 【发布时间】:2017-11-09 13:46:30 【问题描述】:如何实现 RGB 通道的值
浮点数据类型 强度范围在0-255之间我使用 CV_32FC4 作为矩阵类型,因为我将执行浮点数学运算来实现道尔顿化。我期待强度范围与 CV_8UC3 中 RGB 通道的强度范围相同,只是具有不同的数据类型。但是当我打印矩阵时,我注意到通道的强度不在 0-255 范围内。我意识到这是由于浮动matrix type 的范围。
Mat mFrame(height, width, CV_32FC4, (unsigned char *)pNV21FrameData);
for(int y = 0 ; y < height ; y++)
for(int x = 0 ; x < width ; x++)
Vec4f BGRA = mFrame.at<Vec4f>(y,x);
// Algorithm Implementation
mFrame.at<Vec4f>(y,x) = BGRA;
Mat mResult;
mFrame.convertTo(mResult, CV_8UC4, 1.0/255.0);
我需要像BGRA[0] = BGRA[0] * n;
这样操作像素,然后将其分配回矩阵。
【问题讨论】:
浮点矩阵mFrame
的范围是多少?
当我打印浮点矩阵时,我得到了像 2.3693558e-38 这样的值
你的pNV21FrameData
来自哪里,它已经在浮动了吗?或者是其他东西?您可以在 0-255.... 的浮点矩阵中获取数据,然后您不需要执行 1.0/255.0。仅当它在 0-1 的范围内时才需要
This 是原始代码。
我不确定使用 CV_8UC4 作为矩阵类型,然后转换数据类型(char 到 float),操作像素然后将其转换回来。
【参考方案1】:
通过您的 cmets 和其中的链接,我看到数据来自 BGRA。数据在uchar中。
我从这一行假设:
Mat mResult(height, width, CV_8UC4, (unsigned char *)poutPixels);
要解决这个问题,您可以创建矩阵,然后将其转换为浮点数。
Mat mFrame(height, width, CV_8UC4, (unsigned char *)pNV21FrameData);
Mat mFloatFrame;
mFrame.convertTo(mFloatFrame, CV_32FC4);
请注意,如果您需要另一个范围(如 0-1),这将保持当前范围 (0-255),您可以输入比例因子。
最后你可以转换回来,但要注意这个函数是saturate_cast
。如果您有特定的方式来管理溢出或小数,则必须在转换之前完成。
Mat mResult;
mFloatFrame.convertTo(mResult, CV_8UC4);
请注意,1.0/255.0
不存在,因为数据已经在 0-255 的范围内(至少在操作之前)。
最后一条评论,您的 cmets 中的链接使用 IplImage 和其他旧 C(已弃用)版本的 OpenCv。如果您使用 c++ 工作,请坚持使用 Mat 等 c++ 版本。这不在您在此处显示的代码中,而是在您链接的代码中。此评论更适合您避免以后的麻烦。
【讨论】:
当我将它转换回来时,saturate_cast 是如何工作的?该值是否会被估算为整数? 引用文档:“当参数为浮点值且目标类型为整数(8 位、16 位或 32 位)时,首先将浮点值四舍五入为最接近的整数,然后根据需要进行剪裁(当目标类型为 8 位或 16 位时)。”因此,如果需要,它将被舍入和剪裁(例如 -1.3123 = 0、256.54 = 255、125.9 = 126、18.0 = 18) 支持并标记为答案不足以表达我对接受我问题的人的感谢。虽然这必须被标记,但谢谢! @Moon 不用担心 :) 很高兴能为您提供帮助,如果您有更多问题可以问,这就是 Stack Overflow 的目的。以上是关于OpenCV - 浮点数据类型和强度范围在 0-255 内的 RGB 通道的主要内容,如果未能解决你的问题,请参考以下文章