CS2-YOLO-V1

A YOLO26s-based object detection model trained specifically for visual analysis of Counter-Strike 2 gameplay.

CS2-YOLO-V1 is the first detection model developed as part of the CS Vision Suite project.

The model is designed to detect Counter-Strike 2 players and selected gameplay utilities from recorded gameplay footage.

The system focuses entirely on visual detection and analysis. It does not interact with the game, generate automated inputs, or control the player.


Overview

CS2-YOLO-V1 detects seven classes:

ID Class Description
0 CT Counter-Terrorist player
1 CT_HEAD Counter-Terrorist head
2 T Terrorist player
3 T_HEAD Terrorist head
4 fire Fire / incendiary area
5 grenade Grenade
6 smoke Smoke grenade cloud

The model is primarily focused on player detection, with initial support for gameplay utility detection.


Model

Property Value
Architecture YOLO26s
Task Object Detection
Framework Ultralytics
Version V1
Number of Classes 7
Released Weight best.pt

The released best.pt file is the CS2-specific trained model.

It is not the original generic YOLO26s checkpoint.


Classes

Player Classes

The model explicitly distinguishes between the two teams:

  • CT
  • T

It also detects the corresponding head regions:

  • CT_HEAD
  • T_HEAD

This allows downstream systems to reason about both player presence and head position.

Utility Classes

The model also detects:

  • fire
  • grenade
  • smoke

Utility detection is currently less mature than player detection because the V1 training data contains substantially fewer utility examples.


V1 Evaluation

The final validation results for CS2-YOLO-V1 were approximately:

Class Precision Recall mAP50 mAP50-95
All 0.868 0.788 0.841 0.533
CT 0.963 0.921 0.965 0.711
CT_HEAD 0.940 0.860 0.918 0.506
T 0.945 0.930 0.956 0.699
T_HEAD 0.952 0.910 0.943 0.655
fire 0.809 0.453 0.607 0.300
grenade 0.742 0.541 0.687 0.350
smoke 0.595 0.632 0.666 0.430

Evaluation Notes

The player classes show strong performance, particularly:

  • CT
  • T
  • CT_HEAD
  • T_HEAD

The utility classes should be interpreted more cautiously.

The V1 dataset contains significantly fewer examples of fire, grenade, and smoke, so their evaluation metrics are less stable and their generalization is expected to be weaker than the player classes.

Therefore, V1 should primarily be considered a:

Strong CS2 player detection model with initial gameplay utility detection capability.


Training

CS2-YOLO-V1 was trained in two stages:

Stage 1

50 epochs

The model was initially trained on the assembled CS2 detection dataset.

Stage 2

30 additional fine-tuning epochs

The best checkpoint from the first training stage was used as the starting point for further training.

The final released model is the best.pt checkpoint selected during the final training stage.


Dataset

The training data was assembled from CS2-related object detection datasets and processed into a unified seven-class dataset.

The final class mapping used during training was:

0  CT
1  CT_HEAD
2  T
3  T_HEAD
4  fire
5  grenade
6  smoke

The underlying training datasets are not included in this model repository.

The repository contains the trained model release rather than a redistribution of the underlying datasets.

Users should review and comply with the licenses and attribution requirements associated with the original datasets.


Intended Use

CS2-YOLO-V1 is intended for:

  • Counter-Strike 2 gameplay analysis
  • Computer-vision experimentation
  • Recorded gameplay analysis
  • Screen-capture based visual analysis
  • Player detection
  • Head detection
  • Team-aware scene analysis
  • Gameplay utility detection
  • Tactical visualization
  • Replay analysis
  • Computer-vision research
  • Building higher-level CS2 analysis systems

The model can serve as the visual perception component of a larger modular CS2 analysis system.


What This Model Does NOT Do

CS2-YOLO-V1 is a visual detection model only.

It does not:

  • Control the game
  • Press keyboard keys
  • Press mouse buttons
  • Aim automatically
  • Fire weapons
  • Move the player
  • Interact with game memory
  • Inject game inputs
  • Provide an autonomous gameplay agent

