Music of Color

CTP431 20110227 김덕성

들어가며

"그림은 어떤 소리를 낼까" 라는 생각으로 본 프로젝트를 시작하게 되었습니다. 이미지는 음악과 밀접한 관련을 가집니다. 앨범은 앨범 커버와, 콘서트는 콘서트 포스터와, 유튜브에서 이미지와 함께 음악을 듣는 것이 그냥 음악만 듣는 것보다 낫다고 느끼곤 합니다. 이어폰을 꼽고 저녁 풍경을 보면서 지금 순간과 음악이 잘 어울린다고 감탄하기도 합니다.

거기엔 수많은 요인이 있겠지만 저는 그중에 「색」에 집중하였습니다. 우리는 색이 주는 느낌에 민감하기 때문에 어떤 작업을 하더라도 굉장히 신중을 기해 고릅니다. 따라서 이미지에서 색을 해체하고 재분류하여 소리와 맵핑하여 보기로 하였습니다. 먼저 색을 추출을 고민해봅니다.

색 추출

평균

무엇이 이미지의 색일까는 생각할 거리가 많은 주제입니다. 처음엔 단순히 전체 이미지의 평균색을 생각하였습니다. 그래도 통일적인 느낌은 비슷하지 않을까 생각하였기 때문입니다. 평균 결과물은, 이미지의 색이 아니라고 할 순 없지만, 색 고유의 느낌을 정말 많이 해치고 일반적으로 어두운 색만이 나왔습니다. 생각보다 이미지속엔 느끼는 것보다 무채색과 어두운색이 많았으며 우리의 눈에 오브젝트와 유채색이 더 눈에 먼저 들어온다는 결론을 내렸습니다. 오브젝트 디텍팅은 이슈가 많고 비교적 느릴것같아 이번 프로젝트에선 제외하였고, 유채색과 무채색을 분리하기로 하였습니다.

유채색 무채색

채도의 높고 낮음을 측정하기 위해서 색공간을 다뤄야합니다. RGB를 HSV(HSL)로 변경하여 채도(Saturate)를 기준으로 무채색(Achroma)과 유채색(Chroma)의 픽셀들을 분류할 수 있었습니다. 그러면 이제 유채색은 다시 색상(Hue)를 기준으로 그룹을 지을 수 있으며 이를 히스토그램으로 표현하여 피크를 찾았습니다. 들쭉날쭉한 히스토그램을 GausianSmoothing을 이용해 부드럽게 깎고, 낮은 부분에서 발생 할 수 있는 노이즈를 제거기위해 히스토그램의 Max값을 기준으로 일정 높이 이상은 잘라낸뒤 피크를 찾아 내었습니다. 이 피크는 해당 피크의 시작점과 끝점 정보를 함께 포함합니다. 색상은 0부터 360의 값을 갖는데, 360이후에는 0이되는 순환데이터이기 때문에 빨간계열의 색들, 예를 들어 340 ~ 40사이의 색상을 갖는 히스토그램에서 피크점을 찾는데에 이슈가 있었습니다.

이제 이 색상 데이터를 가지고 유채색 픽셀들을 순회하며 해당 색상의 픽셀들을 평균내었습니다. 본 과정에서 색의 존재비율도 함께 계산합니다. 본래 채도와 명도를 기준으로 클러스터링 알고리즘을 적용하였으나, 너무 속도가 느려져 평균으로 대체하였습니다. 이에따라 현재 알고리즘에선 같은 색상의 다른 채도, 밝기를 가진 두 색을 구분하지 못합니다.

무채색에선 색상보단 밝기가 더 중요할 것입니다. 밝기에 대한 히스토그램을 그려 마찬가지로 피크점을 찾은 후, 이를 바탕으로 무채색 픽셀을 순회하여 색을 골랐습니다. 유채색과 마찬가지 이유로 평균을 사용하였고 본래 채도가 낮아서 유채색에 비해 평균의 결과값이 민감하진 않았습니다.

눈에 띄는 색

