사진 속 별자리 찾기: 7년 걸린 Plate Solver 만들기
Software Engineer

1. 들어가며
안녕하세요, 버즈빌에서 Frontend 개발자로 일하고 있는 Brice입니다. 기술 이야기로 딱딱한 이곳 테크 블로그에서, 조금은 낭만적인 이야기를 해 보려고 합니다. 여러분은 별을 얼마나 자주 보시나요?
어린 시절, 아버지에게서 북두칠성과 카시오페이아자리, 오리온자리를 배웠습니다. 북두칠성과 카시오페이아자리는 늘 북쪽 하늘에서 북극성을 사이에 두고 서로 반대편에 있었고, 언제 보느냐에 따라 무엇이 보이는지, 어느 쪽에 보이는지가 달랐습니다. 하늘 높이 떠 있을 때는 작아 보이는데, 산 능선에 걸쳐 있을 때는 엄청 커 보여서 같은 별자리가 맞나 신기했습니다.
오리온자리는 분명 겨울철 별자리인데, 생각보다 자주 밤하늘에서 보였습니다. 고등학생 때 야간자율학습을 마치고 집으로 돌아가는 길에 하늘을 올려다보면 오리온자리가 반겨 주곤 했습니다. 고향보다 별이 훨씬 덜 보이는 서울에서도 오리온자리만큼은 밝게 빛나서, 대학교 과제를 마치고 들어갈 때도, 친구들과 놀다 들어갈 때도 하늘에서 오리온자리를 찾을 수 있었습니다.
이 사진에는 어떤 별자리가 있을까요? 답은 이 글에 들어오자마자 보셨죠?
밤하늘을 볼 때도, 밤하늘이 찍힌 사진을 볼 때도, 저기 찍힌 별은 무엇일까, 그 별들이 이루는 별자리는 무엇일까 궁금했습니다. 그래서 공부를 하다 보니 세상에는 제가 몰랐던 별과 별자리가 훨씬 많았고, 아주 옛날에는 이 별들로 내가 있는 위치와 시간을 알아냈다는 것도 알게 되었습니다.
2. 발단: 2019년, 사이판 워크숍 사진
예전에 버즈빌은 글로벌 워크숍을 가곤 했습니다. 2019년 6월의 글로벌 워크숍은 사이판에서 열렸는데, 그때 슬랙에 올라온 사진 한 장이 제 호기심을 자극했습니다. 해변에서 밤하늘을 올려다보는 사진이었는데, 저는 배경에 찍힌 별이 더 궁금했습니다.
별자리 앱으로 직접 찾아보고, 앱 화면을 찍어 스레드에 이렇게 남겼습니다.
배경의 별들이 궁금해서 찾아봤는데 남쪽하늘이었군요
왼쪽은 2019년 6월 슬랙에 올라온 사이판 사진, 오른쪽은 별자리 앱(Constellation Map)으로 같은 하늘을 찾아본 화면입니다. 사진에서 맨눈으로 보이던 별 8개(노란 원)의 배치를 앱에서 같은 모양으로 찾았어요.
7개월 뒤, 그 별에 대해 새로 알게 된 것을 같은 스레드에 덧붙였습니다.
방금 알게 되었는데 사진에 보이는 밝은 별은 '리길 켄타우루스', '알파 센타우리' 등의 이름을 가지고 있는데, 밤하늘에서 맨 눈으로 볼 수 있는 별 중에 태양 다음으로 가까운 별로 ...
사진 속 별이 하늘의 어디인지 찾아 주는 Astrometry.net이라는 훌륭한 서비스가 있어서 사이판 사진을 올려 봤습니다. 하지만 이 사진은 풀리지 않았습니다. 사람과 해변, 구름 같은 지상 물체가 별과 함께 찍혀 있었기 때문입니다. 그래서 저는 이렇게 일반인들이 찍은 사진들에 대해 잘 동작하는 도구를 만들어 보면 좋겠다는 생각이 들었습니다. 당시 회사 내에서 진행 중이던 머신러닝 스터디에 다음과 같은 말을 남겼습니다.
제가 예전에 머신러닝 공부하면 만들고 싶다고 생각했던 게 사진에 찍힌 별의 정보로 추가적인 정보를 얻는 것(ex: 위/경도, 시간, 방위 등)이었습니다. 과연 언젠가는 만들 수 있을까요?ㅋㅋㅋ
2019년 8월 19일
3. 공부: Plate Solving은 어떻게 하나 (2022)
만들려면 먼저 알아야 했습니다. Astrometry.net이 어떻게 사진을 푸는지 논문을 읽으며 공부했습니다. 사진 속 별이 하늘의 어디인지 알아내는 일을 천문학에서는 Plate Solving이라고 부른다고 합니다. 옛날에는 밤하늘을 찍은 유리질의 사진 건판에서 별을 찾았기 때문에 그렇게 불렀다고 합니다.
왼쪽은 1888년 윌리아미나 플레밍이 하버드 천문대의 사진 건판에서 말머리 성운을 처음 찾아낸 부분(빨간 원), 오른쪽은 오늘날 찍은 말머리 성운입니다. (왼쪽: 하버드 천문대 사진 건판, 오른쪽: ESO, CC BY 4.0)
공부한 내용을 바탕으로 2022년 6월 사내 Dev Seminar에서 "Introduction to Plate Solving"이라는 제목으로 발표했습니다. 몇 가지 밤하늘 사진으로 제가 직접 Plate Solving을 시연했고, 이를 컴퓨터로 구현할 때 어떤 구조와 알고리즘을 쓰면 좋을지는 Astrometry.net에서 공개한 논문과 발표 자료를 바탕으로 공유했습니다.
Plate Solver가 하는 일은 크게 네 단계입니다.
- 사진에서 별 찾기: 주변보다 밝은 점을 찾습니다.
- 별 지도에서 같은 배치 찾기: 별 몇 개가 이루는 모양을 "지문"으로 바꿔, 미리 만들어 둔 별 지도의 지문 중 닮은 것을 찾습니다.
- 맞는지 확인하기: 찾은 자리대로 별 지도를 사진에 겹쳐서 다른 별들도 맞는지 봅니다.
- 그리기: 사진 위에 별 이름과 별자리 선을 그립니다.
이 중 핵심은 2번의 지문입니다. 사람은 별자리 모양을 보고 "아, 오리온자리!" 합니다. 컴퓨터에게 시키려면 사진을 어떻게 찍었든 변하지 않는 "모양의 지문" 이 필요합니다.
Astrometry.net 논문(Lang et al., 2010)의 방법은 별 4개(quad)를 쓰는 것입니다. 4개 중 가장 먼 두 별 A, B를 (0,0)과 (1,1)에 오도록 옮기고, 돌리고, 키우면 나머지 두 별 C, D의 좌표 네 숫자가 남습니다. 사진을 돌려 찍어도, 망원 렌즈로 찍어도 이 네 숫자는 그대로입니다.
별 지도 쪽에도 같은 지문을 미리 만들어 두고, 사진의 지문과 가장 비슷한 것을 찾습니다. 찾으면 그 4개 별의 짝으로 사진 좌표와 하늘 좌표 사이의 변환을 구해, 주변 별과 별자리를 사진 위에 그립니다.
이 발표를 준비하며 다른 것도 하나 알게 됐습니다. 별자리만으로는 사진을 찍은 날짜와 시각을 하나로 정할 수 없다는 것입니다. 같은 하늘이 한 달에 2시간씩 일찍 오기 때문입니다.
발표 마지막에는 이렇게 말했습니다.
공부한 내용을 바탕으로 저만의 Plate Solver를 만들고 싶습니다. 일단은 배운 것들이 동작하는지만 확인할 수 있는 PoC 수준으로, 밝은 별로 동작하게 하고, 땅이나 구름이 찍혀도 동작하는 것으로, 모든 사진에 대해서 동작하게 만들기가 어렵다면 사진 한두 장에 대해서만이라도 동작하는 것을 목표로 하고 싶습니다.
4. 1차 시도: 2023년 드림챌린지
버즈빌에는 분기마다 각자 도전을 고르는 버즈챌린지라는 제도가 있습니다. 도전적인 목표를 세우고 달성하는 과정을 응원하는 포커스챌린지와, 도전 과정에서의 실패와 시행착오를 함께 나누는 드림챌린지 두 가지입니다. 이제는 정말 만들어 보고 싶다는 생각이 들어, 2023년 1분기에 Plate Solver 만들기를 드림챌린지로 신청하고 3개월 동안 집중해서 만들기 시작했습니다.
원래는 참고한 논문처럼 별 4개짜리 quad를 쓰고 싶었습니다. 하지만 관련 로직을 구현하는 데 어려움이 있었습니다. 시간은 빠르게 흘러 어느덧 약속한 3개월이 거의 지나, 발표일이 일주일 남았습니다. 어떻게든 발표 일정을 맞추기 위해 목표를 최대한 단순화했습니다.
- 별 4개짜리 quad는 포기하고, 더 단순한 별 3개 삼각형으로 찾는다.
- 여러 후보 중 가장 정확한 정답을 골라내는 부분은 구현하지 않고, 후보 중에 정답이 있다는 것만 보여 준다.
- 누구나 쓸 수 있게 호스팅하기 위한 경량화 작업은 이번에는 실패로 보고 미룬다.
그런데 별 9천 개로 만든 삼각형이 284만 개나 됐고, 사진 속 삼각형과 닮은 삼각형이 너무 많았습니다.
사진 속 별 셋으로 만든 삼각형의 모양 값(십자)과, 그 둘레를 확대한 별 지도 삼각형들(파란 점). 작은 원 안에만 닮은 삼각형이 2만 개 넘게 있고, 정답(초록)은 닮은 순으로 3,049등입니다.
다양한 시도 끝에 발표 전날인 4월 20일, 드디어 북두칠성으로 시험한 풀이가 5시간 35분 만에 정답을 첫 번째 후보로 내놓았습니다. '어쩌면, 발표 전에는 성공시킬 수 있지 않을까?' 하는 생각이 들었습니다. 발표 직전에는 오리온자리로 시험해 2분 41초까지 줄였습니다. 하지만 모든 사진에 대해 동작하는 것은 아니었고, 여러 후보 중 어떤 것이 정답인지도 알 수 없었고, 호스팅하지도 못했으니 실패한 것으로 선언해야 했습니다.
발표는 실패와 함께 "컴퓨터를 가르치는 일은 어렵습니다."라는 말로 마무리했습니다. 하지만 정확히 가르치려면 정확히 알아야 합니다. 결국 제가 정확히 몰랐기 때문에 정확히 가르칠 수 없었던 거죠.
이번에 글을 쓰며 그때 코드를 다시 살펴보니, 원인은 여러 겹이었습니다. 별 지도의 삼각형을 하늘의 작은 영역(반지름 5도쯤) 안에서만 만들어서, 25도에 걸친 북두칠성의 삼각형은 대부분 별 지도에 아예 없었습니다. 별 지도에 있는 정답 삼각형조차 모양이 비슷한 후보 3천여 개 속에서 632등이었고, 마지막 확인은 각도가 사실상 똑같아야 통과해서 정답을 넣어도 "아니다"라고 답했습니다. 하지만 당시에는 정확한 원인을 알지 못했고, 이 모든 원인을 하나하나 파악하고 해결하는 것은 많은 시간이 드는 일이라 더 진행하기 어려웠습니다.
언젠가 개선하리라 마음은 먹었지만, 시간이 많이 흘렀습니다. 그리고 새로운 세상의 변화에서 용기를 얻어 다시 도전하게 되었습니다.
5. 2차 시도: 2025년, ChatGPT와 함께
AI에게 디버깅을 맡겨 볼 만해진 2025년, AI를 쓰면 지금 무엇이 문제인지 쉽게 파악하고 고칠 수 있지 않을까 하는 생각이 들었습니다. ChatGPT에게 상황을 설명하면 ChatGPT가 상태를 확인하는 스크립트를 주고, 제가 그걸 돌려 결과를 다시 알려 주는 식으로 하나씩 고쳐 나갔습니다.
사진에서 별을 감지하는 방법을 물으니 ChatGPT는 OpenCV로 짠 파이썬 코드를 바로 내놓았고, 브라우저에서 돌아가게 OpenCV.js 코드로 바꿔 달라고 하니 그것도 해 주었습니다. 찾은 별들을 이어 삼각형을 그리는 코드도 마찬가지였습니다. 그래도 발표에서는 "AI가 시키는 대로만 하고 발표하는 사람은 되지 말자"고 다짐했습니다.
이번에는 논문대로 별 4개 quad로 돌아갔습니다. 하늘을 같은 넓이의 192칸으로 나누고(HEALPix), 칸마다 가까운 별끼리만 quad를 만들어 개수를 줄였습니다. 지문 검색에는 KD-tree를 썼습니다. HEALPix와 KD-tree를 직접 구현하려 했다면 매우 막막했겠지만, ChatGPT에게 요청하면 뚝딱뚝딱 코드를 만들어 주었고, 저는 그것을 제품에 넣고 동작하는지 확인만 하면 되었습니다. 그렇게 다양한 개선을 시도한 뒤, 2025년 3월 Dev Seminar에서 다시 발표했습니다.
2차 시도에서는 사람과 컴퓨터가 협업하는 방식으로 문제를 풀기로 했습니다. 사진에서 별과 건물 외곽의 불빛을 구별하는 알고리즘을 짜는 건 여전히 어려운 일이었기 때문에, 사람이 검수하기로 했습니다. 컴퓨터가 먼저 별을 감지하고, 사람이 그걸 검토해서 사람이 생각하는 별들을 표시해 주면, 그걸 토대로 컴퓨터가 Plate Solving을 합니다. 그 결과 컴퓨터 혼자서는 정확도가 높지 않았지만, 사람이 정리해 주면 정확도가 높게 나왔습니다.
사람 손 없이 돌리면 샘플 16장 중 4장만 맞았습니다. 첫 단추인 별 찾기부터 건물 불빛을 별로 잡았기 때문입니다.
그리고 지문이 가장 가까운 후보를 그대로 답으로 삼았는데, 그게 틀린 경우가 많았습니다.
후보가 나오기까지 사진 한 장에 4초쯤 걸렸습니다. 정답을 올바르게 판단하는 부분이 아직 부족해서, 호스팅을 위한 준비는 이번에도 하지 못했습니다. 별 사진 한 장을 풀어내려면 아직 28MB를 내려받아야 했습니다. 발표 마지막 장에 적은 남은 숙제는 세 가지였습니다.
- 올바른 결정하기: 찾은 답이 맞는지 스스로 판단하기
- 주변 별 표시의 오차 보정하기
- 아무나 써 볼 수 있게 웹사이트로 공개하기
ChatGPT와 함께했지만, 원인을 파악하고 분석하고 해결하는 디버깅 과정은 여전히 순탄치 않았고, 더 개선하려면 많은 시간을 들여야 했습니다. 언젠가 개선하리라는 다짐만 다시 하고, 그렇게 또 시간이 흘러갔습니다.
그리고 얼마 지나지 않아, 다시 기회가 찾아왔습니다.
6. 3차 시도: 2026년, Claude Code와 완성
겨우 1년밖에 지나지 않은 2026년, AI의 성능이 비약적으로 발전하여 이제는 직접 코드를 작성하지 않고 개발하는 것이 일반화되었습니다. 버즈빌에서도 이제 코드를 직접 작성해서 개발하는 사람은 없습니다. 2026년 하반기에 이르러서는 AI에게 브라우저 접근 권한까지 주고 직접 디버깅하게 했는데, 사람의 개입 없이도 어지간한 문제들은 훌륭하게 해결되었습니다. 이 방식을 Plate Solver에 적용하면 이번에는 완성할 수 있지 않을까 하는 생각이 들었습니다.
그래서 이번에는 코드를 한 줄도 직접 쓰지 않고 Claude Code에게 맡겼습니다. 대신 함께 지킬 규칙을 정했습니다.
- 감으로 판단하지 않고 여러 사진으로 잰다.
- 앱과 같은 조건(사진 한 장에 8초)으로 잰다.
- 시도와 발견을 모두 기록한다.
1년 전에는 "AI가 시키는 대로만 하는 사람은 되지 말자"고 했는데, 이번에는 아예 AI에게 일을 시키는 쪽이 되었습니다. 저는 무엇을 할지 정하고, 결과가 맞는지 확인하고, 방향이 틀어지면 바로잡았습니다. 코드는 Claude Code가 썼고, 브라우저로 사이트를 직접 띄워 화면을 보며 고쳤습니다. 2026년 6월부터 넉 달 동안 커밋이 500개쯤 쌓였습니다.
세 가지 규칙은 생각보다 자주 저희를 구했습니다. 은하수 사진을 어안 렌즈로 찍은 사진이라고 믿고 어안 풀이를 따로 만들었는데, 여러 사진으로 재 보니 실은 원근 보정을 거친 사진이었습니다. 시간 제한 없이 재면 나아지던 개선이, 앱처럼 8초에서 끊으면 오히려 나빠진 적도 있었습니다. 이런 시도와 발견을 빠짐없이 적어 두었더니 30개 장이 넘는 기록이 남았고, 이 글도 그 기록을 바탕으로 썼습니다.
2025년의 남은 숙제 세 가지를 하나씩 풀었습니다.
같은 샘플 16장을 사람 손 없이 풀었을 때. 위가 2차 시도, 아래가 3차 시도입니다. 흐리게 처리한 네 장은 네이버 카페 별하늘지기에서 마음에 드는 사진을 골라 개발용 샘플로 쓴 것이라 이 글에서는 가렸습니다.
3차 시도는 어떤 과정을 통해 문제를 해결했을까요?
맞는 답인지 스스로 판단하기
가장 비슷한 지문이 늘 정답은 아닙니다. 그렇다고 "답대로 별 지도를 겹쳤을 때 사진의 별이 지도에 없으면 틀린 답"이라고 하면 곤란합니다. 답이 맞아도 사진에는 지도에 없는 점이 늘 있기 때문입니다. 그래서 Astrometry.net 논문처럼 "이 답이 우연보다 얼마나 그럴듯한지" 를 계산합니다.
- 답대로 별 지도를 사진에 겹칩니다.
- 짝을 찾는 데 쓰지 않은 별이 몇 개나 사진의 별과 겹치는지 셉니다.
- 아무 데나 겹쳤을 때 우연히 겹칠 기대치를 구합니다. 사진 별 60개, 지도 별 168개라면 2.4개쯤입니다.
- 기대치가 2.4개인데 26개가 겹쳤다면, 그게 우연일 확률은 10의 −17.8승입니다.
이 확률이 10억 분의 1보다 낮을 때만 "찾았어요" 라고 말하고, 아니면 "모르겠어요"라고 합니다.
사람이 하던 일을 흉내 내기
사람은 별을 볼 때 그 점의 주변도 봅니다. 진짜 별은 둘레가 고른 밤하늘이고, 창문 불빛은 둘레에 벽과 다른 불빛이 있습니다. 그래서 점마다 둘레 고리의 밝기가 얼마나 고른지를 "별다움"으로 매겨, 별다운 점을 먼저 씁니다.
사람은 사진을 보면 땅부터 가리고 하늘만 봅니다. 그래서 사진 전체로 못 풀면 위쪽 75%, 55%, 45%만 남기고 다시 풀어 봅니다.
1차 시도에서 실패했던 삼각형도 다시 꺼냈습니다. quad는 별 지도의 크기를 줄이려고 네 별이 모두 서로 10도 안에 모인 조합만 만듭니다. 그래서 북두칠성처럼 넓게 퍼진 별자리에서는 만들 수 있는 모양이 적습니다. 삼각형은 별 셋만 있으면 거의 어디서나 만들 수 있지만, 앞에서 본 것처럼 닮은 가짜가 너무 많습니다.
가짜를 줄인 열쇠는 크기였습니다. 사진 속 삼각형은 픽셀 단위라 하늘에서 몇 도짜리인지 모르니, 지금까지는 모양(닮음)만 비교할 수 있었습니다. 그런데 렌즈 화각을 하나 짐작하면 사진 속 삼각형이 하늘에서 몇 도짜리인지 나옵니다. 모양이 가장 닮은 후보 8개를 가져온 뒤, 그 절반에서 두 배 사이 크기가 아닌 것은 확인하지 않고 버립니다. 모양만 닮고 크기는 엉뚱한 가짜를 일일이 확인하지 않아도 되니 그만큼 빨라집니다. 화각은 모르니 10도에서 75도까지 아홉 가지를 모두 짐작해 봅니다. 화각을 틀리게 짐작하면 정답까지 버릴 수 있지만, 아홉 가지 중 하나만 맞으면 됩니다.
그리고 quad와 삼각형을 둘 다 씁니다. 둘은 잘하는 곳이 달라서, 처음에는 서로 못 푸는 사진을 풀었습니다.
| 삼각형 (별 셋) | quad (별 넷) | |
|---|---|---|
| 사진에서 만들 수 있는 진짜 모양 | 304개 | 64개 (10° 안만) |
| 정답보다 더 닮은 가짜 (중간값) | 3,052개 | 1개 |
| 혼자서 푸는 사진 (14장 중) | 14장 | 10장 |
| 걸린 시간 (풀린 사진 중 가장 오래) | 3.3초 | 0.3초 |
quad는 가짜가 거의 없어 빠르게 확신하고, 삼각형은 어디서나 만들 수 있어 끝까지 붙잡습니다. 그래서 quad로 먼저 빠르게 풀어 보고, 못 풀면 삼각형을 씁니다.
2023년 발표를 "컴퓨터를 가르치는 일은 어렵습니다"라는 말로 마무리했는데, 이번에 배운 건 똑똑한 방법보다 사람이 실제로 하는 단순한 일을 하나씩 흉내 내게 하는 쪽이 강하다는 것이었습니다.
주변 별 표시 보정하기
2차 시도는 짝지은 별 3~4개로만 사진과 하늘 사이의 변환을 구했습니다. 그래서 짝지은 별 근처는 맞지만, 멀어질수록 그려 넣은 별자리가 실제 별에서 어긋났습니다. 앞에서 본 2차 시도 화면 ④에서도 북극성 쪽 선이 실제 별에서 벗어나 있습니다.
3차 시도는 답을 찾은 뒤, 사진의 별과 겹친 별 전부로 변환을 다시 맞춥니다. 겹친 별이 8개 이상이면, 사진을 비스듬히 찍어서 생기는 사다리꼴 모양의 일그러짐까지 맞추는 원근 변환으로 한 번 더 다듬습니다.
배포 준비
2차 시도를 배포하지 못한 이유는 네 가지였습니다.
- 정확도: 아무 사진이나 기대만큼 풀지 못했고, 찾은 답이 맞는지 판정하지 못했습니다.
- 속도: 후보 목록이 나오기까지 사진 한 장에 4초쯤 걸렸습니다. 거의 다 65MB짜리 패턴 DB를 펼쳐 검색 나무를 쌓는 시간이었습니다.
- 용량: 사진 한 장을 풀 때까지 28MB를 받아야 해서 서버 비용이 걱정됐습니다.
- 편의성: 사람이 별 표시를 고쳐 줘야 풀렸습니다. 저는 어떤 점을 지울지 알지만, 처음 온 사람은 모릅니다.
정확도와 편의성은 앞에서 풀었습니다. 틀린 답은 "모르면 모른다고 하기"로 걸러 내고, 별 고르기는 사람이 하던 일을 흉내 내 사람 손 없이 하게 했습니다. 속도는 확신하면 바로 멈추게 했습니다. 준비는 사진을 고르는 동안 미리 해 두고(0.75초), 풀이는 중앙값 0.13초, 가장 오래 걸린 사진도 3.9초입니다. 못 푸는 사진은 8초에서 끊습니다.
남은 건 용량이었습니다. 받는 양을 재 보니 패턴 DB가 22MB, 이미지 처리 라이브러리 OpenCV.js가 3.9MB, 그리고 의외로 글꼴이 2MB였습니다.
- OpenCV.js 빼기: OpenCV가 하던 일은 흑백, 흐리기, 빼기, 밝은 점 고르기였습니다. 직접 짜니 120줄 남짓이었고, 속도도 거의 같았습니다(같은 사진에서 0.16초 대 0.15초). 그런데 이걸 위해 3.9MB를 받고 있었습니다.
- 글꼴은 쓰인 글자만: 글꼴 파일 하나에 한글 1만 1천여 자가 다 들어 있었습니다. 글자를 92조각으로 나눠 두고 화면에 쓰인 글자가 든 조각만 받게 해서 0.31MB가 됐습니다.
- 패턴 DB는 받지 말고 만들기: 패턴 DB는 별 위치와 규칙(하늘을 같은 넓이 192칸으로 나누기)만 있으면 언제든 똑같이 만들어집니다. 그래서 받지 않고, 사진을 고르는 동안 브라우저가 맨눈에 보이는 별 1,624개로 0.75초 만에 만듭니다.
2차 시도에서는 별 사진 한 장을 풀려면 약 28MB를 내려받아야 했습니다. 이미지 처리 라이브러리(OpenCV.js)를 빼고, 글꼴은 쓰인 글자만 받고, 패턴 DB는 받지 않고 브라우저가 만들게 해서 0.68MB, 40분의 1이 됐습니다.
중립적으로 검증하기
샘플 16장은 개발하면서 수없이 돌려 본 사진입니다. 샘플만 통과하도록 맞춰진 것은 아닌지 확인하기 위해, 개발하면서 한 번도 본 적 없는 사진으로 따로 검증했습니다.
- 사진: 위키미디어 공용에서 고른 밤하늘 사진 200장입니다. 오로라, 은하수, 별자리, 땅과 건물이 함께 찍힌 사진에 더해, 달빛·박명·별 궤적·망원·휴대폰으로 찍은 사진처럼 어려운 조건을 일부러 91장 넣었습니다. 성운을 확대한 망원경 사진이나 별자리 선을 그려 넣은 사진은 뺐습니다.
- 조건: 앱과 똑같이 사진 한 장에 8초 상한을 두고 돌렸습니다.
- 판정: 풀이가 "찾았어요"라고 해도 그대로 믿지 않았습니다. 정답을 아는 샘플로 판정 기준을 먼저 맞춘 뒤, 확신한 사진마다 별자리 선을 사진 위에 그려 눈으로도 하나하나 확인했습니다.
결과는 200장 중 102장을 확신했고, 확신한 102장은 모두 맞았습니다. 틀린 답을 확신한 사진은 한 장도 없었습니다. 확신한 사진의 풀이 시간은 중앙값 0.09초였고, 102장 중 76장이 1초 안에 끝났습니다. 못 푼 사진에는 별이 점이 아니라 선으로 찍힌 별 궤적 사진(10장 중 0장)이나, 하늘 전체를 동그랗게 담은 어안 사진처럼 아직 다루지 못하는 조건이 몰려 있었습니다.
개발하면서 한 번도 본 적 없는 인터넷 밤하늘 사진 200장. 8초 안에 102장을 확신했고, 틀린 답을 확신한 사진은 0장입니다.
성공률은 50% 근처라 아직 개선할 점이 남아 있지만, 모르면 모른다고 하고 틀린 답은 내지 않으니, 일단 공개할 수 있는 수준의 도구라는 것을 확인했습니다.
결과
처음 발단이 되었던 2019년의 그 사이판 사진을 이제는 풀 수 있습니다.
2019년에 손으로 찾았던 알파 센타우리가 그려져 있습니다.
7년의 꿈을 AI가 드디어 이루어주는 순간입니다.
함께 만들며 배운 것
AI는 저보다 개발을 잘합니다. 지난 3년 동안 붙잡고도 원인을 알지 못했던 문제들을, 이번에는 AI가 여러 사진으로 재고 기록하며 하나씩 풀어 나갔습니다.
제가 코드 한 줄 한 줄을 직접 작성한 것은 아니지만, 무언가를 만드는 일은 여전히 재미있었습니다. 생각이 빠르게 구현되어 눈으로 보이니 짧은 기간 집중해서 만들 수 있었고, 몰입감과 만족도도 높았습니다.
일을 맡겨 두고 저는 다른 일을 할 수 있다는 것도 좋았습니다. AI가 만드는 동안 회사 일이나 개인 일을 보고, 가끔은 게임을 하다가 결과만 확인하면 됐습니다. 그래서 따로 시간을 크게 내지 않고도 다른 일과 병행하며 꾸준히 진행할 수 있었습니다.
다만 직접 만들지 않다 보니, 코드에 대한 애정은 예전보다 조금 덜한 것 같습니다. 그리고 이제는 누구나 AI로 이 정도는 쉽게 만들 수 있으니, 제가 무언가 특별한 것을 했다는 생각은 들지 않습니다.
한편, 발표 자료와 이 글처럼 사람에게 전하는 일은 여전히 하나하나 살펴보고 고쳐야 했습니다.
7. 직접 써 보기
아래에서 직접 Plate Solving을 체험해 보실 수 있고, star.byb.kr에서 해 보실 수도 있습니다.
더 즐길 거리
하다 보니 하늘을 계산하는 코드가 쌓여서, 배울 거리와 놀 거리도 만들었습니다.
배울 거리
- 찾는 원리: 이 글에서 다룬 풀이 과정(별 지도 준비, 별 찾기, 모양 맞추기, 확인하기, 어려운 사진들)을 직접 움직여 보는 데모와 함께 단계별로 정리했습니다.
- 하늘 읽기 기초: 하늘의 좌표, 하루가 4분씩 어긋나는 이유, 주먹 하나가 10도라는 걸로 별을 건너뛰어 찾는 스타 호핑, 옛 선원들이 별로 위치를 찾던 방법 등 9가지 개념을 담았습니다.
- 별자리 익히기: 도감을 모으고, 카드로 별자리 모양을 익히고, 실제 하늘에서 별 사이 길을 찾아가 봅니다.
놀 거리
별 놀이터에 게임 12개와 둘러보기 7개가 있습니다.
- 하늘 맞추기: 위도·날짜·시각 다이얼을 돌려 사진 속 하늘을 만듭니다. 사람이 하는 Plate Solving입니다.
- SkyGuessr: 밤하늘을 둘러보고, 지구 어디서 찍었는지 세계 지도에 핀을 찍습니다.
- 사람 계산원 vs 컴퓨터: 사진 속 별자리를 누가 먼저 찾을까요? 나는 눈으로, 컴퓨터는 Plate Solver로 겨룹니다.
- 별자리 숨은그림찾기: 밤하늘에서 제시한 별자리를 찾아 누릅니다. 아래에서 바로 해 보세요.
더 많은 콘텐츠는 별 놀이터에서 찾아보세요.
8. 남은 숙제
2022년에 처음 세운 목표는 소박했습니다. PoC 수준으로, 밝은 별만으로, 땅이나 구름이 찍혀도, 안 되면 사진 한두 장만이라도. 4년이 걸려 다 이뤘고, 사진 한두 장이 아니라 개발에 쓰던 샘플 16장 중 15장이 풀렸습니다.
아직 할 일도 남았습니다. 어안 렌즈와 별 궤적 사진, 별이 10개 남짓인 사진을 시각·장소 없이 푸는 것, 휴대폰에서 얼마나 걸리는지 재는 것입니다.
휴대폰에 밤하늘 사진이 있다면 star.byb.kr에 올려 보세요. 안 풀리는 사진이 있으면 알려 주세요. 다음 개선의 재료가 됩니다.
코드: github.com/ybbarng/star.byb.kr
9. 버즈빌이라서 가능했던 것
Plate Solver는 개인 프로젝트이지만, 버즈빌이 아니었다면 여기까지 오지 못했을 겁니다.
- AI를 적극적으로 쓰는 회사: 버즈빌은 AI 네이티브 조직으로 바뀌어 가고 있습니다. 3차 시도처럼 코드를 직접 쓰지 않고 AI와 함께 만드는 방식이 회사 일에서도 자리 잡았고, 개발자가 아닌 동료들도 사내 AI 해커톤에서 직접 AI로 무언가를 만들어 냈습니다. (그놈의 AI, 결국 같이 일하게 됐습니다)
- 성장과 꿈을 응원하는 버즈챌린지: 분기마다 각자 목표를 세워 도전하고, 회사가 그 도전을 응원합니다. 이 프로젝트의 1차 시도도 버즈챌린지의 드림챌린지로 시작했습니다.
- 리프레시를 위한 버즈홀리데이: 3년을 함께하면 2주간의 유급 휴가를 줍니다. 저는 이 휴가로 캐나다 옐로나이프에 오로라를 보러 다녀왔고, 이 글 처음에 나온 오로라 사진도 그때 찍은 사진입니다. (버즈빌리언이 리프레시 하는 방법, 버즈홀리데이)
🚀 AI 네이티브 기업 버즈빌에서 함께 별을 찾고, 커리어를 쌓아 가고 싶다면?
>> 지금 바로 채용 공고 확인하기 (클릭)
참고 자료
논문
- Lang, D., Hogg, D. W., Mierle, K., Blanton, M., & Roweis, S. (2010). Astrometry.net: Blind astrometric calibration of arbitrary astronomical images. The Astronomical Journal, 139(5), 1782–1800. arXiv:0910.2233 — quad 지문, 우연일 확률로 판정하기
- Górski, K. M., et al. (2005). HEALPix: A Framework for High-Resolution Discretization and Fast Analysis of Data Distributed on the Sphere. The Astrophysical Journal, 622(2), 759–771. arXiv:astro-ph/0409513 — 하늘을 같은 넓이 칸으로 나누기
- Bentley, J. L. (1975). Multidimensional binary search trees used for associative searching. Communications of the ACM, 18(9), 509–517. — KD-tree
데이터
- Hoffleit, D., & Warren, W. H. Jr. (1991). The Bright Star Catalogue, 5th Revised Edition. VizieR V/50 — 별 목록
- Olaf Frohn, d3-celestial (BSD 라이선스) — 별자리선과 별자리 경계(IAU)
해·달·행성 계산
- Meeus, J. (1998). Astronomical Algorithms (2nd ed.). Willmann-Bell. — 항성시 등 계산 확인
- The Astronomical Almanac의 해·달 저정밀 공식
- Standish, E. M. Keplerian Elements for Approximate Positions of the Major Planets. JPL. — 행성 위치
- JPL Horizons — 계산 결과 확인
사진
-
동료들이 찍은 밤하늘 사진: 사이판(Jarrod), 누각(Berry), 오로라(Carl), 호주·정선(Nike)
-
도입부와 대표 이미지의 오로라 사진, 별자리 앱(Constellation Map) 화면: 글쓴이
-
사진 건판: 하버드 천문대(Harvard College Observatory)의 사진 건판 중 윌리아미나 플레밍이 1888년 말머리 성운을 찾아낸 부분
-
말머리 성운: ESO (eso1839i), CC BY 4.0 — 위키미디어 공용 File:Nebulosa testa di cavallo con SPECULOOS.jpg
-
개발 초기 샘플 사진 중 일부는 네이버 카페 별하늘지기에서 마음에 드는 사진을 골라 썼습니다. 이 글에서는 흐리게 처리했습니다.
-
지금 사이트 샘플 중 12장은 위키미디어 공용의 자유 이용 사진(퍼블릭 도메인·CC0·CC BY)입니다. 작가와 라이선스는 사이트의 출처와 참고 자료에 있습니다.