The model receives visual frames and produces object detections.


Recommended Input

The customized CS2 inference pipeline is designed primarily for recorded gameplay video.

Recommended video characteristics

Property Recommended
Resolution 1920 × 1080 (1080p)
Frame Rate 60 FPS preferred
Alternative FPS 30 FPS
Aspect Ratio 16:9
Container MP4
Video Codec H.264 / AVC
Audio Optional

1080p

1920×1080 is the recommended input resolution.

The inference pipeline also supports higher-resolution input such as 4K. Frames are processed and then resized to the final 1920×1080 output.

For the intended CS2 gameplay workflow, 1080p provides a good balance between visual detail, processing requirements, and output size.

Frame Rate

60 FPS is preferred when available.

30 FPS is also supported and can be useful when processing lower-frame-rate footage or when reducing computational requirements.

The current visualization pipeline produces a final output at 60 FPS.

For a native 30 FPS input, the output configuration can be changed to 30 FPS if required.


Customized Inference Pipeline

CS2-YOLO-V1 includes a customized visualization pipeline designed specifically for CS2 gameplay.

Instead of relying on the default Ultralytics visualization, the pipeline provides:

  • Fixed class-specific colors
  • Clean bounding boxes
  • Filled label backgrounds
  • White label text
  • Confidence scores
  • 1080p output
  • H.264 encoding
  • Controlled output quality
  • FFmpeg-based video generation

The visualization is intentionally kept simple and readable during fast gameplay.


Detection Visualization

The current class color scheme is:

Class Color
CT Dark Blue
CT_HEAD Dark Blue
T Dark Red
T_HEAD Dark Red
fire Deep Orange
smoke Dark Green
grenade Dark Amber

Color Mapping

The exact BGR values used by the OpenCV visualization layer are:

CLASS_COLORS = {

    "CT":      (192, 101, 21),
    "CT_HEAD": (192, 101, 21),

    "T":       (40, 40, 198),
    "T_HEAD":  (40, 40, 198),

    "fire":    (0, 81, 230),
    "smoke":   (50, 125, 46),
    "grenade": (23, 127, 245),
}

OpenCV uses BGR color ordering rather than RGB.


Installation

Create a Python environment and install the required packages:

pip install ultralytics opencv-python

The inference pipeline also requires FFmpeg to be installed and available in the system PATH.

Verify FFmpeg:

ffmpeg -version

Download the Model

Download:

best.pt

from this Hugging Face repository.

Place the model somewhere accessible to the inference script.

For example:

CS2-YOLO-V1/
├── best.pt
└── inference.py

Customized Video Inference

The following is the customized inference pipeline used for CS2-YOLO-V1.

Update MODEL and VIDEO_PATH according to your local setup.

from ultralytics import YOLO
import cv2
import os
import subprocess

## Config

MODEL = "best.pt"
VIDEO_PATH = "test_videos/cs2_clip.mp4"

CONFIDENCE = 0.23

## Final output
OUTPUT_DIR = "runs/detect/final"
OUTPUT_PATH = os.path.join(
    OUTPUT_DIR,
    "cs2_output.mp4"
)

## Final video resolution
OUTPUT_WIDTH = 1920
OUTPUT_HEIGHT = 1080

## Final output frame rate
OUTPUT_FPS = 60


## Class colors

CLASS_COLORS = {

    ## CT side
    "CT":      (192, 101, 21),    ## Dark Blue
    "CT_HEAD": (192, 101, 21), 

    ## T side
    "T":       (40, 40, 198),     ## Dark Red
    "T_HEAD":  (40, 40, 198),     

    ## Utility
    "fire":    (0, 81, 230),      ## Deep Orange
    "smoke":   (50, 125, 46),     ## Dark Green
    "grenade": (23, 127, 245),    ## Dark Amber
}


## load the model weights

print("\nLoading YOLO model...")

model = YOLO(MODEL)

print("Model loaded successfully.")
print("Classes:", model.names)


## Input video

cap = cv2.VideoCapture(VIDEO_PATH)

if not cap.isOpened():
    raise RuntimeError(
        f"Could not open video: {VIDEO_PATH}"
    )


source_width = int(
    cap.get(cv2.CAP_PROP_FRAME_WIDTH)
)

source_height = int(
    cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
)

source_fps = cap.get(
    cv2.CAP_PROP_FPS
)

total_frames = int(
    cap.get(cv2.CAP_PROP_FRAME_COUNT)
)


print("\nInput video")
print("--------------------------------")
print(f"Resolution : {source_width}x{source_height}")
print(f"FPS        : {source_fps:.2f}")
print(f"Frames     : {total_frames}")
print("--------------------------------")


## creating output dir 

os.makedirs(
    OUTPUT_DIR,
    exist_ok=True
)


## ffmpeg output  

ffmpeg_command = [

    "ffmpeg",

    "-y",

   
    "-f", "rawvideo",
    "-vcodec", "rawvideo",

    "-pix_fmt", "bgr24",

    "-s",
    f"{OUTPUT_WIDTH}x{OUTPUT_HEIGHT}",

    "-r",
    str(OUTPUT_FPS),

    "-i",
    "-",

    ## H.264
    "-c:v",
    "libx264",

    ## Good quality / reasonable file size
    "-preset",
    "medium",

    "-crf",
    "18",

    ## Compatibility
    "-pix_fmt",
    "yuv420p",

    OUTPUT_PATH,
]


print("\nStarting H.264 encoder...")

ffmpeg_process = subprocess.Popen(
    ffmpeg_command,
    stdin=subprocess.PIPE,
    stdout=subprocess.DEVNULL,
    stderr=subprocess.PIPE
)




def draw_detection(
    frame,
    box,
    class_name,
    confidence
):

    x1, y1, x2, y2 = map(
        int,
        box
    )

    color = CLASS_COLORS.get(
        class_name,
        (255, 255, 255)
    )

   

    thickness = max(
        3,
        int(
            min(
                source_width,
                source_height
            ) / 700
        )
    )

    font_scale = max(
        0.7,
        min(
            source_width,
            source_height
        ) / 1800
    )

    text_thickness = max(
        2,
        int(
            min(
                source_width,
                source_height
            ) / 900
        )
    )

    padding = max(
        6,
        int(
            min(
                source_width,
                source_height
            ) / 300
        )
    )


    ## Bounding box 

    cv2.rectangle(
        frame,
        (x1, y1),
        (x2, y2),
        color,
        thickness,
        cv2.LINE_AA
    )


    ## Labelling

    label = (
        f"{class_name} "
        f"{confidence:.2f}"
    )

    font = cv2.FONT_HERSHEY_SIMPLEX

    (
        text_width,
        text_height
    ), baseline = cv2.getTextSize(
        label,
        font,
        font_scale,
        text_thickness
    )


    ## Position of the label 

    label_width = (
        text_width
        + padding * 2
    )

    label_height = (
        text_height
        + baseline
        + padding * 2
    )

    label_x1 = x1
    label_x2 = x1 + label_width

    # Normally place label above box
    label_y2 = y1
    label_y1 = y1 - label_height


    # If there isn't enough space above,
    # place label inside the box.
    if label_y1 < 0:

        label_y1 = y1

        label_y2 = (
            y1
            + label_height
        )



    cv2.rectangle(
        frame,
        (label_x1, label_y1),
        (label_x2, label_y2),
        color,
        -1,
        cv2.LINE_AA
    )


    ## Lable text (u can customize the label color if u want, but i personally picked white for my color stack of classes )
    text_x = (
        label_x1
        + padding
    )

    text_y = (
        label_y2
        - padding
        - baseline
    )

    cv2.putText(
        frame,
        label,
        (text_x, text_y),
        font,
        font_scale,
        (255, 255, 255),
        text_thickness,
        cv2.LINE_AA
    )


## inference loop 

print("\nStarting inference...")
print("This may take a while.")
print("--------------------------------")


frame_number = 0


while True:

    ret, frame = cap.read()

    if not ret:
        break

    frame_number += 1


    results = model.predict(
        source=frame,
        conf=CONFIDENCE,
        verbose=False
    )

    result = results[0]

    if result.boxes is not None:

        for box in result.boxes:

            xyxy = (
                box.xyxy[0]
                .cpu()
                .numpy()
            )

            confidence = float(
                box.conf[0]
                .cpu()
                .numpy()
            )

            class_id = int(
                box.cls[0]
                .cpu()
                .numpy()
            )

            class_name = model.names[
                class_id
            ]


            draw_detection(
                frame,
                xyxy,
                class_name,
                confidence
            )


    ## Resized to 1080p output 
    frame_1080p = cv2.resize(
        frame,
        (
            OUTPUT_WIDTH,
            OUTPUT_HEIGHT
        ),
        interpolation=cv2.INTER_AREA
    )

    ffmpeg_process.stdin.write(
        frame_1080p.tobytes()
    )


    if (
        frame_number % 100 == 0
        or frame_number == total_frames
    ):

        progress = (
            frame_number
            / total_frames
            * 100
        )

        print(
            f"Processing: "
            f"{frame_number}/{total_frames} "
            f"({progress:.1f}%)"
        )



cap.release()

ffmpeg_process.stdin.close()

ffmpeg_process.wait()


if ffmpeg_process.returncode != 0:

    error = (
        ffmpeg_process.stderr
        .read()
        .decode(
            errors="replace"
        )
    )

    raise RuntimeError(
        "\nFFmpeg encoding failed:\n"
        + error
    )


print("\n")
print("============================================")
print("        INFERENCE COMPLETED")
print("============================================")
print(
    f"Output     : {OUTPUT_PATH}"
)
print(
    f"Resolution : "
    f"{OUTPUT_WIDTH}x{OUTPUT_HEIGHT}"
)
print(
    f"FPS        : {OUTPUT_FPS}"
)
print(
    f"Confidence : {CONFIDENCE}"
)
print("Codec      : H.264")
print("============================================")

Inference Configuration

The important configuration values are:

MODEL = "best.pt"

CONFIDENCE = 0.23

OUTPUT_WIDTH = 1920
OUTPUT_HEIGHT = 1080

OUTPUT_FPS = 60

Confidence Threshold

The V1 pipeline uses:

0.23

as its default confidence threshold.

This can be increased to reduce false positives or decreased to increase detection sensitivity.


Output Format

The customized inference pipeline produces:

Resolution : 1920 × 1080
FPS        : 60
Codec      : H.264
Pixel Format : yuv420p
Container : MP4

The output is encoded using:

libx264
CRF 18
Preset medium

This provides a high-quality H.264 output while keeping the file size considerably smaller than raw or lightly compressed source footage.


Audio

The customized inference renderer generates the video stream.

Audio is not processed by the OpenCV/FFmpeg rendering pipeline shown above.

If the original gameplay footage contains audio, it can be muxed back into the generated detection video without re-encoding the YOLO video stream.

For example:

ffmpeg \
-i "original.mp4" \
-i "cs2_output.mp4" \
-map 1:v:0 \
-map 0:a? \
-c:v copy \
-c:a aac \
-shortest \
"cs2_output_audio.mp4"

This keeps the generated detection video while adding the original audio track when one is available.


Example Pipeline

A typical workflow is:

CS2 Gameplay Video
        │
        â–¼
  H.264 MP4 Input
        │
        â–¼
   YOLO26s V1
        │
        â–¼
 Object Detection
        │
        â–¼
 Custom Visualization
        │
        â–¼
 1920×1080 H.264
        │
        â–¼
 Optional Audio Mux
        │
        â–¼
 Final Annotated Video