이제 두가지 문제가 있었습니다. 같은 색상이더라도 샛노랗거나 새빨간 고채도의 색이 우리 눈을 먼저 사로잡지만 색상의 피크점은 이런 고채도 색을 걸러내지 못했습니다. 또한 야경 같은 이미지에서 밝은 점들은 눈에 먼저 띄므로 먼저 걸러낼 필요성이 있습니다. 따라서 무채색 유채색 분리에 앞서 채도가 높은 색과 밝기가 밝은 색은 먼저 걸러내었습니다. 이부분은 흰바탕에 검은 점이 있을 때는 검은 점이 눈에 띄는등 색 자체보단 존재비율과 콘트라스트와 관련이 있을 수도 있고, "눈에 띄는 색"에 대한 기준에 대해서도 다소 논의가 있을 수 있습니다만, 본 프로젝트에선 시간관계상 고채도와 고명도색을 주관에 따른 임의의 기준으로 설정하여 나누었습니다. 유채색, 무채색 기준도 마찬가지입니다.

HSV에서 Lch로

다음문제는 거꾸로 색상에서 발생하였습니다. 빨강, 초록, 파랑 계통의 색이 섞여 있을 때 우리눈은 빨강 초록 계열이 더 눈에 들어오며, 색을 디테일하게 분간할 수 있는데 이는 눈의 구조 때문입니다. 초록에서 파랑 사이의 색보다 빨강에서 초록사이의 색 (다홍 주황 노랑 등)에 더 많은 이름이 붙은 것도 이런 이유에서 입니다. 따라서 우리눈에 보이는 것보다 컴퓨터적인 파랑은 더 많은 범위를 차지하게 되고, 빨강과 초록사이에 끼어있는 노랑은 보이는 것보다 더 적은 범위를 차지하게 됩니다. 이를 처음엔 빨강초록파랑에 임의의 가중치를 두어 해결하였으나, 파랑의 경우는 아무리 새파랑이어도 어둡다는 문제 때문에 색공간을 조정해야할 필요를 느낍니다. 이런 인간의 지각을 기준으로 생겨난 색공간이 Lab 색공간이며, 이를 HSV와 비슷하게 밝기, 채도, 색으로 변환한 것이 Lch색공간입니다. Lch로 변환하면서 고채도의 색을 디테일하게 고채도의 색과, 고명도의 색으로 나누어 추출 할 수 있었으나 시간의 문제로 색공간 변환으로만 만족하였습니다.

소리

맵핑

음악을 만들까 소리를 만들까가 첫번째 고민이었습니다. 많은 색 데이터를 바탕으로 한 음을 뽑아내는 것과 음악을 만드는 것중에 색 하나하나가 음이다라는 생각에 본 프로젝트는 음악을 제너레이팅하기로 하고 일정 마디를 계속 루프를 하는 형태를 생각하였습니다.

색상은 진동수, 밝기는 BPM, 색의 수가 소리의 풍부함을 정하며 존재 비율이 음의 개수를 정하자는 것이 초기 생각이었고, 색을 뽑고나니 고채도의 색과 유채색 무채색으로 나뉘었고 각각은 어떤 느낌을 주는 걸까 다시 고민하였습니다. 초등학교 때 음악을 그림으로 표현해보는 것이 생각나서 떠오르는 음의 형태를 그림으로 그리며 생각해보았습니다.

무채색

무채색의 모습은 지직거리거나 우웅거리는 노이즈의 형태였습니다. 단순노이즈와 그 무채색의 밝기를 진동수와 맵핑하여 소리를 내고 임의의 박자를 주어 들어보았는데 꽤 들을 만한 소리가 되었고, 노이즈와 박자의 조합은 자연스레 드럼을 떠올리게 하였습니다. 따라서 무채색을 세가지로 나누어 검정의 계열은 Kick, 회색은 Close Hi-hat, 흰색은 Open Hi-hat으로 맵핑한 뒤 임의의 노트로 연주하였습니다. 악기의 색을 밝기에 다시 맵핑하여 색에 따라 서로다른 kick, Hi-hat의 음색이 되게 하였습니다.

BPM, 박자

