//將HSV顏色空間值轉換成RGB值,參考這里
cv::Scalar HSV2RGB(const float h, const float s, const float v) { const int h_i = static_cast<int>(h * 6); const float f = h * 6 - h_i; const float p = v * (1 - s); const float q = v * (1 - f*s); const float t = v * (1 - (1 - f) * s); float r, g, b; switch (h_i) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; case 5: r = v; g = p; b = q; break; default: r = 1; g = 1; b = 1; break; } return cv::Scalar(r * 255, g * 255, b * 255); }
//固定s和v值,改變h值,並通過黃金分割得到隨機均勻的h值,從而得到較理想的隨機顏色 vector<cv::Scalar> GetColors(const int n) { vector<cv::Scalar> colors; cv::RNG rng(12345); const float golden_ratio_conjugate = 0.618033988749895; const float s = 0.3; const float v = 0.99; for (int i = 0; i < n; ++i) { const float h = std::fmod(rng.uniform(0.f, 1.f) + golden_ratio_conjugate, 1.f);//始終返回(0,1)區間的小數,取余fmod(a,b)=a-n*b(n為最大整除得到的整數商)商的符號取決於a colors.push_back(HSV2RGB(h, s, v)); } return colors; }
RNG rng(12345)
隨機數生成器RNG,計算機的偽隨機數是由隨機種子根據一定的計算方法計算出來的數值,所以只要計算方法一定,隨機種子一定,那么產生的隨機數就是固定的。opencv 里RNG類構造函數初始化為固定值后,隨機種子也是固定的,所以在同一個平台上,編譯后每次運行它,顯示的隨機數是一樣的,上面的代碼運行后產生的隨機顏色都是一樣的,是不是頓時有種“隨機也非隨機”的感覺。也就是說如果我們在目標檢測上可以為相同的類標記為同一個顏色,而且不管運行多少次,都會保留初始化的隨機顏色序列。