[PHP]HSV(HSB)をRGBに変換する

以前 RGB を HSV に変換するプログラムを作りましたが、 今回はその逆で、HSV を 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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
function hsv2rgb($h, $s, $v){
    if ( $s == 0 ) {
        $r = $v * 255;
        $g = $v * 255;
        $b = $v * 255;
    } else {
        $h = ($h >= 0) ? $h % 360 / 360 : $h % 360 / 360 + 1;
        $var_h = $h * 6;
        $i = (int)$var_h;
        $f = $var_h - $i;
         
        $p = $v * ( 1 - $s );
        $q = $v * ( 1 - $s * $f );
        $t = $v * ( 1 - $s * ( 1 - $f ) );
         
        switch($i){
            case 0:
                $var_r = $v;
                $var_g = $t;
                $var_b = $p;
                break;
            case 1:
                $var_r = $q;
                $var_g = $v;
                $var_b = $p;
                break;
            case 2:
                $var_r = $p;
                $var_g = $v;
                $var_b = $t;
                break;
            case 3:
                $var_r = $p;
                $var_g = $q;
                $var_b = $v;
                break;
            case 4:
                $var_r = $t;
                $var_g = $p;
                $var_b = $v;
                break;
            default:
                $var_r = $v;
                $var_g = $p;
                $var_b = $q;
        }
        $r = $var_r * 255;
        $g = $var_g * 255;
        $b = $var_b * 255; 
    }
    return array($r, $g, $b);
}

引数は色相、彩度、明度の順で渡します。
色相(H)は 0 ~ 360 を指定し、彩度(S)・明度(V)は 0 ~ 1 の小数で指定します。
結果は RGB 値( 0 ~ 255 )の配列で返されます。

参考: HSV色空間 – Wikipedia

[PHP]RGBをLab色空間の座標に変換する

専門外なので公式をPHPに書き換えただけですが、RGB値をもとに l*a*b* に変換することができます。
D50 や D65 というのは昼光色を基準として決められた標準イルミナント(標準となる光)で、
D50 は色温度 5000K を、D65 は 6500K をベースに定められています。
今回は Photoshop CS6 のカラーピッカーに近似する D50 を使い、変換を行いました。

直接 RGB から Lab には変換できないようなので、XYZ 表色系に変換してからそれを Lab にします。

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?php
function xyz2lab($xyz) {
    $threshold = 0.008856;
     
    //Chromatic Adaptation Matrices
    // D50
    $ref_x = 0.96422;
    $ref_y = 1.0000;
    $ref_z = 0.82521;
     
    // D65
    /*
    $ref_x = 0.95047;
    $ref_y = 1.0000;
    $ref_z = 1.0883;
    */
     
    $var_x = $xyz[0] / ($ref_x * 100);
    $var_y = $xyz[1] / ($ref_y * 100);   
    $var_z = $xyz[2] / ($ref_z * 100);
     
    $var_x = ($var_x > $threshold) ? $var_x = pow($var_x, 1/3 ) : (7.787 * $var_x) + (16 / 116);
    $var_y = ($var_y > $threshold) ? $var_y = pow($var_y, 1/3 ) : (7.787 * $var_y) + (16 / 116);
    $var_z = ($var_z > $threshold) ? $var_z = pow($var_z, 1/3 ) : (7.787 * $var_z) + (16 / 116);
     
 
    $l = ( 116 * $var_y ) - 16;
    $a = 500 * ( $var_x - $var_y );
    $b = 200 * ( $var_y - $var_z );
    $lab = array();
     
    $lab = array($l, $a, $b);
     
    return $lab;
}
 
function rgb2xyz($rgb) {
 
    $r = $rgb[0] / 255;
    $g = $rgb[1] / 255;
    $b = $rgb[2] / 255;
 
    $r = ($r > 0.04045) ? pow(($r + 0.055) / 1.055, 2.4) : $r / 12.92;
    $g = ($g > 0.04045) ? pow(($g + 0.055) / 1.055, 2.4) : $g / 12.92;
    $b = ($b > 0.04045) ? pow(($b + 0.055) / 1.055, 2.4) : $b / 12.92;
 
    $r = $r * 100;
    $g = $g * 100;
    $b = $b * 100;
     
    $xyz = array();
     
    //sRGB D50
    $xyz[] = $r * 0.4360747 + $g * 0.3850649 + $b * 0.1430804;
    $xyz[] = $r * 0.2225045 + $g * 0.7168786 + $b * 0.0606169;
    $xyz[] = $r * 0.0139322 + $g * 0.0971045 + $b * 0.7141733;
     
    //sRGB D65
    /*
    $xyz[] = $r * 0.4124564 + $g * 0.3575761 + $b * 0.1804375;
    $xyz[] = $r * 0.2126729 + $g * 0.7151522 + $b * 0.0721750;
    $xyz[] = $r * 0.0193339 + $g * 0.1191920 + $b * 0.9503041;
    */
    return $xyz;
}
 
function rgb2lab($rgb) {
    $xyz = rgb2xyz($rgb);
    $lab = xyz2lab($xyz);
    return $lab;
}
 
//RGB値を 0~255 で指定する
$rgb = array(244,46,32);
var_dump( rgb2lab($rgb) );

参考
http://w3.kcua.ac.jp/~fujiwara/infosci/colorspace/
http://www.brucelindbloom.com/

[PHP]RGBをHSV(HSB)に変換する

前回RGB値を元に類似画像を検索しましたが、やはり人間の感覚で言うとHSVを使って画像を検索したほうがより近い画像を得られると考え、下準備として RGB を HSV に変換するプログラムを作りました。

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
36
<?php
//RGB値(0~255)
$rgb = array(
  "red" => 167,
  "green" => 65,
  "blue" => 189
);
 
$hsv = rgb2hsv($rgb);
print_r($hsv);
 
function rgb2hsv($rgb){
  $r = $rgb['red'] / 255;
  $g = $rgb['green'] / 255;
  $b = $rgb['blue'] / 255;
   
  $max = max($r, $g, $b);
  $min = min($r, $g, $b);
  $v = $max;
   
  if($max === $min){
    $h = 0;
  } else if($r === $max){
    $h = 60 * ( ($g - $b) / ($max - $min) ) + 0;
  } else if($g === $max){
    $h = 60 * ( ($b - $r) / ($max - $min) ) + 120;
  } else {
    $h = 60 * ( ($r - $g) / ($max - $min) ) + 240;
  }
  if($h < 0) $h = $h + 360;
 
  $s = ($v != 0) ? ($max - $min) / $max : 0;
   
  $hsv = array("h" => $h, "s" => $s, "v" => $v);
  return $hsv;
}

逆にHSVからRGBを割り出す場合はこちらを御覧下さい。

計算式は Wikipedia を参考にしています。