Yolo 11 — полноэкранный ESP на ImGui
1.7.8532+
Подсветить объекты на экране через YOLO
Запускайте код как верхнеуровневый C# Script EyeAuras. Он только визуализирует найденные объекты рабочего стола/учебного видео и не отправляет ввод в игру. Нужны указанные версии EyeAuras.ImGuiSdk и ImGui.NET, доступ к ONNX-файлу по URL, рабочие захват экрана и ML runtime. Файл модели не встроен в скрипт; доступность URL и совместимость нативных компонентов здесь не проверены.
Этот пример показывает, как собрать полноэкранный ESP-оверлей с помощью YOLOv11s (модели машинного обучения для обнаружения объектов) и ImGui — библиотеки для UI в реальном времени. Он работает поверх рабочего стола и подсвечивает объекты, найденные в выбранной области экрана.
Также в примере есть горячая клавиша F1, которая позволяет включать и отключать распознавание прямо во время работы.
Посмотреть в действии: Demo
Попробовать на видео: Target Tracking - YouTube
Основные возможности
F1— включение и выключение захвата/обработкиF2— ручной выбор области захвата- Используется YOLOv11s ONNX model для быстрого ML-распознавания объектов
- Отображаются bounding boxes + labels поверх найденных целей
- Рисуется счетчик FPS (в правом верхнем углу)
- Для производительности анализируется только заданная область экрана
Используемые технологии
- EyeAuras.ImGuiSdk
- ImGui.NET
- API EyeAuras: CV (Computer Vision), ImGui, Input, Logging
Что делает скрипт
Когда скрипт включен, он:
- непрерывно сканирует заданную область экрана или весь экран
- использует ML для поиска целей в этой области
- рисует bounding boxes и подписи через ImGui
- показывает FPS в реальном времени
- позволяет приостанавливать и возобновлять распознавание клавишей
F1
Пример кода
//this is a simple fullscreen ESP using Yolo 11s model for https://aimtrainer.io/target-tracking
//open this YT video https://www.youtube.com/watch?v=rTqg2hEjGdE
#r "nuget:EyeAuras.ImGuiSdk, 0.0.6"
#r "nuget:ImGui.NET, 1.91.6.1"
using EyeAuras.ImGuiSdk;
using ImGuiNET;
using System.Numerics;
using System;
using System.Drawing;
using System.Linq;
using EyeAuras.OpenCVAuras.Scripting;
using EyeAuras.Roxy.Api;
using EyeAuras.Scripting.Api;
using EyeAuras.Shared.Services;
using PoeShared.Scaffolding;
private object StateGate { get; } = new object();
public bool IsEnabled { get; set; } = true;
public Rectangle CaptureRegion { get; set; }
{
AddNewExtension<ImGuiContainerExtensions>();
using var cv = GetService<IComputerVisionExperimentalScriptingApi>()
.ForScreen();
using var osd = GetService<IImGuiExperimentalApi>();
var mlModelPath = @"https://s3.eyeauras.net/public/eyeauras-ml/yolo/yolov11s.onnx";
Log.Info("Working...");
var renderGate = new object();
var renderStopped = false;
var renderRegistration = osd.AddRenderer(() =>
{
lock (renderGate)
{
if (renderStopped || cancellationToken.IsCancellationRequested) return;
bool enabled;
Rectangle captureRegion;
lock (StateGate)
{
enabled = IsEnabled;
captureRegion = CaptureRegion;
}
var drawList = ImGui.GetBackgroundDrawList();
// Draw FPS in top-right corner of the capture area
float fps = ImGui.GetIO().Framerate;
var captureAreaBounds = captureRegion.IsEmpty
? System.Windows.Forms.Screen.PrimaryScreen.Bounds
: captureRegion;
drawList.AddRect(
new Vector2(captureAreaBounds.Left, captureAreaBounds.Top),
new Vector2(captureAreaBounds.Right, captureAreaBounds.Bottom),
Color.Purple.ToImGuiColor());
string fpsText = $"FPS: {fps:F1}";
float fontSize = ImGui.GetFontSize() * 3f; // x3 size
var textSize = ImGui.CalcTextSize(fpsText) * 3f; // also scale position
drawList.AddText(
ImGui.GetFont(),
fontSize,
new Vector2(captureAreaBounds.Right - textSize.X - 10, captureAreaBounds.Top + 10),
Color.Yellow.ToImGuiColor(),
fpsText);
drawList.AddText(
ImGui.GetFont(),
fontSize,
new Vector2(captureAreaBounds.Left + 10, captureAreaBounds.Top + 10),
enabled ? Color.Purple.ToImGuiColor() : Color.Yellow.ToImGuiColor(),
$"F1 - {(enabled ? "Stop" : "Start")}, F2 - Select Region");
if (!enabled)
{
return;
}
// Perform ML-search
//or you can use Context Menu => Pick region to insert custom region - this will drastically improve quality
var result = cv.MLSearchRaw(mlModelPath, region: captureRegion);
var predictions = result.Detected.Predictions.Where(x => x.Score > 0.7).ToArray();
if (!predictions.Any()) return;
foreach (var prediction in predictions)
{
var predictionBounds = result.ToScreen(prediction.Rectangle);
drawList.AddRect(
new Vector2(predictionBounds.Left, predictionBounds.Top),
new Vector2(predictionBounds.Right, predictionBounds.Bottom),
Color.AliceBlue.ToImGuiColor());
var topLeft = new Vector2(predictionBounds.Left, predictionBounds.Top);
var label = $"{prediction.Label.Name} ({prediction.Score:P1})";
drawList.AddText(topLeft, Color.White.ToImGuiColor(), label);
}
}
});
try
{
cancellationToken.WaitHandle.WaitOne();
}
finally
{
lock (renderGate)
{
// Wait for any current callback, then prevent all later work.
renderStopped = true;
}
renderRegistration.Dispose();
}
}
[Keybind(Hotkey = "F1", SuppressKey = true)]
public void HandleF1()
{
lock (StateGate)
{
IsEnabled = !IsEnabled;
}
}
[Keybind(Hotkey = "F2", SuppressKey = true)]
public async Task HandleF2(EyeAuras.Shared.Osd.IOsdSelectionService osdSelectionService)
{
Log.Info($"F2 pressed");
try
{
var selection = await osdSelectionService.PickRegion();
Log.Info($"Selection result: {selection}");
if (cancellationToken.IsCancellationRequested) return;
lock (StateGate)
{
CaptureRegion = selection.Region;
}
}
catch (OperationCanceledException)
{
Log.Info($"Selection cancelled");
}
}
MLSearchRaw получает ROI именованным аргументом region. При пустом ROI захват определяется ForScreen, а рамка в этом примере берётся с основного экрана; это не утверждение, что они совпадают при любой конфигурации мониторов. Порог CV по умолчанию — confidence 30%, IoU 40%, затем код дополнительно оставляет Score > 0.7. Пустой список означает отсутствие подходящих предсказаний, а не ошибку загрузки модели. Каждый прямоугольник проходит через result.ToScreen перед отрисовкой.
Состояние F1/F2 копируется под одним lock, чтобы Rectangle не читался одновременно с записью. Само распознавание остаётся в callback ImGui и может задерживать кадр. FPS показывает частоту ImGui, не отдельную скорость ML. PickRegion может быть отменён пользователем; токен проверяется после выбора, но этот вызов не объявляется отменяемым токеном скрипта. В finally выставляется флаг завершения под тем же lock, который охватывает callback, и снимается регистрация; затем using освобождает ImGui API и CV. Поэтому уже начавшийся callback завершится до освобождения ресурсов, а поздний не начнёт работу; нельзя передавать заимствованные кадры в фоновый поток или считать общий CV-контекст потокобезопасным.
Дальше
Контекст скрипта · Захват и результаты CV · CV API
Операции CV и владение регистрацией сопоставлены с исходниками EyeAuras 20fd3d4. Пример сохраняет историческую привязку EyeAuras.ImGuiSdk 0.0.6; её бинарная совместимость с этими исходниками и ImGui.NET 1.91.6.1 не подтверждена. Рамки показаны через публичный draw list ImGui, а не отсутствующий в текущем интерфейсе osd.DrawFrame. Перед использованием проверьте сигнатуры SDK своей версии; компиляция и запуск этого листинга не выполнялись.