늘모자란, 개발 :: Sort color using delta E(CIE 2000) - Similar Color gradient

늘모자란, 개발

이 글은 HSV(HSL) for DB query - Sort color by lightness 에서 이어진 글입니다.

HSL은 밝기 기준으로 색을 정렬하는 기준이다.
하지만, 무작위 배열을 선택해 정렬했을 때는 전혀 정렬한것 같게 보이지 않는다는 단점이 존재한다.
복습해보자면, 간단한 쿼리로 HSL을 계산해서 색을 정렬했었고 그 결과는 다음 이미지와 같다.



사실 표본이 작기 때문에 이정도로도 충분히 정렬되었다고 판단할 수 있다.
하지만 모든 표본을 나열해보면 그렇지가 않다.
다소 길지만 비교를 위해서 그냥 올려본다. 양해를 구한다.



모든 표본을 나열했을때 밝음에서 어두움으로 넘어오곤 있지만, 사실 밝기 diff는 몰라도 사람의 시각으로는 이 데이터는 '정렬' 되었다고 말할 수가 없다.
물론, HSL이 쓸모가 없다는것은 아니다. 단지, 무작위 데이터를 처리할때 한가지 더 처리를 해줘야된다는것을 얘기하고 싶은것이다.

color Difference를 구하는 방법은 여러가지가 있으며 위키피디아에서 다수의 방법을 확인할 수도 있으며,
휘도(Luminance)로 정렬하는 방법도 존재한다.

하지만 휘도는 결국 Brightness 로서 HSL과 별 다를바가 없으며, 정렬햇을때도 결과가 비슷했다.
여러 방향으로 접근을 해봤으나 결론은 그라데이션(gradient)를 구현하려면 한가지 처리를 더 해야겠다고 생각했는데 (말은 쉽게하지만 나름 고민 하느라 많은 시간을 보냈다 ㅠㅠ) 그러다가 이 글을 보게 되었다.

내가 얻은 결론은 한가지 색을 뽑고 그 색의 color DIff를 계산해서 근접한 값을 모아줘야된다것이다.

데이터가 200개도 안되는 작은 숫자였기때문에, 선택 정렬(selection sort)을 이용해 정렬을 해볼까 했다.
2단 루프로 o(n^2)로 엄청나게 느리지만 표본이 적고, 먼저 HSL로 정렬된 값을 뽑기때문에 가능할거라 생각했지만..
중복처리를 하려면 답이 안나와서 결국 멋대로 작업해보기로 했다.
루프를 하나 돌고, 어레이를 삭제하고 초기화하는 좀 극단적인 방법이지만 별 다른 수가 떠오르지 않았다.....ㅠㅠ

색 판별은 delta E(CIE 2000) 알고리즘을 사용하기로 했다. color diff를 계산하는 방법은 여러가지가 있었으나, 색사이의 distance를 계산해야했기때문에 이 알고리즘을 선택했다.
라이브러리르는 직접 구현하지 않고, github에서 찾아다 썼다.

$sArray = Array();
$sArray[0] = $array[0];
$count = 0;

$i = 0;
while ( count($array) ) {

    $diff = "";
    $pointer = "";

    for ($j = 0; $j < count($array); $j++ ) {
        $cDiff = (new color_difference())->deltaECIE2000([ $sArray[$i]['colorR'], $sArray[$i]['colorG'], $sArray[$i]['colorB'] ], [ $array[$j]['colorR'], $array[$j]['colorG'], $array[$j]['colorB'] ]);
            if ( $diff == "" ){
                $diff = $cDiff;
                $pointer = $j;
            } else {
            if ( $cDiff < $diff )  {
                $diff = $cDiff;
                $pointer = $j;
            }
        }
    }

    $sArray[] = $array[$pointer];
    if ( $i == 0 ) {
        unset($array[0]);
    }
    unset($array[$pointer]);
    $array = array_filter($array);
    $array = array_values($array);
    $i = count($sArray)-1;

}


그 결과이다.


아래 그림은 최종본은 아니고, 실제로는 정렬되어있다.
재밌는 점은 분명히 이렇게 엮일거같다고 생각한 색들도 알고리즘에 의해 계산된 숫자 수치로는 다르다는점이었다
사람의 시각으로 정렬하는게 맞겠지만.. 일단은, 여기까지!



색상 정렬 (Color sort) 맺으며.. 에서 이어집니다.


Reference
https://en.wikipedia.org/wiki/HSL_and_HSV
https://en.wikipedia.org/wiki/Color_difference
https://github.com/renasboy/php-color-difference
2015/10/20 03:16 2015/10/20 03:16