繁体   English   中英

RGB 到 HIS 为某些 RGB 值提供 NaN

[英]RGB to HIS giving NaN for certain RGB values

我有一个函数可以计算给定 rgb 值的色调。 对于某些值, acos返回 NaN,因为参数略大于 1。此代码遵循我在网上找到的大多数公式,但我不知道为什么会弹出 NaN。

例子是

40 28 28
40 28 28
40 28 28
49 25 25
46 34 34
40 28 28
42 24 24
42 24 24
40 22 22
40 22 22
#include <math.h>

double hue(unsigned char r, unsigned char g, unsigned char b) {
  double rn = (double) r / (r + g + b);
  double gn = (double) g / (r + g + b);
  double bn = (double) b / (r + g + b);

  if (rn == gn && gn == bn) {
    return 0;
  }

  double h = acos((rn - gn + rn - bn) / (2.0 * sqrt((rn - gn) * (rn - gn) + (rn - bn) * (gn - bn))));

  // issue with the argument of acos being just slightly bigger than 1. Approximate to 0
  if (isnan(h)) {
    h = 0;
  }

  if (b > g) {
    return (2 * M_PI - h) * (180.0 / M_PI);
  } else {
    return h * (180.0 / M_PI);
  }
}

我不明白为什么 NaN 会出现

答案就在您的问题中:

因为参数略大于 1


在这种情况下,正确的问题是:

我应该如何确保acos的参数不大于 1?

为此,您需要分析您的公式并查看问题出在哪里。 sqrt和除法有可能起作用。

最简单的技巧(可能对您的应用程序不利)是首先验证参数是否大于 1,如果是,则将其截断为 1。


请注意,您失去了计算rngnbn额外精度。 sqrt的参数最好计算为:

a = (r-g)*(r-g)+(r-b)*(g-b);
b = (r+g+b)*(r+g+b);
argument = a/b;

玩它,看看会发生什么。


另外,序列

// issue with the argument of acos being just slightly bigger than 1. Approximate to 0
if (isnan(h)) {
    h = 0;
}

应该在调用之前使用acos ,以及使用的(precalculaed)参数acos代替计算h

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM