스도쿠 사진 인식기를 측정하며 알게 된 것
2026년 11월 5일 업데이트
정확히 읽었다는 기준
81칸이 모두 맞아야만 퍼즐을 제대로 읽은 것으로 봅니다. 숫자 하나만 틀려도 다른 퍼즐이 되기 때문입니다. 그래서 칸이 아니라 퍼즐 전체를 단위로 셉니다. 이 페이지에서 보듯 두 기준은 전혀 다른 이야기를 할 수 있습니다. 인쇄 퍼즐 사진에서 인식기는 이제 칸의 98.9%를 맞히지만, 퍼즐 전체를 맞힌 비율은 거의 움직이지 않았습니다. 틀린 칸 대부분이 몇 장의 어려운 사진에 몰려 있기 때문입니다.
가장 위험한 실수도 따로 셉니다. 잘못 읽었는데도 답이 정확히 하나인 퍼즐입니다. 진짜 스도쿠는 답이 하나뿐이므로, 답이 없거나 여러 개인 결과는 바로 걸러집니다. 반면 답이 하나인 잘못된 퍼즐은 멀쩡해 보입니다. 그래서 풀이기는 확신하지 못한 칸을 모두 표시하고, 풀기 전에 그 칸들을 실제 퍼즐과 비교해 보라고 안내합니다.
사진이 200장이면 결과의 정밀도에는 한계가 있습니다. 주요 결과에는 95% 범위(윌슨 구간)를 함께 적었습니다. 200장 중 89.5%라는 결과는 실제 비율이 높은 확률로 84.5%에서 93.0% 사이에 있다는 뜻입니다.
테스트에 쓴 사진
두 개의 공개 데이터셋에서 시작했습니다. Lexski의 Sudoku Image Recognition 데이터셋(CC0)에는 사진 1,400장이 있으며, 대부분은 사람들이 온라인에 공유한 스크린숏과 사진입니다. 온갖 스타일의 앱, 다크 테마, 연필 메모, 종이에 절반쯤 푼 퍼즐까지 들어 있습니다. 바티스트 비흐트(Baptiste Wicht)와 장 엔베르(Jean Hennebert)의 데이터셋(CC BY 4.0)에는 휴대전화로 찍은 신문 스도쿠가 들어 있으며, 그중 일부는 펜으로 끝까지 푼 것입니다.
아무것도 바꾸기 전에 테스트 세트 세 개를 따로 떼어 두었습니다. Lexski 사진 200장, 신문 사진 40장, 손으로 끝까지 푼 신문 퍼즐 40개입니다. 작업하는 동안 이 사진들로 학습하지도 않았고 들여다보지도 않았습니다. 모든 결정은 다른 Lexski 사진 200장, 즉 조정 세트를 기준으로 내렸고, 테스트 세트는 마지막에 한 번만 읽었습니다.
출발점
10월 31일의 첫 버전은 Lexski 사진 200장 중 101장, 신문 사진 40장 중 34장을 정확히 읽었고, 끝까지 푼 퍼즐 40개는 하나도 정확히 읽지 못했습니다. 문제의 대부분은 숫자를 읽기 이전 단계에서 생겼습니다. 첫 버전은 잉크로 된 가장 큰 사각형 비슷한 모양을 판으로 여겼는데, 스크린숏에서는 이 모양이 상단 헤더나 숫자 패드까지 포함하는 경우가 많았고, 다크 테마의 가는 회색 선은 아예 놓쳤습니다. 조정 세트에서 격자를 올바른 위치에 잡은 것은 200장 중 118장뿐이었습니다.
단계별 변경 내용
각 행은 변경 하나를 나타내며, 숫자는 그 변경 후 조정 사진 200장 중 정확히 읽은 사진의 수입니다. 마지막 세 행은 2차 작업입니다.
| 변경 내용 | 정확히 읽은 조정 사진(200장 중) |
|---|---|
| 첫 버전, 10월 31일 | 99 |
| 선으로 격자 찾기: 가로세로 각각 등간격 선 10개 | 129 |
| 격자 후보를 나란히 비교, 한 칸 어긋남도 시도 | 136 |
| 흐린 가는 선도 격자 찾기에 사용 | 138 |
| 칸을 통째로 잘라 냄, 실제 칸으로 숫자 학습 | 161 |
| 작은 신경망이 판의 위치를 그려 냄 | 162 |
| 페이지가 휘는 곳에서 선을 따라감 | 163 |
| 더 나은 숫자 신경망, 연필 메모를 별도 클래스로 | 173 |
| 숫자 신경망 세 개의 평균 | 177 |
| 신중한 단일 해 규칙, 완성된 판은 통째로 읽기 | 177 |
| 2차: 원본 크기 사진을 축소 전에 절반씩 줄임 | 178 |
| 2차: 짧고 흐린 잉크는 연필 메모로 처리 | 179 |
| 2차: 옆으로 찍힌 사진은 신경망 세 개 모두가 판정 | 179 |
개선의 대부분은 세 가지 변경에서 나왔습니다. 첫째, 이제 격자는 선을 기준으로 찾습니다. 판의 위치에 대한 모든 추정을 가로세로 각 방향으로 등간격 선 10개에 맞춰 옮긴 뒤 나란히 놓고 평가하며, 판이 어디 있는지 그려 내는 작은 신경망도 한 표를 행사합니다. 둘째, 각 칸을 통째로 잘라 내므로 연필 메모는 칸 모서리에 작게 남고, 어두운 타일 위의 밝은 숫자는 종이 위 잉크처럼 보입니다. 셋째, 숫자 인식 신경망은 Lexski 학습용 사진에서 잘라 낸 실제 칸으로 학습했고, 연필 메모를 별도의 클래스로 두었습니다. 이제 따로 학습시킨 작은 신경망 세 개가 각 칸을 읽고 그 답을 평균합니다. 세 신경망이 서로 다른 칸에서 실수하기 때문입니다.
끝까지 푼 퍼즐은 추가로 도움을 받습니다. 판에 숫자가 79개 이상 있으면, 인식기는 모든 행, 열, 박스에 1부터 9까지가 들어가는 완성 격자 가운데 가장 그럴듯한 것을 찾습니다. 칸별로 읽었을 때는 손글씨 테스트 퍼즐 40개 중 7개만 정확히 나왔지만, 완성된 스도쿠로 읽었을 때는 40개 모두 정확히 나왔습니다.
2차 작업에서는 더 작은 변경 세 가지를 추가했습니다. 휴대전화로 찍은 원본 크기 사진은 축소하기 전에 단계적으로 절반씩 줄이므로, 가는 선과 연필 획이 건너뛰어지지 않고 평균에 반영됩니다. 잉크가 판의 확실한 숫자들보다 훨씬 짧으면서 훨씬 흐린 칸은 연필 메모일 가능성이 높은 것으로 처리합니다. 그리고 옆으로 찍힌 사진의 회전 방향은 신경망 하나가 아니라 세 개 모두가 판정합니다.

