1.6.8148

Март — CV API и выбор OSD

Прототип Computer Vision API

Это довольно крупное обновление. Появился новый экспериментальный scripting API, который позволяет работать с Computer Vision в EyeAuras вообще без использования Auras.

Достаточно написать всего несколько строк кода — и в вашем распоряжении окажутся все инструменты, которые развивались годами: поиск изображений, поиск по цвету, нейросети и многое другое.

Обратите внимание: API совсем новый, поэтому он еще может меняться. Не говоря уже о возможных багах и шероховатостях — пожалуйста, присылайте свои отчеты.

Быстрый старт

Вот как может выглядеть работа с новым API. Для начала попробуем найти изображение где-то на экране.

csharp
var cv = GetService<IComputerVisionExperimentalScriptingApi>()
    .ForScreen() //search through entire screen, could be ForWindow - see below
    .EnableOsd(fps: 10); //optional, with enabled on-screen-display refreshed @ 10 fps

var position = cv.ImageSearch(targetImagePath);
if (position.IsEmpty)
{
    Log.Info($"Found @ {position}");
} else {
    Log.Info($"Image not found");
}

Вот и все — никаких auras, triggers или actions. Все доступно прямо в этих нескольких строках кода.

Под капотом EyeAuras постарается максимально оптимизировать ваши вызовы: кэшировать изображения, модели, заранее подгружать нужные данные и т. д.
В этой области еще есть куда расти по производительности, но даже текущего состояния уже более чем достаточно для большинства задач.

Возможности

Вот что доступно уже сейчас:

  • поддерживается загрузка изображений и моделей как с локальной файловой системы, так и по URL
  • PixelSearch — можно использовать либо для поиска пикселя определенного цвета/оттенка, либо для проверки, соответствует ли пиксель в конкретной точке ожидаемому цвету
  • ImageSearch — просто ищет изображение
  • TextSearch — распознает текст в указанной области экрана/окна. Пока почти не настраивается, но в ближайшее время возможности будут расширены
  • MLSearch — получает предсказания от ML-модели; по смыслу этот вызов во многом эквивалентен старому Refresh()
  • OnScreenDisplay (OSD) — если включен, визуализирует каждый вызов этого API прямо на экране. Также можно задать FPS для OSD, чтобы снизить нагрузку на систему; обычно 5-10 FPS более чем достаточно, чтобы видеть, что происходит под капотом
  • много новых вспомогательных инструментов для работы с API — селекторы окна, региона, точки, цвета и не только; подробнее ниже

Где это может пригодиться

  • более тонкий контроль над EyeAuras — именно вы управляете каждым тактом CPU, который тратится на computer vision
  • использование Computer Vision напрямую из Macros/BTs. В ближайшее время появятся Nodes, которые будут использовать этот же API и позволят не завязываться везде на AuraIsActive
  • небольшие переносимые скрипты, которыми удобно делиться через форум — когда не нужно разбираться в цепочке из множества auras, гораздо проще понять, что именно происходит

Что планируется после стабилизации текущей версии

  • сделать так, чтобы API учитывал Bindings — это упростит интеграцию API в trees и Macros
  • добавить возможность «заглядывать» в Triggers, которые используются под капотом этого API — примерно так же, как сейчас можно делать Preview этих триггеров в Auras
  • улучшения редактора — предварительная загрузка изображений (с предпросмотром прямо в редакторе) и более удобное автодополнение в этой части
  • загрузка встроенных файлов — чтобы можно было помещать модели/изображения прямо в скрипт и подгружать их по запросу

Пример aim bot на основе поиска изображения

Это пример бота, который отслеживает изображение и кликает по нему (на примере AimTrainer).

Что стоит обратить внимание на OSD:

  • мигающий синий прямоугольник — захваченное окно
  • (необязательно) большой желтый прямоугольник — захваченная область внутри этого окна
  • маленький прямоугольник — успешное совпадение по изображению

p.s. Здесь все специально замедлено для наглядной демонстрации. При нормальной настройке скрипт может достигать до 60-80 hits/second :D

Example

csharp
//this is an example of a script
//which uses image search to find and follow a specific image inside a window
//It uses 2-times probing for optimization - if we know the previous location of the image
//it makes sense to repeat the search in that specific region first

//picking a window
var windowSelector = GetService<IWindowSelector>();
windowSelector.TargetWindow = "Aim Trainer";
var targetWindow = windowSelector.ActiveWindow ?? throw new InvalidOperationException("Window not found");

//this API is used to do Computer Vision stuff (image/text/color/ml search)
var cv = GetService<IComputerVisionExperimentalScriptingApi>()
    .ForWindow(targetWindow)  //for a specific window
    .EnableOsd(fps: 10); //with enabled on-screen-display refreshed @ 10 fps

