이 글은 Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle에 제출한 내용입니다.
문제점 (The Problem)
작년으로 돌아가, 저희는 BGBO(대학 수준의 BGMI 토너먼트)를 주최했습니다. 이때 한 가지 문제가 발생했는데, 최종 점수표를 작성하는 데 너무 많은 시간이 소요되어 시청자들의 분위기를 망쳤습니다. 그들은 가장 좋아하는 팀이 우승했는지 확인하기 위해 결과를 최대한 빨리 원했습니다. 이 문제는 저희와 연락을 하는 많은 지역 스크림 주최 측에서도 존재했던 문제입니다.
또한, 저희가 관찰한 또 다른 문제점은 경기 중에 시청자들이 자신의 팀을 머릿속으로 계속 추적해야 한다는 것이었는데, 이는 명백히 좋은 경험이 아닙니다.
간단한 개요:
우리가 구축한 것 (What We Built)
저희는 오픈 소스이며 호스트 측에서 로컬로 실행할 수 있는 솔루션을 만들었습니다. 이 솔루션은 스트림을 읽고, 새로운 킬 피드(kill feed) 이벤트를 감지하며, 밀리초 단위로 실시간 점수표를 업데이트하고 이를 스트림 자체에 오버레이(overlay) 형태로 보여줍니다. BGMI가 점수표를 업데이트하기 위해 단순히 파싱할 수 있는 API를 노출하지 않기 때문에 저희는 이 방법을 선택했습니다. 이것이 기존에 그러한 애플리케이션이 없는 주된 이유 중 하나입니다.
작동 방식 (How It Works)
경기 전에 호스트는 대시보드에 팀 이름과 각 플레이어의 플레이어 태그를 입력하기만 하면 됩니다. 그런 다음 OBS 스트림을 시작하고, 가상 카메라 1(Virtual Camera 1)을 생성한 후 저희 애플리케이션을 실행해야 합니다. 이 애플리케이션은 스트림을 감지하고, 킬 피드에서 새로운 이벤트를 찾으며, 공식이 설정한 실제 기준에 따라 점수를 계산하고, 그 업데이트를 프론트엔드(frontend)로 전송합니다. 이 프론트엔드는 스트림 위에 오버레이되는 형태입니다. 또한, 이 오버레이는 최고 킬 수나 포지션과 같은 더 많은 정보도 보여줍니다.
ui
저희 애플리케이션은 경량화되도록 최적화되어 있어 고품질 60 FPS 스트림을 쉽게 처리할 수 있습니다. 이는 킬 피드 이벤트가 없는 대부분의 불필요한 프레임을 필터링하고, 유용한 정보를 포함할 가능성이 있는 프레임만을 더 무거운 ML 모델로 전달함으로써 달성됩니다.
hld
첫 사용 후 피드백
저희는 학내에서 실제 경기를 호스팅하여, 저희 솔루션이 포인트 분배의 복잡성을 처리하는 동시에 라이브 경기에서 킬 피드를 실제로 감지할 수 있는지 테스트해 보았습니다. 그 결과는 저희에게 유리했습니다. 경기가 끝난 후 몇 초 만에 포인트 테이블을 생성해냈습니다.
다음은 저희가 받은 피드백입니다:
feedback
데모
직접 사용해 보세요! README에는 시작하기 위한 간단하고 쉬운 단계가 제공되므로, 친구들과 즐기실 수 있습니다. 스트리밍을 즐겨주세요 :)
라이브 BGMI 킬 피드 파서 및 포인트 테이블 유지 관리자
BGMI 킬 피드 영상을 구조화된 이벤트로 변환하고, 이를 토너먼트 스코어링과 라이브 스코어보드 전달을 위한 빌딩 블록을 제공하는 AI 지원 연구 프로토타입.
Python 3.12+ Hacktoberfest YOLO11
BGMI 방송은 제거(elimination) 정보를 빠르게 변하는 HUD 텍스트와 아이콘으로 노출합니다. 각 이벤트를 읽고 표를 수동으로 업데이트하는 것은 느리고 오류가 발생하기 쉽습니다. 본 저장소는 지원적인 워크플로우를 탐구합니다: 비디오에서 예상되는 킬 피드 변경 부분만 좁히고, OCR로 두 개의 이름을 인식하며, 학습된 디텍터로 피드 아이콘을 분류하고, 그 결과를 토너먼트 로스터와 비교할 수 있는 Event로 표현하는 것입니다.
이것은 이미 배포된 스코어링 서비스가 아니라, 토너먼트 도구 개발자, 스트림 제작 팀, 컴퓨터 비전 기여자, 그리고 Hacktoberfest 기여자를 대상으로 합니다. 가장 강력하게 구현된 경로는 AI 후보-이벤트 파이프라인입니다. 로스터 초기화, 게시된 표로의 변환, UI 통합은 아직 연결 작업(wiring)이 필요합니다.
오늘 다룰 내용
View on GitHub
Open Innovation이 중요한 이유?
앞서 논의했듯이, 게임 자체는 API를 제공하지 않기 때문에, 유일하게 실현 가능한 해결책은 우리가 구축한 것과 일치합니다: OBS 스트림에 오버레이를 추가하는 오픈 소스 로컬 설정입니다.
저희 솔루션은 PaddleOCR과 미세 조정된 YOLOv11을 사용하여 킬 피드를 읽는 다중 모드(multimodal) 접근 방식을 사용합니다 (둘 다 오픈 가중치 모델입니다).
이러한 오픈 혁신 덕분에, 픽셀 변화 감지, 글리프 일치, OCR, 객체 탐지를 결합하는 다중 모드 시스템을 구현할 수 있었는데, 이는 미리 정의된 출력을 가진 폐쇄형 API로는 어려웠을 것입니다.
기술 심층 분석
lld
이 섹션에서는 실제로 낮은 지연 시간으로 60 FPS 스트림을 처리한 방법을 강조합니다. 매초 60프레임 전체를 ML 파이프라인으로 보낼 수는 없습니다. 왜냐하면 병목 현상이 발생할 것이기 때문입니다. 즉, 처리되지 않은 프레임들이 계속 쌓이고 과도한 리소스를 소모하게 됩니다.
따라서, 우리는 ML 파이프라인 앞에 필터링 레이어를 두어 킬 피드(kill feed)가 포함되어 있지 않은 대부분의 쓸모없는 프레임을 제거해야 합니다. 이 레이어는 결정론적(deterministic)이어야 하며 계산적으로 가벼워야 합니다.
1단계: 관심 영역(Region of Interest, ROI) 크롭핑
우선 각 프레임에서 관심 영역(ROI)만 잘라냅니다. 이렇게 하면 전체 픽셀 수가 이미지 차원 제곱에 비례하기 때문에 계산을 수행해야 하는 픽셀 수를 줄일 수 있습니다.
2단계: 캐스케이딩 프레임 필터(Cascading Frame Filters)
- 픽셀 강도 차이: 각 프레임과 인접한 프레임 간의 평균 픽셀 강도 차이를 계산합니다. 만약 픽셀 강도 차이가 임계값보다 낮으면 해당 프레임은 폐기됩니다.
- 이진 글리프 템플릿 매칭(Binary glyph template matching): 첫 번째 검사를 통과한 프레임은 두 번째 필터링 단계에 도달하며, 여기서 이진 글리프 템플릿 매칭을 수행하여 해당 프레임에 킬 피드 텍스트가 포함되어 있는지 감지합니다.
이러한 캐스케이딩 필터는 실제로 ML 파이프라인으로 진입하는 프레임 수를 극적으로 줄여줍니다.
필터링 결과
참고로, 60 FPS의 5분 스트림은 18,000개의 프레임을 생성합니다:
60 프레임/초 × 60 초/분 × 5분 = 18,000 프레임
우리의 필터링 파이프라인은 두 단계의 연속적인 과정을 거쳐 이 양을 줄입니다:
- 레이어 1: 전처리(Preprocessing): 18,000개의 프레임을 단지 347개 프레임으로 줄여, 들어오는 프레임의 약 **98.1%**를 제거합니다.
- 레이어 2: 전처리(Preprocessing): 347개 프레임을 더욱 줄여 단지 132개 프레임만 남겨, 전체적으로 약 **99.3%**의 감소율을 달성했습니다.
최종 결과: 5분 스트림을 처리하는 동안 18,000 프레임 중 단 132개 프레임만이 다음 단계에 도달하여 ML 파이프라인의 작업 부하를 크게 줄였습니다.
ML 파이프라인
이제 ML 파이프라인은 두 단계의 처리를 수행합니다:
- PaddleOCR: 킬 피드(kill feed)에서 이벤트의 주체인 플레이어 이름을 읽습니다.
- 미세 조정된 YOLOv11 (Fine tuned YOLOv11): 점수 계산 로직에 필요한 킬 피드 내 중요한 아이콘들을 분류합니다.
- 이 솔루션은 4명의 팀원들에 의해 구축되었습니다.
MEMBER 1: @satviksingh192 (본인)
MEMBER 2: @pushpam345
MEMBER 3: @urastogi2048
MEMBER 4: @shreyas_prajapati_7911096