도움이 되지 않은 것
다음 시도들도 조정 세트에서 측정했으며, 결국 넣지 않았습니다:
- 더 큰 숫자 신경망: 가중치를 42,000개 대신 59,000개로 하자 조정 사진을 한 장 더 읽었지만, 브라우저에서 3.8배 느리게 실행되었습니다.
- 연필 메모와 다크 테마를 넣어 생성한 앱 스크린숏 3,000장: 넣든 빼든 점수가 같았습니다.
- 빨간 펜도 검은 잉크만큼 진하게 보이도록 회색조 대신 컬러로 읽기: 조정 사진은 두 장 더 읽었지만 손글씨 인식은 나빠졌습니다.
- 학습용 숫자를 손글씨처럼 보이도록 변형하기: 손글씨 인식이 나빠졌습니다.
- 답이 하나라는 규칙이 더 많은 칸을 바꾸도록 허용하기: 정확히 읽은 퍼즐은 늘었지만, 답이 하나인 위험한 오독 퍼즐도 늘었습니다.
- 세 신경망을 새 데이터로 다시 학습시키거나 네 개 또는 여섯 개를 쓰기: 차이가 잡음 수준이라 처음 것들을 그대로 두었습니다.
- 프레임에 잘린 판을 위해 사진 가장자리를 판 가장자리로 취급하기: 새로 맞힌 사진만큼 놓친 사진도 생겼습니다.
첫 테스트 세트 결과
각 테스트 세트에서 첫 버전과 현재 인식기가 정확히 읽은 퍼즐 수:
| 테스트 세트 | 10월 31일 | 현재 |
|---|---|---|
| 온라인에 공유된 스크린숏과 사진(Lexski)사진 수: 200 | 10150.5% | 17989.5% |
| 신문 사진(Wicht와 Hennebert)사진 수: 40 | 3485.0% | 40100.0% |
| 손으로 끝까지 푼 신문 퍼즐(Wicht와 Hennebert)사진 수: 40 | 00.0% | 40100.0% |
Lexski 사진에서 인식기는 50.5%에서 89.5%(84.5%~93.0%)로 올랐고, 잘못 읽었는데도 답이 하나인 퍼즐은 7개에서 4개로 줄었습니다. 그 네 개 중 세 개는 추가로 들어간 숫자 하나가 원래 그 자리에 들어갈 숫자여서, 퍼즐이 여전히 올바른 해답으로 이어집니다. 네 번째는 또렷하게 인쇄된 1인데 데이터셋에서는 빈칸으로 되어 있습니다. 179장 중 177장은 1차 작업이 끝났을 때 이미 맞혔습니다. 나머지 두 장은 실패 사례를 살펴본 뒤 2차 작업에서 맞힌 것이므로, 이 세트는 더 이상 손대지 않은 세트가 아닙니다.
40개 중 40개라고 하면 완벽하게 들리지만, 사진 40장으로는 실제 비율이 약 91%보다 높다는 것까지만 보여 줄 수 있습니다. 또 먼저 했어야 할 점검을 해 보니, 신문 테스트 사진 40장 중 4장은 해당 데이터셋의 학습 세트에도 들어 있었고, 그중 2장은 픽셀 단위까지 똑같았습니다. 이들을 빼면 36개 중 36개입니다.
새 테스트: 어느 버전도 본 적 없는 사진 200장
그 무렵 첫 테스트 세트는 이미 읽혔고 실패 사례도 분석된 상태라, 인식기가 처음 보는 사진에서 어떤 성능을 내는지 더는 알려 줄 수 없었습니다. 그래서 Hugging Face, Kaggle, GitHub, Zenodo, Figshare, AIcrowd에서 라벨이 붙은 스도쿠 사진을 더 찾았습니다. 대부분은 생성된 판, 숫자 하나짜리 이미지, 또는 Wicht 사진의 사본이었습니다. GitHub의 컬렉션 세 개에 라벨이 붙은 실제 사진이 있었고, 모두 인쇄 퍼즐이었습니다. 공개 퍼즐 책을 찍은 사진 100장(NatalijaPetric/SudokuDataset), 주로 신문을 찍은 사진 80장(mineshpatel1/sudoku-solver, Wicht 본인의 사진 49장과 사본 1장을 뺀 수), 부쿠레슈티 대학교 컴퓨터 비전 강의 프로젝트에서 나온 인쇄물 20장(danielsociu/SudokuRecognition)입니다.
세 곳 모두 라이선스를 밝히지 않았기 때문에 측정에만 사용했습니다. 학습에는 전혀 쓰지 않았고, 여기에도 싣지 않았습니다. 사진 목록은 어떤 변경도 하기 전에 파일 해시와 라벨에 따른 규칙으로 정해 저장해 두었고, 2차 작업의 마지막 변경 전까지는 사진을 열어 보지 않았습니다. 그 뒤 인식기의 각 버전이 사진을 한 번씩 읽었습니다. 표는 정확히 읽은 퍼즐 수입니다.
| 출처 | 10월 31일 | 1차 | 현재 |
|---|---|---|---|
| 공개 퍼즐 책(NatalijaPetric)사진 수: 100 | 7979.0% | 7676.0% | 7878.0% |
| 주로 신문(mineshpatel1)사진 수: 80 | 6581.3% | 6885.0% | 6986.3% |
| 인쇄물(부쿠레슈티 대학교 강의)사진 수: 20 | 20100.0% | 20100.0% | 20100.0% |
| 전체 200장사진 수: 200 | 16482.0% | 16482.0% | 16783.5% |
인식기가 처음 보는 인쇄 퍼즐에서는 두 차례에 걸친 작업 전체로도 결과가 별로 달라지지 않았습니다. 첫 버전은 82.0%를 정확히 읽었고, 현재 버전은 83.5%(77.7%~88.0%)를 정확히 읽습니다. 14개를 새로 맞혔고 11개를 놓치게 되었습니다. 나아진 것은 칸 단위입니다. 칸을 맞힌 비율이 94.2%에서 98.9%로 올랐고, 격자는 200장 중 195장이 아니라 모든 사진에서 찾습니다. 잘못 읽었는데도 답이 하나인 퍼즐은 당시 5개, 지금은 6개입니다.
이렇게 놓친 데에는 분명한 원인이 있습니다. 연필 메모와 다크 테마를 읽기 위해 이제 각 칸을 통째로 잘라 내고 흐린 잉크도 셉니다. 얇은 신문지에서는 뒷면이 흐릿하게, 좌우가 뒤집힌 채 비쳐 보이는데, 새 인식기는 이 그림자를 숫자로 읽습니다. 첫 버전은 칸 안에서 가장 큰 잉크 모양만 보았기 때문에 이런 그림자를 전혀 보지 못했습니다. 휘어진 책 페이지에서는 판의 바깥 선이나 박스 선이 칸 안으로 들어와 1로 읽힐 수 있습니다.
놓친 것 중 두 개는 라벨 오류입니다. 사진에는 3과 9가 있는데 라벨에는 9와 8로, 4가 있는데 라벨에는 2로 적혀 있습니다. 이를 바로잡아 세면 현재 인식기는 84.5%를 정확히 읽습니다.
아직 틀리는 것
새 사진 200장 중 33장은 정확히 읽지 못했습니다. 22장은 공개 퍼즐 책의 페이지입니다. 책등 근처에서는 페이지가 인식기가 따라갈 수 있는 것보다 더 많이 휘어서, 선이 칸 안에 들어와 1로 읽히거나 모서리 칸이 선에 걸쳐 잘립니다. 7장은 뒷면이 비쳐 보이는 신문입니다. 나머지는 모아레가 생긴 화면 사진, 1로 읽힌 판 가장자리, 그리고 앞서 말한 라벨 오류 두 건입니다.
Lexski 사진 200장 중 21장은 정확히 읽지 못했습니다. 연필 메모를 숫자로 읽은 경우가 7장이며, 지운 연필 자국이 흐린 숫자를 남긴 경우도 여기에 포함됩니다. 숫자가 하나 더 들어간 경우가 5장이며, 대부분 홀로 있는 연필 메모를 입력된 숫자로 읽은 것입니다. 격자를 잘못된 위치에서 찾거나 아예 찾지 못한 경우가 5장이며, 칸 사이에 선이 없는 앱 테마나 손으로 그린 격자였습니다. 특이한 타일과 색상이 4장입니다.
97%에 이르지 못한 이유와 다음 단계
모든 처리는 브라우저 안에서 이루어집니다. 모델은 224KB, JavaScript는 약 850줄이며, 노트북에서 사진 한 장당 처리 시간의 중앙값은 약 300밀리초이고, 느린 휴대전화처럼 프로세서를 4배 느리게 하면 약 1.2초입니다. 이 예산 안에서는 더 큰 신경망이 도움이 되지 않았습니다. 남은 것은 긴 꼬리입니다. 휘어진 페이지, 뒷면 비침, 연필 메모, 특이한 앱 스타일입니다. 저희가 찾은 공개 라벨 데이터셋은 이제 모두 사용했거나 이미 본 것이므로, 다음 단계에는 저희가 직접 찍고 라벨을 붙인 사진이 필요하며, 흐린 잉크와 휘어진 페이지 문제를 고친 뒤 그 사진들로 측정해야 합니다.
가장 잘 스캔하려면
- 휴대전화를 퍼즐 바로 위에서 똑바로 들고, 격자 전체가 화면에 들어오게 하세요.
- 책이나 신문은 평평하게 펴세요. 인쇄 퍼즐에서 놓치는 경우 대부분은 휘어진 페이지 때문입니다.
- 얇은 신문이라면 페이지 뒤에 무지 종이를 한 장 대어 뒷면이 비치지 않게 하세요.
- 퍼즐에 연필 메모를 쓰기 전에 스캔하세요.
- 풀기 전에 풀이기가 표시한 칸을 실제 퍼즐과 비교하세요.
데이터 및 출처
- Lexski, Sudoku Image Recognition (Hugging Face), CC0 1.0
- Wicht, B. and Hennebert, J., Sudoku dataset (GitHub), CC BY 4.0; "Camera-based Sudoku recognition with deep belief network", SoCPaR 2014
- NatalijaPetric, SudokuDataset (GitHub), 라이선스 명시 없음, 측정용으로만 사용
- mineshpatel1, sudoku-solver (GitHub), 라이선스 명시 없음, 측정용으로만 사용
- danielsociu, SudokuRecognition (GitHub), University of Bucharest course project, 라이선스 명시 없음, 측정용으로만 사용
- 솔버가 사진을 읽는 과정 단계별로 보기 (English)