Engineering
주니어 FE 개발자의 색상 추출 라이브러리 개발기
eve.christmas카카오
2024년 7월 8일
원문에서 보기 ↗개요
안녕하세요, 카카오 FE플랫폼 조직에서 광고SDK 업무를 담당했던 이브입니다.
이 글에는 광고 프로젝트를 담당하던 주니어 개발자가 색상 추출 라이브러리를 개발하게 된 과정을 담았습니다. 이 글에 포함되는 내용은 다음과 같습니다.
- 광고 효율을 높이기 위한 기획자의 아이디어를 구체화하여 사내 라이브러리로 배포하기까지의 과정을 소개합니다.
- 색상 추출에 사용한 K-means Clustering 알고리즘의 작동 원리와 실제 적용 결과를 소개합니다.
- 기획자, 디자이너 등 타 직군과의 소통을 위해 스토리북을 활용한 사례를 소개합니다.
문제정의
카카오 광고 템플릿 소개
카카오에서는 광고 사업을 활발하게 진행하고 있습니다. 카카오 FE 조직에서는 자신의 페이지에 광고를 노출하려는 매체들이 사용할 수 있는 광고SDK 뿐만 아니라, 광고 동영상 플레이어, 광고 템플릿과 같이 광고와 관련된 여러가지 FE 프로젝트를 담당하고 있습니다.
그 중 광고 템플릿 프로젝트는 광고주가 광고 이미지와 문구만 등록하면, 카카오에서 미리 정의한 다양한 템플릿으로 조합하여 광고를 노출하는 프로젝트입니다. 카카오 광고 템플릿을 사용하면 다음과 같은 장점이 있습니다.
- 광고주가 완성된 형태의 광고를 등록할 필요가 없이, 광고에 필요한 최소 정보(광고 문구, 이미지 등)만 등록합니다. 이처럼 광고 등록 과정을 간소화하여 광고주의 부담을 줄이고, 광고주가 광고 캠페인에 더 집중할 수 있게 합니다.
- 카카오에서 검수한 디자인에 따라 광고 지면에 알맞은 크기와 형태로 광고가 노출됩니다. 이는 광고주에게 안정적인 광고 노출을 보장하고, 오랫동안 카카오에서 축적한 데이터와 노하우를 활용한 템플릿으로 광고 효율을 향상합니다.
![[그림1] 카카오 광고 템플릿 프로젝트](https://t1.kakaocdn.net/kakao_tech/image/81e5dccb019000001.png)
광고 색상 추출 작업의 목표
기획에서 이러한 광고 템플릿에 광고 이미지와 어울리는 색상을 채워주면 어떨까 하는 아이디어를 제안하셨습니다. 이렇게 하면 광고주가 등록한 에셋으로 채워지지 않는 여백을 최소화하면서 전체 광고가 일관성 있게 보여지는 효과를 기대할 수 있었습니다.
![[그림2] 템플릿의 빈 곳에 색상을 채운 광고의 예시](https://t1.kakaocdn.net/kakao_tech/image/81e5e249019000001.png)
광고주가 광고에 노출할 문구와 이미지를 등록할 때, 광고의 빈 곳에 채워질 색상을 추가로 등록하도록 하면 이 아이디어는 쉽게 구현될 수 있습니다. 그렇지만 색상이 채워진 광고의 효과가 입증되지 않은 상태에서 카카오의 고객인 광고주에게 이를 요청하는 것은 위험성이 있다고 판단하였습니다. 따라서 우선 광고주에게 별도의 색상을 요청하지 않고, 광고를 그려주는 템플릿에서 광고 이미지를 기반으로 적절한 색상을 채워주도록 구현한 후 광고 효과를 측정해 보기로 하였습니다.
대표 색상의 정의
이러한 배경을 바탕으로 ‘광고 이미지의 대표 색상을 자동으로 추출하는 템플릿 코드 작성’이라는 태스크가 기획에서 개발로 넘어오게 되었습니다. 그런데 ‘대표 색상’이라는 정의가 생각보다 쉽지 않았습니다. 아래에 두 가지 예시를 들어보겠습니다.
첫 번째, 만약 이미지 전체의 수치적 평균을 계산해 보면 어떤 결과가 나올까요? 대상 이미지를 아주 멀리서 바라보면 전체 픽셀 RGB의 수치적 평균과 유사한 결과를 얻을 수 있습니다. 만약 전체 이미지가 비슷한 톤으로 이루어져 있다면 이미지를 대표할 만한 결과를 얻겠지만, 다양한 색으로 이루어진 이미지의 경우에는 생뚱맞은 결과를 얻을 수 있습니다.
예시로, 그림3의 첫 번째와 두 번째 이미지의 경우 그럴듯한 결과를 보이지만, 세 번째와 네 번째 이미지의 경우 이미지에는 없는 색상이 도출되는데요, 마치 이미지의 모든 색상을 한 팔레트에서 섞은 것과 같습니다. 원본 이미지에는 존재하지 않는 색상이기 때문에 대표 색상이라고 하기에는 어색합니다.
![[그림3] 수치적 평균값을 적용한 예시](https://t1.kakaocdn.net/kakao_tech/image/81e5e4ea019000001.png)
두 번째, 전체 픽셀 RGB 값 중 가장 많이 등장한 값, 즉 최빈값을 추출해보면 어떤 결과가 나올까요? 단색 위주의 이미지라면 괜찮은 결과를 얻을 수 있을 것입니다. 하지만 사람의 눈에는 비슷해보이지만 그라데이션과 같이 실제 RGB 값에 미세한 차이가 있는 색상들이 주류를 이루는 이미지라면 전혀 다른 결과를 얻을 수 있을 것입니다.
예시로, 그림4의 첫 번째와 두 번째 이미지의 경우 단색 위주로 이루어진 이미지이기 때문에 그럴듯한 결과를 보입니다. 그러나 세 번째 이미지의 경우 가장 많은 영역을 차지하는 것처럼 보이는 초록색 계열의 색상이 아닌, 전혀 생뚱맞은 색상을 반환합니다. 또한 세 번째, 네 번째 이미지의 결과값을 보면 매우 유사하게 보이는 색상들이 줄지어 있는 것을 확인할 수 있습니다
![[그림4] 최빈값을 적용한 예시](https://t1.kakaocdn.net/kakao_tech/image/81e5e797019000001.png)
위 두 가지 예시를 종합하여 보면, 사람이 보기에는 비슷한 색상이지만 실제 RGB 값은 조금씩 다른 픽셀들을 하나의 그룹으로 묶은 후, 가장 많은 픽셀이 포함된 그룹의 색상을 선택한다면, 좀 더 괜찮은 결과를 얻을 수 있지 않을까요?
문제 해결
K-means Clustering 알고리즘
색상 정보는 RGB 또는 HSV 라는 3차원의 값으로 표현할 수 있습니다. 3차원의 색상 정보 간 ‘거리’를 활용하여, 거리가 짧은 픽셀끼리 같은 그룹으로 묶는다면 색상들을 그룹화할 수 있을 것으로 보였습니다.
![[그림5] 색상 정보 간 거리](https://t1.kakaocdn.net/kakao_tech/image/81e5ea07019000001.png)
이러한 문제를 데이터 과학에서 ‘군집화’ 문제라고 합니다. 군집화는 서로 유사한 데이터들은 같은 그룹으로, 서로 유사하지 않은 데이터는 다른 그룹으로 분리하는 것입니다. 군집화에서 중요한 두 가지 문제는 다음과 같습니다.
- 몇 개의 그룹으로 묶을 것인가
- 데이터의 ‘유사도’를 어떻게 정의할 것인가
군집화 문제를 푸는 알고리즘 중 가장 널리 쓰이는 K-means Clustering 은 위의 두 가지 문제를 다음과 같이 풀어냅니다.
- ‘K’ 라는 인자를 사용해 사용자가 몇 개의 그룹을 만들 것인지 설정합니다.
- ‘Means’ 는 각 데이터로부터 데이터가 속한 그룹 중심까지의 평균 거리를 의미하며, 이 거리가 짧을수록 유사한 데이터가 됩니다. 이 값을 최소화하는 것이 K-means Clustering 알고리즘의 목표입니다.
![[그림6] K-means clustering 알고리즘](https://t1.kakaocdn.net/kakao_tech/image/81e5ec47019000001.png)
K-means clustering 알고리즘의 작동 원리는 다음과 같은 반복적인 접근이 핵심입니다.
- K 개의 임의의 중심점(centroid)을 배치한다.
- 각 데이터를 가장 가까운 중심점(centroid)의 군집(cluster)으로 할당한다.
- 새롭게 만들어진 각 군집의 중심점을 업데이트한다.
- 위의 2, 3번 과정을 반복한다.
이를 그림으로 살펴보면 다음과 같습니다.
설정값: K=2
- 중심점을 랜덤 초기화합니다.

- 모든 데이터를 가장 가까운 중심점의 군집으로 할당합니다.

- 각 군집의 중심점을 업데이트합니다.

- 모든 데이터를 가장 가까운 중심점의 군집으로 할당합니다.

- 각 군집의 중심점을 업데이트 합니다.

- 4,5 과정을 반복해도 더이상 중심점이 달라지지 않기 때문에 종료합니다.
[그림7.1 - 7.5] K-means clustering 알고리즘 예시
K-means clustering 알고리즘은 위와 같은 방식으로 동작합니다. 이 동작과 함께 유의해야 할 사항은 다음과 같습니다.
- 최초의 중심점 초기화에 따라 결과가 달라집니다. 따라서 중심점 초기화에 랜덤 선택, K-means++ 기법 등의 다양한 전략이 존재합니다.
- k값을 정하는 데에도 다양한 방법을 시도해 볼 수 있습니다. 원하는 군집의 개수가 있다면 이를 k값으로 사용할 수 있습니다. 원하는 군집의 개수가 없다면 Elbow Method, Silhouette Method와 같은 방법으로 이상적인 k값을 결정할 수 있습니다. 중요한 것은 다양한 조합으로 시도해 보고, 그중 가장 이상적인 결과값을 반환하는 파라미터를 선택하는 것입니다.
- 일반적으로는 더 이상 중심점이 달라지지 않을 때까지 중심점 할당과 업데이트를 반복하지만, 무한 루프에 빠지지 않도록 최대 업데이트 횟수에 제한을 둡니다.
- 시간 복잡도는 일반적으로
O(I * K * d * n)입니다. 변수는 다음과 같습니다.I=반복 횟수,K=군집의 개수,d=데이터의 차원
색상 추출 알고리즘 적용
위에서 소개한 K-means Clustering 알고리즘을 광고 템플릿 내의 코드로 구현하여 광고 이미지의 색상을 그룹화하였습니다. 이때, 색상 정보의 분류라는 점에서 중심점과 K값을 결정하였습니다.
- 중심점은 빨간색, 초록색, 파란색, 노란색, 보라색 등의 가장 특징적인 색상들을 사용하였습니다.
- 다양한 이미지로 테스트해 보며 가장 이상적인 결과가 나오는 K값(군집의 개수)을 디자이너와 논의하여 결정하였습니다.
알고리즘을 적용한 결과는 다음과 같은데요, 이미지 내 색상들이 대체로 잘 군집화가 되고 대표 색상이 잘 추출되는 것처럼 보입니다.
![[그림8] 광고 이미지에 K-means clustering 알고리즘을 적용한 결과](https://t1.kakaocdn.net/kakao_tech/image/81e5f8f5019000001.png)
발전
스토리북을 활용한 테스터
K-means clustering 알고리즘을 적용하여 원하는 결과를 얻기까지 디자이너와의 소통이 중요했습니다. 다음과 같은 사항에 대하여 디자이너의 검토가 필요했기 때문입니다.
- 가장 이상적인 결과를 반환하는 색상 추출 방식
- 무채색, 원색과 같이 추출에서 제외할 색상의 범위
- 흰색 또는 검은색 중 어울리는 문구 색상
일반적으로는 개발 결과를 디자이너가 검토하고 의견을 전달하면, 개발자가 다시 개발에 반영하는 방식으로 소통할 수 있는데요, 이러한 방식을 여러 번 반복하는 것은 많은 시간이 소요되고 서로의 피로감이 높을 것으로 예상되었습니다. 따라서 개발자와 디자이너 간의 빠른 소통이 가능한 방법을 고민하였고 스토리북(Storybook.js)을 활용한 웹 테스트 도구를 만들어 디자이너에게 전달하였습니다.
스토리북은 패널에 원하는 값을 넣어 테스트할 수 있는 기능을 제공합니다. 이를 활용하여 패널에 테스트할 이미지의 url, 추출할 색상의 채도 및 밝기 범위, 다양한 색상 추출 방식을 선택할 수 있도록 개발하였습니다.
테스터를 사용하면 디자이너는 테스트할 이미지 url을 넣어 색상 추출의 결과를 바로 확인할 수 있습니다. 또한 다양한 옵션으로 테스트한 후 가장 마음에 드는 결과를 바로 개발자에게 전달할 수 있습니다. 이러한 소통 방식으로 디자인 검토 또는 개발 반영을 기다리는 딜레이를 줄일 수 있었고 불필요한 소통 과정을 줄일 수 있었습니다.
![[그림9] 디자이너와 기획자에게 전달한 테스터](https://t1.kakaocdn.net/kakao_tech/image/81e5fbeb019000001.png)
사내 라이브러리로 개발
최종적으로 디자이너가 검수를 마친 옵션을 적용하여 실제 광고 템플릿에 광고 이미지의 대표 색상이 채워지도록 배포하였습니다. 이후 A/B 테스트를 통하여 광고 배경색의 효과를 측정하였고, 광고의 빈 부분에 색상이 칠해져 있을 때 유의미한 효과가 있다는 것을 확인할 수 있었습니다.
따라서 초기의 기획 의도로 돌아가서, 광고 배경색의 효과가 입증되었으니, 광고주가 카카오 광고 플랫폼에 광고를 등록하는 시점에 광고와 어울리는 색을 광고주에게 요청하기로 하였습니다.
이 때, 광고주가 등록한 광고 이미지를 기반으로 대표 색상을 추출하여 광고주에게 추천한다면, 광고주 입장에서 해당 색상을 가이드 삼아서 보다 쉽게 색상을 고를 수 있을 것입니다.
![[그림10] 광고 이미지 기반 배경 색상을 제안하는 광고 플랫폼 예시](https://t1.kakaocdn.net/kakao_tech/image/81e5fe84019000001.png)
따라서 광고 템플릿에 적용했던 색상 추출 로직을 이제는 광고주가 사용하는 카카오 광고 플랫폼에 적용하고자 하였는데요, 광고 템플릿은 저희 FE 팀에서 담당하여 개발하고 있지만 카카오 광고 플랫폼의 경우 다른 팀에서 개발하고 있기 때문에 개발 주체가 다르다는 문제가 있었습니다.
따라서 광고 템플릿에 적용한 색상 추출 로직을 다른 팀에서도 사용할 수 있도록 사내 라이브러리 형태로 개발하여 전달하기로 협의하였습니다. 이를 통하여 광고 플랫폼 이외에도 ‘이미지의 대표 색상 추출 로직’을 필요로 하는 사내 다른 팀들의 니즈도 함께 충족할 수 있게 되었습니다.
라이브러리 형태에 적절한 인풋과 아웃풋을 정의하고, 기존 광고 템플릿 내에 적용했던 로직을 라이브러리 형태로 개발하였습니다. 이후 라이브러리 사용 가이드를 작성하여 사내에 배포하고, 광고 플랫폼 개발 측에 전달하였습니다.
![[그림11] 사내 npm 에 배포된 색상 추출 라이브러리](https://t1.kakaocdn.net/kakao_tech/image/81e6009c019000001.png)
이전에 기획자, 디자이너와의 소통을 위하여 스토리북을 활용하였던 것과 마찬가지로, 라이브러리를 테스트할 수 있는 페이지 또한 스토리북으로 개발하여 제공하였습니다. 테스트 페이지를 통해 다양한 옵션을 사용하여 라이브러리를 적용한 결과를 미리 테스트해 볼 수 있습니다.
![[그림12] 색상 추출 라이브러리 테스터](https://t1.kakaocdn.net/kakao_tech/image/81e60311019000001.png)
이후 다양한 팀에서 색상 추출 라이브러리를 사용하게 되면서 기존과는 다른 유즈 케이스를 만족하기 위한 개선 작업을 진행하며 라이브러리의 버전을 올려 나갔습니다. 예를 들어, 광고 템플릿에서는 이미지의 대표 색상 1개만 추출하면 되지만 광고주 플랫폼에 적용될 때에는 광고주에게 추천할 최소 색상 개수를 만족하도록 라이브러리가 지원해야 했습니다. 이러한 경우 옵션 추가 등의 방법으로 대응하며 현재도 계속 업데이트되고 있습니다.
마치며
지금까지 광고의 빈 곳을 이미지의 대표 색상으로 채웠을 때의 광고 효과를 확인하기 위한 작업이 사내 라이브러리 개발로 이어지게 된 과정을 소개해 드렸습니다.
이 과정을 통하여 주니어 개발자로서 문제 정의부터 문제 해결을 위한 알고리즘 구현, 그리고 타 부서의 니즈를 충족하기 위한 테스터 개발 및 소통까지 개발자로서 많은 영역을 경험하고 성장할 수 있었습니다. 이 과정에서 함께 애써주신 humphrey.park, jake.baek, terry.s, sienna.choi 에게 정말 감사드립니다.
독자분들에게도 이 과정이 조금이나마 흥미로우셨기를, 그리고 제가 얻었던 지식과 경험이 전달되었기를 바라며 글을 마칩니다. 긴 글 함께 해주셔서 감사합니다.