簡體   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