近期在做一个在复杂背景下识别球颜色的项目。当接到这个任务时,下意识的采用了扫像素点+RGB值找规律设定阈值的方式。这种方法固然简单直白,但是存在以下问题:
1.由于需要尽可能减少背景的干扰,故采用这种方法往往需要写多个if条件进行归类,这也导致程序的复杂度上升
2.光照是单目识别的自然杀手,检测颜色也不例外,该方法受光照影响较大,在较强光照和较弱光照下,如果识别条件写的比较粗糙,容易产生误判
3.通用性不强,对于每一种颜色都需要单独设立判断条件
4.鲁棒性不强,判断条件较为机械
HSL
于此,想到了基于RGB的更为合理、通用性更强的HSL色彩空间进行颜色检测的办法。
- 其中,H(Hue) 代表色相,S(Saturation) 代表饱和度。Hue(色相)是指取值范围在0-360°的圆心角,每个角度可以代表一种颜色。
- 饱和度S为一比例值,范围从0到1,它表示成所选颜色的纯度和该颜色最大的纯度之间的比率。S=0时,只有灰度。
- HSL的L(lightness)分量,指的是色彩的明度,作用是控制色彩的明暗变化。它同样使用了0%至100%的取值范围。数值越小,色彩越暗,越接近于黑色;数值越大,色彩越亮,越接近于白色。
RGB转换为HSL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
/** * Converts an RGB color value to HSL. Conversion formula * adapted from http://en.wikipedia.org/wiki/HSL_color_space. * Assumes r, g, and b are contained in the set [0, 255] and * returns h, s, and l in the set [0, 1]. * * @param {number} r The red color value * @param {number} g The green color value * @param {number} b The blue color value * @return {Array} The HSL representation */ function rgbToHsl(r, g, b){ r /= 255, g /= 255, b /= 255; var max = Math.max(r, g, b), min = Math.min(r, g, b); var h, s, l = (max + min) / 2; if(max == min){ h = s = 0; // achromatic }else{ var d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch(max){ case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return [h, s, l]; } |
HSL转换为RGB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<span class="com">/** * Converts an HSL color value to RGB. Conversion formula * adapted from http://en.wikipedia.org/wiki/HSL_color_space. * Assumes h, s, and l are contained in the set [0, 1] and * returns r, g, and b in the set [0, 255]. * * @param {number} h The hue * @param {number} s The saturation * @param {number} l The lightness * @return {Array} The RGB representation */</span> <span class="kwd">function</span><span class="pln"> hslToRgb</span><span class="pun">(</span><span class="pln">h</span><span class="pun">,</span><span class="pln"> s</span><span class="pun">,</span><span class="pln"> l</span><span class="pun">){</span> <span class="kwd">var</span><span class="pln"> r</span><span class="pun">,</span><span class="pln"> g</span><span class="pun">,</span><span class="pln"> b</span><span class="pun">;</span> <span class="kwd">if</span><span class="pun">(</span><span class="pln">s </span><span class="pun">==</span> <span class="lit">0</span><span class="pun">){</span><span class="pln"> r </span><span class="pun">=</span><span class="pln"> g </span><span class="pun">=</span><span class="pln"> b </span><span class="pun">=</span><span class="pln"> l</span><span class="pun">;</span> <span class="com">// achromatic</span> <span class="pun">}</span><span class="kwd">else</span><span class="pun">{</span> <span class="kwd">var</span><span class="pln"> hue2rgb </span><span class="pun">=</span> <span class="kwd">function</span><span class="pln"> hue2rgb</span><span class="pun">(</span><span class="pln">p</span><span class="pun">,</span><span class="pln"> q</span><span class="pun">,</span><span class="pln"> t</span><span class="pun">){</span> <span class="kwd">if</span><span class="pun">(</span><span class="pln">t </span><span class="pun"><</span> <span class="lit">0</span><span class="pun">)</span><span class="pln"> t </span><span class="pun">+=</span> <span class="lit">1</span><span class="pun">;</span> <span class="kwd">if</span><span class="pun">(</span><span class="pln">t </span><span class="pun">></span> <span class="lit">1</span><span class="pun">)</span><span class="pln"> t </span><span class="pun">-=</span> <span class="lit">1</span><span class="pun">;</span> <span class="kwd">if</span><span class="pun">(</span><span class="pln">t </span><span class="pun"><</span> <span class="lit">1</span><span class="pun">/</span><span class="lit">6</span><span class="pun">)</span> <span class="kwd">return</span><span class="pln"> p </span><span class="pun">+</span> <span class="pun">(</span><span class="pln">q </span><span class="pun">-</span><span class="pln"> p</span><span class="pun">)</span> <span class="pun">*</span> <span class="lit">6</span> <span class="pun">*</span><span class="pln"> t</span><span class="pun">;</span> <span class="kwd">if</span><span class="pun">(</span><span class="pln">t </span><span class="pun"><</span> <span class="lit">1</span><span class="pun">/</span><span class="lit">2</span><span class="pun">)</span> <span class="kwd">return</span><span class="pln"> q</span><span class="pun">;</span> <span class="kwd">if</span><span class="pun">(</span><span class="pln">t </span><span class="pun"><</span> <span class="lit">2</span><span class="pun">/</span><span class="lit">3</span><span class="pun">)</span> <span class="kwd">return</span><span class="pln"> p </span><span class="pun">+</span> <span class="pun">(</span><span class="pln">q </span><span class="pun">-</span><span class="pln"> p</span><span class="pun">)</span> <span class="pun">*</span> <span class="pun">(</span><span class="lit">2</span><span class="pun">/</span><span class="lit">3</span> <span class="pun">-</span><span class="pln"> t</span><span class="pun">)</span> <span class="pun">*</span> <span class="lit">6</span><span class="pun">;</span> <span class="kwd">return</span><span class="pln"> p</span><span class="pun">;</span> <span class="pun">}</span> <span class="kwd">var</span><span class="pln"> q </span><span class="pun">=</span><span class="pln"> l </span><span class="pun"><</span> <span class="lit">0.5</span> <span class="pun">?</span><span class="pln"> l </span><span class="pun">*</span> <span class="pun">(</span><span class="lit">1</span> <span class="pun">+</span><span class="pln"> s</span><span class="pun">)</span> <span class="pun">:</span><span class="pln"> l </span><span class="pun">+</span><span class="pln"> s </span><span class="pun">-</span><span class="pln"> l </span><span class="pun">*</span><span class="pln"> s</span><span class="pun">;</span> <span class="kwd">var</span><span class="pln"> p </span><span class="pun">=</span> <span class="lit">2</span> <span class="pun">*</span><span class="pln"> l </span><span class="pun">-</span><span class="pln"> q</span><span class="pun">;</span><span class="pln"> r </span><span class="pun">=</span><span class="pln"> hue2rgb</span><span class="pun">(</span><span class="pln">p</span><span class="pun">,</span><span class="pln"> q</span><span class="pun">,</span><span class="pln"> h </span><span class="pun">+</span> <span class="lit">1</span><span class="pun">/</span><span class="lit">3</span><span class="pun">);</span><span class="pln"> g </span><span class="pun">=</span><span class="pln"> hue2rgb</span><span class="pun">(</span><span class="pln">p</span><span class="pun">,</span><span class="pln"> q</span><span class="pun">,</span><span class="pln"> h</span><span class="pun">);</span><span class="pln"> b </span><span class="pun">=</span><span class="pln"> hue2rgb</span><span class="pun">(</span><span class="pln">p</span><span class="pun">,</span><span class="pln"> q</span><span class="pun">,</span><span class="pln"> h </span><span class="pun">-</span> <span class="lit">1</span><span class="pun">/</span><span class="lit">3</span><span class="pun">);</span> <span class="pun">}</span> <span class="kwd">return</span> <span class="pun">[</span><span class="typ">Math</span><span class="pun">.</span><span class="pln">round</span><span class="pun">(</span><span class="pln">r </span><span class="pun">*</span> <span class="lit">255</span><span class="pun">),</span> <span class="typ">Math</span><span class="pun">.</span><span class="pln">round</span><span class="pun">(</span><span class="pln">g </span><span class="pun">*</span> <span class="lit">255</span><span class="pun">),</span> <span class="typ">Math</span><span class="pun">.</span><span class="pln">round</span><span class="pun">(</span><span class="pln">b </span><span class="pun">*</span> <span class="lit">255</span><span class="pun">)];</span> <span class="pun">}</span> |