//this API is used to generate mouse movements
var sendInput = GetService<ISendInputScriptingApi>();
sendInput.TargetWindow = targetWindow; //for a specific window

//could be either local file or URL
var targetImagePath = @"C:\Users\Xab3r\Documents\ShareX\Screenshots\2025-03\uupb4m3RQkfHa8sv.png";

//repeat until script is stopped
while (true)
{
	  //try to find the image
    var position = cv.ImageSearch(targetImagePath); 
    if (position.IsEmpty)
    {
        //not found
        continue;
    }

    Log.Info($"Found @ {position}");
    
    //found the image - moving the mouse to the center and clicking on object
    sendInput.MouseMoveTo(position.Center());
    sendInput.MouseClick();
}

Альтернативно тот же цикл может выглядеть так при использовании нейросети.

ML, скорее, рассчитан на более опытных пользователей. Сейчас метод возвращает «сырые» результаты в виде WindowImageProcessedEventArgs — это дает максимально возможный контроль над извлеченными данными.

csharp
//as with the image, model path could be local or could point to remote file
var mlModelPath = @"https://s3.eyeauras.net/media/2025/03/AimLab_20240213193604OOBfW2f00U5K.onnx";
while (true)
{
    //get predictions from the model
    var result = cv.MLSearchRaw(mlModelPath); 
    if (!result.Detected.Predictions.Any())
    {
        //not found
        continue;
    }

    var currentPosition = result //WindowImageProcessedEventArgs
      .Detected //get detection results 
    	.Predictions //get predictions
    	.First() //more specifically, first one
      .Rectangle //get bounding box of that prediction IN LOCAL(aka World) coordinates
      .Transform(result.ViewportTransforms.WorldToWindow); //transform World coordinates to Window coordinates
    Log.Info($"Found via ML @ {currentPosition}");

    if (!currentPosition.IsEmpty)
    {
        //found the image - moving the mouse to the center
        sendInput.MouseMoveTo(currentPosition.ToWinRectangle().Center());
        sendInput.MouseClick();
    }
}

Новые инструменты для написания кода

Вместе с новым API понадобились и более удобные инструменты для работы с ним.

Идея простая: вы используете эти инструменты, чтобы получить значения, которые затем можно сразу вставить в код — например, координаты, цвет, заголовок окна или имя процесса.
Это должно заметно ускорить разработку, особенно для небольших скриптов.

В список входят:

  • Color selector — позволяет выбрать цвет

Color selector

var pixelLocation = cv.PixelSearch(Color.FromArgb(26, 26, 26)); //<- Color.FromArgb(26, 26, 26) inserted by Color selector
  • Window Selector — позволяет выбрать окно и вставляет подходящее Window Match Expression — заголовок окна, имя процесса и т. д.
var cv = GetService<IComputerVisionExperimentalScriptingApi>().ForWindow("l2.bin"); //<- "l2.bin" inserted by Process selector
  • Region selector — позволяет выбрать область окна/экрана
cv.MLSearchRaw(mlModelPath, new Rectangle(719, 406, 988, 584)); //<- new Rectangle(719, 406, 988, 584) inserted by Region selector
  • Point selector — позволяет выбрать конкретную точку окна/экрана
sendInput.MouseMoveTo(new Point(190, 393)); //<- new Point(190, 393) inserted by Point selector

Абсолютные и относительные координаты

При работе с координатами не забывайте, что они могут быть либо абсолютными (screen), либо относительными (window). В зависимости от сценария удобнее может быть как один, так и другой вариант.

Новые инструменты поддерживают оба режима — для этого есть два разных типа инструментов, используйте тот, который лучше подходит вашей задаче.

Tools

Исправления и улучшения

  • [Scripting] API SendInput переведен из SendInputUnstableScriptingApi в SendInputScriptingApi — почти год без изменений, так что он выглядит достаточно стабильным
  • [Scripting] Номера строк с ошибками теперь должны корректно подсвечиваться/отображаться при ошибках компиляции
  • [Scripting] Добавлено неявное преобразование из string в WindowMatchExpression
  • [Scripting] Добавлена новая структура Percentage, которую можно использовать, чтобы явно обозначать значения в % (например, 0.1 = 10%)
  • [Scripting] У всех OSD-объектов теперь есть Opacity
  • [Scripting] В WindowImageProcessedEventArgs добавлена матрица преобразования WorldToWindow — это позволяет очень просто вычислять координаты внутри окна после Refresh()
  • [ColorSearch] Небольшая оптимизация — потребление памяти стало ниже, а работа немного (~2-3%) быстрее
  • [OSD] Исправлена ошибка с окраской OSD-прямоугольников — каналы цвета R и G были перепутаны