HSV 转换中的浮点错误
Floating point error in HSV conversion
>我有一个将 RGB 色彩空间中的矢量转换为 HSV 的功能 - 该例程通过所有测试并在绝大多数时间工作。但是,崩溃报告指示它偶尔会失败(0.0001% 或更少的调用)。但是,由于这个函数被调用得如此之多,这占软件总崩溃的很大一部分。
代码的相关部分如下:
glm::vec4 RGBtoHSV(glm::vec4 rgb)
{
vec4 hsv = vec4(0,0,0,rgb.w);
float r = rgb.x;
float g = rgb.y;
float b = rgb.z;
float M = std::max(std::max(r,g),b);
float m = std::min(std::min(r,g),b);
float c = M - m;
//calc hue
float hp = 0;
if (c == 0)
hp = 0;
else if (M == r)
hp = glm::mod(((g-b)/c), 6.0f);
else if (M == g)
hp = ((b-r)/c) + 2;
else if (M == b)
hp = ((r-g)/c) + 4;
else
EXPECT(false);
float h = hp * 60;
...
glm::vec4 是对 GLM 库的引用,但类型基本上是这样的:
struct vec4 {
union {
struct { float x, y, z, w; }
struct { float r, g, b, a; }
}
}
失败的行是 EXPECT(false); -- 这只是断言我们总是达到大写之一,问题是控制如何到达那里?
假设这些是 IEEE-754 浮点数,那么与 NaN
相比您可能会遇到问题。如果您使用的是不同的浮点表示形式,那么我的其余答案可能无关紧要。
这听起来可能有点奇怪,但与NaN
的任何比较都会返回 False。因此,即使你试图做NaN == Nan
你也会得到错误。MSDN 链接。
如果在引发断言的代码部分中测试NaN
,则这可能是问题所在。您可以使用<cmath>
请参阅 http://en.cppreference.com/w/cpp/numeric/math/isnan 中找到的isnan()
来执行此操作。
我快速整理了一些代码来演示,如果您的系统上发生同样的情况,请告诉我:
#include <iostream>
#include <cmath>
int main(){
float r = 0.0/0;
std::cout << "r = " << r << std::endl;
float g = 7.0;
float b = 0.0;
float M = std::max(std::max(r,g),b);
float m = std::min(std::min(r,g),b);
float c = M - m;
//calc hue
float hp = 0;
if (c == 0)
std::cout << "c == 0" << std::endl;
else if (M == r)
std::cout << "M == r" << std::endl;
else if (M == g)
std::cout << "M == g" << std::endl;
else if (M == b)
std::cout << "M == b" << std::endl;
else
std::cout << "oops" << std::endl;
if(std::isnan(M))
std::cout << "NaN encountered" << std::endl;
}
在我的机器上使用 gcc 编译时,这给出了以下输出:
r = -nan
oops
NaN encountered
因此,代码中的其他地方似乎有可能发生0.0/0
。
相关文章:
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- C++使用params创建线程函数会导致转换错误
- 在混合代码库中将C转换为C++时出现许多包含错误
- 为什么g++在未执行的代码处标记强制转换错误
- 错误:从"int"到枚举c++的转换无效
- 错误 C2679:二进制"<<":未找到采用类型 'std::string_view' 的右侧操作数的运算符(或者没有可接受的转换)
- 从标准::未来<void>到非标量标准::未来<bool>引发的错误转换
- 使用宏的错误转换
- 在 opencv 中使用 Color_YUV2BGR 从 YUV 到 BGR 的错误转换
- 无法通过此操作,因为类型的错误转换
- PyQt5:使用自定义信号时 int 对象的错误转换
- 从长途错误转换
- C 错误:转换为非量表类型
- C 错误:转换为执行字符集
- 使用SOCI从PostgreSQL数据库获取数据时发生错误转换
- 分段错误C++转换问题
- 在ARM上的Qt中从双精度到QString的错误转换
- C++浮点转换为Python浮点错误转换
- 错误:转换为非标量类型