BPM과 박자, 곧 악보를 색의 존재비율과 연결을 짓기로 하고 기준이 되는 BPM은 이미지에서 가장 지배적인 색(이하 지배색)으로 정하였습니다. 뿐만아니라 반복되는 루프의 길이도 중요한데, 지배색의 비율이 크면 그만큼 이미지가 단순한 것이며, 작으면 이미지가 복잡한 것이기 때문에 지배색의 비율의 작을 수록 반복되는 마디수는 커집니다. 다른 색들의 박자는 이 지배색과의 비율을 통해 정하기로 하여 지배색으로 결정된 마디 수를 일정간격으로 나누어 악보를 만들었습니다. 이에 따라 서로다른 하이엣사운드는 존재비율이 다르면 서로 엇박을 만들게 되어 디테일한 드럼박자를 만들 수 있게됩니다.

유채색

단순 frequency맵핑은 두가지만 섞여도 불협화음으로 소음을 만들어내어서 기존 음 체계를 토대로 frequency를 midi로 바꾸어 연결하였습니다. 마찬가지 방법으로 악보를 생성하였고 sawtooth와 sine 의 oscillator와 delay, filter를 이용해 음을 만들었습니다.

고채도 색

음악에서의 조미료 처럼 효과음이나, 청아한 소리 같은 느낌을 생각하여 delayNode를 통해 여리게 사라지는 음을 만드려고 하였습니다. envelop과 delaytime에 색 데이터를 맵핑하여 시도하였으나 튀는 레이져소리에 가까운 결과물이 나와 해당 데모에서는 고채도 색을 주석처리하였습니다. sound.js파일에서 해당 코드의 주석을 해제하여 들으실 수 있습니다.

제언

시간이 많이 부족한 프로젝트였습니다. 색추출도 많이 스스로와 타협하였는데 색에대해선 Lch를 통해 좀더 많은 정보와 함께 더 디테일하게 납득할만한 색을 뽑고싶습니다. 더 많은 테스트 케이스를 사용하고 또한 알고리즘의 속도를 개선하는 것이 목표입니다.

본 프로젝트로 생성된 것은 소음과 음악의 사이에 아슬아슬하게 놓여있는 것 같습니다. 색에비해 음악이 더 어려웠던 것은 분해보단 조합이 어렵기 때문도 있지만 여러 소리는 처음 구상할 때 상상했던 것보다 더 조화를 이루어야했기 때문이었습니다. 처음엔 색조합에 따라 노드를 다양하게 배치하여 전혀 다른 소리가 나오게 하려고 했었습니다만 소리가 아니라 음악으로써 생성되려면 장르를 정하는 것이 더 음악다운 것을 만들어 낼 것입니다. 혹은 여러 장르 정보를 넣어두고 데이터를 통해 장르를 선정하거나, 처음 기획당시 생각했던대로 8bit 음악을 만드는 것도 방법입니다.

연주나 작곡에 대한 경험이 없던 것도 프로젝트 결과물이 풍부하지 못한 이유입니다. 좀더 작곡적인 기법과 제너레이팅을 연결 할 수 있으면 좋겠습니다. 시간이 부족하여 꾸준히 데이터 맵핑 변수들을 조절하며 소리의 디테일을 잡지 못했던 것들이 아쉽게 느껴집니다.

코드

프로젝트를 움직이는 main.js와 색추출부분, 음악부분으로 나누어져 있습니다. 색추출하는 모듈의 이름은 Rothko로 정하였고, 이 Rothko는 세개의 서브모듈 colorchip.js, drawingKit.js, histogram-analyze.js로 이루어집니다. 각각은 색변환, 캔버스 유틸, 히스토그램 분석에 사용됩니다. 음악부분은 sound.js에 있으며 playSound, stopSound로 나눕니다. playSound에서 사용한 모든 컴포넌트를 리턴하여 stopSound시 모두 제거합니다. 그외 histogram-draw.js는 히스토그램을 보여주기위한 유틸리티입니다.

라이브러리 세가지중 vendor에 있는 moderizr는 브라우저 호환성과 관련된 라이브러리이므로 본 프로젝트와는 무관합니다. 사용한 라이브러리는 bower_components에 있으며 소리를 만들기위해 Tone.js와, 직접작성한 colorchip.js에 문제가 있어 chroma.js를 마지막에 일부 차용하였습니다.

rothko.js는 정리하여 라이브러리 배포할 예정입니다.

데모

사진을 클릭하거나 드롭다운 하여 직접 테스트해보세요

지배적인 색

고채도 색

유채색

무채색