지피지기 백전백퇴

게임 영상 분석하기


Title

개요

대충 하루에 일일퀘만 빠르게 하면 얼마나 시간이 드는지 분석하고 싶었는데, 그러려면 일일퀘만 하는 부분을 뽑아서 분석해야 할 필요가 있다. 마침 나는 일일퀘를 할 때 2계정을 돌려야 하니 그걸 이용해서 게임 플레이 중에 일일퀘를 진행하는 부분만 잘라내는 프로그램을 만들어볼 수 있겠다 싶었다.

대충의 구조

OBS로 전체 화면을 캡쳐한 다음에 프레임을 YOLO같은 object detection model에 넣으면 다인 모드에 해당하는 indicator를 인식할 수 있지 않을까?

Title

동영상에서 프레임 읽기

from IPython.display import display, Image as Img
import cv2
from ultralytics import YOLO

model = YOLO("runs/detect/train9/weights/best.pt")
model.eval()

cap = cv2.VideoCapture(VIDEO_PATH)

def show(frame):
    _, buf = cv2.imencode('.png', frame)
    display(Img(buf))    

def parse_frame(frame_no: int):
    cap.set(cv2.CAP_PROP_POS_FRAMES, frame_no)
    _, frame = cap.read()
    result = model(frame)[0]
    lst = result.boxes.cls.tolist()
    ts = cap.get(cv2.CAP_PROP_POS_MSEC)
    print(ts, lst)
    # show(result.plot())
    return result, lst, ts

IPython 안에서 이미지를 보여주려면 show 함수를 쓰면 된다.

모델 학습용 데이터셋 만들기

YOLO 문서에서 소개하는 roboflow를 이용했더니 상대적으로 간단하게 데이터셋을 만들 수 있었다. 나름 웹 UI가 있어서… 이미지 파일에서 슥슥 네모 그리고 라벨링 해주면 데이터셋이 쨘 하고 나온다. 다만 이미지 업로드는 다음과 같이 코드를 짜면 좋다.

이미지를 처음부터 많이 올릴 필요는 없고, 내 경우엔 10개 정도 올렸을 땐 잘 안됐는데 25개쯤 올리고 나자 쓸만해졌다.

#%%
import os
import cv2
from roboflow import Roboflow

rf = Roboflow(api_key="xxxxxxxxxxxxxxxxx")
project = rf.workspace("xxxxxxxxxxx").project("yyyyyyy")

# Assume YOLOv11 model is available.
# Assume model predict result is available as result

#%% when you got a frame to annotate
if os.path.exists("/tmp/annot.txt"):
    os.remove("/tmp/annot.txt")
result.save_txt("/tmp/annot.txt")
cv2.imwrite("/tmp/image.png", frame)
kargs = {}
if len(result) > 0:
    kargs = { "annotation_path": "/tmp/annot.txt", "annotation_labelmap": {
        0: "1p",
        1: "2p",
    } }
print(project.single_upload(
    image_path="/tmp/image.png",
    is_prediction = True,
    **kargs,
))

모델 학습하기

#%%
from roboflow import Roboflow

rf = Roboflow(api_key="xxxxxxxxxxxxxxxxx")
project = rf.workspace("xxxxxxxxxxx").project("yyyyyyy")
version = project.version(1)
dataset = version.download("yolov11")

#%%
!yolo task=detect mode=train model=yolo11m.pt data={dataset.location}/data.yaml epochs=100 plots=True

워크스페이스 이름이 웹에선 잘 안보이던데, api_key를 넣고 다음 API를 호출하면 쨘 하고 나온다.

curl "https://api.roboflow.com/?api_key=xxxxxxxxxxxxxxxxxx"

결론

이제 일일퀘에 얼마나 시간을 쓰는지 추적할 수 있게 되었다.