늘모자란, 개발 :: 색상 정렬 (Color sort) 맺으며..

늘모자란, 개발

시작하며


제발 마지막 글이 되었으면 좋겠지만..

두번에 걸쳐 HSL과 delta E (CIE 2000)에 거친 색 정렬을 시도해보았으나 정렬된 결과가 아무래도 맘에 들지 않았다.
도대체 21세기에! 색을 정렬하는 방법이 없나?라는 의문을 가지고 구글링했으나.
맞다. 색을 정렬하는 방법은 없다.... 이상한 영상이 하나 있긴한데 색상을 기준으로 하는건 아닌것 같다.

이 글을 쓰게 된데는 이유가 있다. 바로 이 글을 봤기 때문이다.

Unfortunately this idea runs into a basic problem: You can’t sort colors. Because the human eye has three distinct color sensors (red, green, and blue), color is fundamentally a three-dimensional quantity, and there is no linear ordering that brings together “similar” colors. If you sort first by amount of red, for example, then you may bring together wildly different hues and brightnesses. If you sort by hue, then you bring together wildly different degrees of saturation and brightness, and so on. There’s just no way to do it.

댓글에 애초에 베이스부터가 틀렸다고 색 정렬 못한다고 하는데 이대로 끝낼 순 없지않은가?
이가 없으면 잇몸으로라도 한다고... 정렬하는 척이라도 해야지 않을까?

그래서

처음에 접근한 방법은 휘도, 채도를 이용해 HSL로 색을 정렬하는 방법이었다.
공식에 사용되는 수치는 조금씩 다를 수 있지만 원리 자체는 별차이가 없다.

이 방법은 SQL 쿼리만으로도 뽑아낼 수 있다. (아주 편함)
order by SQRT(`R` * `R` * 0.241 + `G` * `G` * 0.691 + `B` * `B` * 0.068)


다음과 같은 SET을 얻을 수 있었다. 온전히 색의 밝기만으로 정렬하는것이기때문에
색상들이 진행될수록 어두워지는걸 알 수 있다. 하지만 정렬이라고 보긴 어렵다.



그 다음으로 시도한것이 delta E (CIE 2000) 으로 색상사이의 간격을 계산 후 정렬하는것이었다. (color distance or difference)
사실 여러방법으로 시도하는 글이 있고, 여러 알고리즘이 있지만, 결국 원리는 비슷했기때문에 요방법만 해보기로 했다.

HSL 로 정렬한 SET에서 색을 한개씩 뽑아내 그 색으로부터 가장 가까운 색을 뽑는것이다.
이 방법은 꽤 괜찮은 시도였다고 생각한다.



꽤 군집이 생긴것 같지만, 여전히 '완전한' 정렬이 되었다고 보긴 어려웠다. 갑자기 회색톤으로 가다가 빨간색이 나오질 않나..
그래서 정렬하는 과정을 꼼꼼히 살펴보기로 했다. 예를 들변 핫핑크에서 꽃핑크를 선택하는 과정은 다음과 같았다. 길어서 중간은 좀 잘랐다.

[!]블드핫핑크
[INIT] 레몬(금속) 155.26638858087
[CHANGED] 리옐(금속) 152.03349927037 
[CHANGED] 리옐 151.11097423585 
[CHANGED] 핫핑크 10.281657185973 
[CHANGED] 꽃핑크 7.5335844516123 
[ADDED] 꽃핑크

[!]꽃핑크
[INIT] 레몬(금속) 150.23029944029
[CHANGED] 리옐(금속) 147.51696619098 
[CHANGED] 리옐 146.71284135744 
[CHANGED] 딥핑크 13.359231425896 
[CHANGED] 딥핑크(금속) 13.359231425896 
[ADDED] 딥핑크(금속)


색상거리의 최소값을 계산하는 과정인데 하자가 없어야했다. 이론대로라면 완전히, 깔끔하게 정렬되어야 하는데 왜 저런 결과가 나온걸까?
도대체 중간에서 오른쪽쯤에 떨어진 저 빨간색은 왜 거슬리게 저기 있어야만 한걸까?

저 친구의 이름은 블드체리인데, 저 친구도 물론 후보로 거론된적이 잇는 친구였다. 하지만..

[!]체리분홍(금속)
 [CHANGED] 블드체리 16.814328547159 
[CHANGED] 블드탁한체리분홍 6.9852497800933 
[ADDED] 블드탁한체리분홍

[!]블드탁한체리분홍
[CHANGED] 블드체리 15.356974641448 
[CHANGED] 블드체리분홍 10.401343164254 

[CHANGED] 블드체리 22.072876833766 
[CHANGED] 블드핫핑크 5.735796527615 
[ADDED] 블드핫핑크

[CHANGED] 블드체리 18.265066068665 
[CHANGED] 핫핑크 17.31315523967 
[CHANGED] 딥핑크 13.359231425896 
[CHANGED] 딥핑크(금속) 13.359231425896 
[ADDED] 딥핑크(금속)

[CHANGED] 블드베이비핑크 48.921819262293 
[CHANGED] 블드체리 40.790667505018 
[ADDED] 블드체리


밀리고 밀리고 밀리다가 색상차이가 40이나 되는 상관없는 색에게 선택받을 수 있었던것이다.
코드상으로는 최소한의 색상차이가 나는 색상을 뽑았기때문에 문제가 없지만, 이는 정렬이 되었다고 판단할 수 없게 만드는 가장 큰 요소였다.
근소한 값으로 차이가 발생했다고 하더라도 선택되지 않으면 다음 색상 선택에서 완전히 달라진 결과를 도출하기 때문이다.

그래서 오차를 줘서 후보군을 구제해보기로 했다.
블드체리 색상은 11정도의 색상차이로 탈락하기 때문에 얼마나 큰 차이가 있을지 비교해보기위해 시각화해서 비교해보기로 했다. (인간의 눈 기준으로)
다음은 그 결과이다.



뭘 보라고 하는지 모르겠는 사람도 있을 것 같지만, 3번라인을 보면 튀는 값도 없고 정렬됐다고 할 수 있을지도 모른다. 흠..
그렇다면 최종 선발된 값과 탈락한 후보군들과의 색상차를 모두 다시 계산해 준다면 어떨까?

요컨데 이런식이다.

[!]탁메론
...
[CHANGED] 연두 11.174564290748 
[CHANGED] 블드연두 8.8682969251542 
[ADDED] 블드연두
...
[CHOSEN]블드연두 ->블드연한메론 18.812444073324
[CHOSEN]블드연두 ->연두 3.1295681624566
[ADDED2] 연두


과정을 되새김질해서 아깝게 탈락한 후보군들을 재활용해보겠다는것이다.
위와 같이 연두컬러는 블드연두라는 컬러와 겨우 3차이의 색상차가 발생해 탈락하지만, 재검사로 바로 다음에 색상을 배치하는것.
그 결과는...


여전히 카오스지만 꽤나 스무스해졌다(고 생각한다)
이 중에서 제일 괜찮아 보이는 4번라인으로 최종선택을 했다.

결론





결과적으로만 놓고보면... 거의 차이가 없다 ㅠㅠ.. 그치만 블드체리 친구(빨간줄)이 사라졌다....... 이게 소득일까...?

사람이 판단 하는 색상과 기계가 판단하는 색상을 동일하게 볼 수 없다는것이며, 휴먼소팅(...)을 해야 예쁜 그라데이션을 만들 수 있을 것 같다.

이 삽질의 흔적은 싴갤러스 지염 도서관에서 찾아보실 수 있습니다...





2016/05/22 00:43 2016/05/22 00:43