Limitations

CS2-YOLO-V1 is the first version of the CS2 detection pipeline and has several limitations.

1. Limited Utility Data

The V1 training data contains significantly fewer examples of:

  • fire
  • grenade
  • smoke

Consequently, utility detection is less reliable than player detection.


2. Fast Gameplay

Rapid movement, motion blur, explosions, particle effects, and heavily populated fights can reduce detection quality.

This is particularly relevant during chaotic:

  • Executes
  • Retakes
  • Close-range fights
  • Multi-player engagements

3. Occlusion

Players may be missed or detected with lower confidence when heavily obscured by:

  • Smoke
  • Other players
  • Map geometry
  • Visual effects
  • UI elements

4. Frame-Level Detection

V1 primarily performs frame-level object detection.

It does not yet include:

  • Persistent object tracking
  • Temporal smoothing
  • Multi-frame identity association
  • Advanced temporal reasoning

These are planned for future development.


5. Dataset Coverage

The model was trained on a limited range of CS2 gameplay conditions.

Performance may vary across:

  • Maps
  • Resolutions
  • HUD configurations
  • Spectator views
  • Gameplay perspectives
  • Visual settings
  • Screen layouts
  • Different levels of visual clutter

V1 Status

Status: Stable Experimental Release

CS2-YOLO-V1 is the first usable detection baseline for the CS Vision Suite.

The player detection component demonstrates strong validation performance and provides a foundation for downstream gameplay analysis.

Utility detection is considered an initial implementation and is expected to improve in future versions.


Future Work — V2

Future versions will focus on improving robustness in difficult gameplay situations.

Planned areas of improvement include:

  • More chaotic gameplay footage
  • More multi-player fights
  • More smoke-heavy scenarios
  • More fire/incendiary examples
  • More grenade examples
  • Better map coverage
  • Better gameplay-condition coverage
  • Improved utility detection
  • Object tracking
  • Temporal smoothing
  • Multi-frame reasoning
  • More robust detection during executes and retakes
  • Higher-quality evaluation datasets

The long-term goal is to move beyond isolated object detection toward a more complete CS2 visual understanding system.


CS Vision Suite

CS2-YOLO-V1 is the visual detection component of the broader CS Vision Suite project.

The intended architecture is modular:

Gameplay / Screen Capture
          │
          â–¼
     YOLO Detector
          │
          â–¼
   Detected Game Objects
          │
          â–¼
   State / Decision Layer
          │
          â–¼
 Analysis / Visualization

The detector is deliberately separated from higher-level reasoning so that additional components can be developed independently.

Future versions of the system may build higher-level game-state and tactical analysis on top of these detections.


Responsible Use

This model is intended for computer-vision research, experimentation, gameplay analysis, and visualization.

The model itself performs visual inference only and does not provide mechanisms for automated game interaction.

Users are responsible for ensuring that their use of the model complies with the rules, policies, and terms applicable to the software, games, platforms, and datasets involved.


License

The license for this model is specified in the repository's LICENSE file.

The underlying training datasets may have separate licenses and attribution requirements.

Users should review the relevant dataset licenses before redistributing derived materials or using the model in contexts where those requirements apply.


Acknowledgements

This project uses the Ultralytics YOLO framework for model training and inference.

Ultralytics:

https://github.com/ultralytics/ultralytics

Ultralytics Documentation:

https://docs.ultralytics.com/


Citation

If you use CS2-YOLO-V1 in a project, please reference this model repository.

CS2-YOLO-V1
CS Vision Suite
YOLO26s

Project Status

CS2-YOLO-V1 is an experimental research and development release.

It serves as the first trained detection model for the CS Vision Suite and provides the foundation for future player tracking, temporal reasoning, utility detection, and higher-level CS2 gameplay analysis.

More tooling and analysis components will be introduced in future releases.

Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for KarthikRaj666/CS2-YOLO-V1

Finetuned
(97)
this model