이전 포스트에서는 수집된 시계열 데이터를 그래프로 시각화 시키는 것 까지 작업을 해보았습니다.
작업을 마무리하며 작성해두기도 했지만, 단순히 흐름표를 보는 것 보다 더 많은 정보를 제공하여 단순 측정기를 넘어선 분석기에 가까운 프로그램을 만들어보려 합니다.
블로그 유입 키워드를 보면 "남던 시간당 경험치"와 같은 특정 사냥터에 대한 기준을 찾는 경우가 많습니다.
메이플을 해보았다면 아시겠지만, 다른 사람이 측정한 기대값을 내 캐릭터에 그대로 적용하긴 어렵죠, 따라서 내가 직접 측정을 해 보는것이 나에게 가장 알맞는 사냥터를 찾는 적절한 방법으로 사료됩니다.
제가 만든 이 경험치 측정기를 사용하여 여러 사냥터를 직접 사냥해보고, 딱 보기에도 가장 성과가 좋아보이는 곳을 찾아가게 만들면 되는 것입니다.
참고로 이번 편에서는 코드 스니펫을 최소화하여 글을 작성해보겠습니다.
이전 포스트에는 코드가 너무 많아 파이썬에 익숙하지 않은 경우 높은 피로도를 유발할 것 같더라구요 ㅎㅎ
장소 데이터 수집하기
이번엔 경험치 데이터와 관련 없는, "장소"에 대한 히스토리 데이터가 필요합니다.
캐릭터가 존재하는 맵의 이름을 수집하고, 이미 수집중인 경험치 시계열 데이터와 시간을 대조하면 "사냥터에 대한 경험치 효율"을 바로 측정할 수 있게되는거죠.
적절한 기술 찾기
경험치 수집 방법과 동일하게 OCR 프로그램을 통해 맵 이름을 가져오려 해보았습니다.
아쉽게도 테서렉트에서는 메이플스토리의 한글 폰트를 전혀 인식하지 못하였습니다.
얼추 비슷하게라도 읽어낸다면 맵 아이콘이나, 대륙 이름 등을 함께 매칭시켜 찾아내어볼 법 하나 아쉽게도 한 글자도 읽지 못하였습니다.....
OCR 모델을 훈련시켜 정확도를 올리는 방법도 있습니다만, 이번에는 OCR이 아닌 OpenCV를 통해 이미지 유사율을 측정하는 방식으로 진행해보려 합니다.
맵 이름을 찾는 방법
OpenCV로는 이미지에 적힌 텍스트를 온전히 추출할 방법이 없습니다. 사용자 입장에서는 남쪽던전1, 구름공원6 등, 사람이 이해할 수 있는 텍스트를 함께 노출 시켜야 처음 기대했던 분석기의 역할을 해낼 수 있을 것이구요.
어쩔 수 없이 이용자가 라벨링을 돕는 방법으로 프로세스를 설계했습니다.
프로세스는 크게 2개의 독립적인 시퀀스로 진행 가능합니다.
(1) 라벨링하기.
메이플랜드의 미니맵의 대부분의 경우 특정 위치를 타겟했을때 맵 이름을 캡쳐 뜰 수 있습니다.
이 캡쳐본을 GUI에 보여주고, 텍스트박스를 함께 제공합니다. 등록되지 않은 맵인 경우 유저가 맵 이름을 직접 입력하고 Submit하면 해당 이미지가 DB역할을 하는 디렉토리에 저장됩니다.
내가 자주 사냥하는 곳만 위치 정보를 등록하게되면 매칭되는 이미지를 찾아야하는 모수가 줄어들게됩니다.
욕심내어 모든 맵 디비를 가지고 있을 필요가 없겠더군요.
(특히 저는 클레릭이라 더욱.....)
(2) 위치 정보 기록하기.
N초마다 정확한 맵 이름을 찾는 Job이 실행되게 세팅되어있습니다. 이 작업에서는 (1)에서 캡쳐한 이미지를 DB 디렉토리에 있는 모든 png파일과 대조하여 100% 일치하는 파일을 찾습니다.
일치하는 파일이 있는 경우 해당 위치 정보를 DB에 시간 정보와 함께 기록합니다.
여기까지 작업을 마치면 시간 흐름에 따른 위치 정보까지 적재하는데 성공한 것입니다.
이제 그래프에 위치 데이터를 적절히 융합시키면 됩니다.
그래프에 위치 정보 보여주기
matplotlib의 어떤 기능을 활용할까 고민하다가 axvspan이라는 기능을 활용해 원하는 시간대의 영역을 색깔로 표시하고
Vspan에 Annotation을 달아 위치에 대한 힌트를 제공하면 될 것 같습니다.
제 그래프의 경우 X축이 시간 정보를 담고 있기에 axvspan를 만들 때에도, 영역의 시작~종료 시간을 정확하게 입력해준다면 원하는 대로 Span을 만들 수 있습니다.
ax.axvspan(start_date, end_date, color="#ccc", alpha=0.5)
x_start = ax.xaxis.convert_units(start_date)
ax.annotate(location["name"], xy=(x_start, 0),
xytext=(x_start, 20), rotation=270,
fontsize=8, horizontalalignment='center',
verticalalignment='bottom')
처음엔 욕심을 내어 내가 자주 사냥하는 몬스터의 이미지를 미리 준비시키고, 몬스터 아이콘과 맵 정보를 보여줄까 했으나..... 아직은 그 만큼 UI에 집중할 필요는 없을 것 같아
위치 텍스트를 270% 회전시켜 이름을 보여주는 것으로 만족하려 합니다.
예외처리하기
모든 위치 정보를 그래프에 보여주면 너무 많은 Span이 생성되어 난잡해보일 수 있습니다.
예를 들어, 특정 지역으로 이동할 때 까지 몬스터를 잡으며 진행하는 경우 단시간 내에 많은 사냥터 정보가 포함되어있기 때문입니다.
기준을 몇가지 정하여 그래프에 보여질 Span 정보를 선별하기로 했습니다.
- 연속된 데이터가 60초 이하인 경우 무시한다.
- 이미지 인식/매칭에 일시적으로 실패했을 경우를 감안해 10초의 공백은 허용한다.
- 동일한 맵에 대한 연속 데이터일 경우라도 120초 이상 공백이 있는 경우 Span을 분리한다.
아쉬운점
CV를 더 잘 활용한다면 해결될 이슈이긴하나, 모든 메이플스토리 미니맵이 동일한 크기를 가지지 않습니다.
지금의 코드는 고정된 X/Y 좌표, Width+Height 크기값을 미리 세팅해 둔 상태이기 때문에 맵이 너무 작은 경우 배경이 함께 보이는 바람에 CV가 인식할 수가 없습니다.
또한, 맵 이동시 캡쳐에 검은 화면이 잡힐 때가 있는데, 아무런 맵 정보와 일치하지 않길 기대하나 "노란빛의 정원1"이 매칭되었다고 뜨는 바람에 쓰레기 데이터가 쌓일 때가 있습니다.
CV를 잘 쓰다보면 좋은 날이 오겠죠...?
데모
개인적으로 측정기의 발전 속도나 퀄리티에 대해 크게 만족하고 있습니다.
아쉬운 점이라면, 그래프에서 보여지는 정보가 재미있고 유익하다보니 상단의 텍스트형 정보를 전혀 확인하지 않는다는 것입니다.
지금 퀘스트를 깨고 다니고 있어서 그런 것일 지도요?
다음 업데이트에선 무엇을 개선해볼까요?
TMI
스톤볼을 잡다가 망토 지력 60% 주문서를 득했습니다. 맙소사.
'게임 > 메이플랜드' 카테고리의 다른 글
메이플랜드 경험치 측정을 자동으로 해보자! (남던 경험치 비교) (26) | 2024.03.02 |
---|---|
메이플랜드 매크로 보다 나은 경험치 측정기 - 데이터 시각화 (38) | 2024.02.09 |
메이플랜드 경험치 측청기,분석기 만들기 - 인사이트 보여주기 (60) | 2024.01.21 |
메이플랜드 경험치 측청기,분석기 만들기 - 시계열 데이터 쌓기 (56) | 2024.01.21 |
메이플랜드 경험치 측정기, 분석기 만들기 - 개발 컨셉 증명하기 (54) | 2024.01.20 |