Написал приложение для экранного перевода текста в режиме реального времени в играх, видео и прочем

Высокая точность и простота. Все, чтобы тебе не пришлось учить языки.

Время от времени на DTF всплывают посты со способами различной степени извращенности на тему автоперевода текста в играх. Что особенно актуально в текущие тяжелые времена. Далеко ходить не нужно: еще вчера была заметка про «Ёлочку» (про нее тоже упомяну позже).

Реализовал первый концепт приложения для себя я еще несколько лет назад, но все не было времени довести его до ума. Однако вот несколько месяцев назад ушел с работы, а что еще делать отдыхающему от рабочей рутины разработчику? Правильно! Разрабатывать для души.

Так за последние месяцы я допилил наконец концепт до презентабельной первой релизной версии, но как Bethesda разрабатывает Starfield 25 лет, так и я могу заявить, что «разрабатывал приложение три года».

Т.к. такие темы — это магнит для личностей «лол, проще выучить английский», уточню, что 90% моих личных сценариев пользования тулзой — это перевод различного рода видео и текста с корейского. Случаи разные, да и нет ничего зазорного не знать английский, пользуясь удобным инструментарием.

Не могу упустить шанса немного рассказать про детали разработки (без технических крайностей, это оставим под Habr). Если лирика не интересна, можете сразу перейти к практической части. Она короткая и простая.

Очевидная идея? Но АНАЛОГОВ НЕТ

Действительно, даже если просто загуглить "screen translator" можно найти десятки различных реализаций. Отбросив откровенно заброшенные проекты, я бы выделил два приложения, которые покрывают все категории доступных сейчас вариантов.

Написал приложение для экранного перевода текста в режиме реального времени в играх, видео и прочем

Сначала по плюсам:

  • Она работает. Часто даже что-то переводит.
  • Предельно проста в использовании: никакого интерфейса, нажал -> выделил -> перевелось.

И вот теперь к минусам:

  • Только режим единоразового перевода. Т.е. для каждой фразы придется проделывать цикл с нажатием и выбором области. Если вы используете перевод один раз в час — терпимо, но в остальном это почти то же самое, что сидеть со словарем. А если еще не можете поставить на паузу?
  • Только Google Translate. Google Translate — это плохо для любого языка. UPD: @Tomurai подсказал, что в другом блоге лежит более новая версия с DeepL переводом через отдельное окно браузера.
  • Движок распознавания текста Windows OCR (про них чуть позже) — он неплох, но со сложным фоном часто не справляется.
Даже достижение, что в таком случае смог в часть текста
Даже достижение, что в таком случае смог в часть текста
  • Только английский язык. Также еще сама она не устанавливает языковые пакеты Windows для распознавания, так что если у вас их не окажется, придется маяться самому.

В целом, уже первых двух пунктов достаточно, чтобы пойти дальше.

Написал приложение для экранного перевода текста в режиме реального времени в играх, видео и прочем

Тулза от корейского товарища (тоже те еще знатоки английского), которая ближе всего к желаемому... на бумаге.

По плюсам:

  • Действительно перехватывает появляющийся текст и переводит в режиме реального времени! (может и в одиночном режиме)
  • Множество доп. фич: словарь с корректировками, озвучка, несколько областей захвата.
  • Удобный оверлей, где отображается текст: выглядит почти как нативные субтитры.
  • Активная поддержка: автор регулярно выпускает обновления (в основном мелкие фиксы).

Но все это звучит здорово пока не начинаешь пользоваться:

  • Ужасный интерфейс. Я, конечно, максимально не UI/UX дизайнер, но это банально тяжело использовать в повседневности. Еще наполовину на корейском языке.
  • Из переводчиков доступны Google translate, Papago naver, DeepL. НО Papago — только по API ключу, DeepL интегрирован криво, у меня заработал только в первый раз. Остается опять православный Google.
  • Установка языковых пакетов опять вручную
  • Движки распознавания доступны на выбор сразу три: Tesseract, Windows OCR (основной), NHOCR (для японского). Но ни одного из них опять по отдельности недостаточно, чтобы эффективно работать с «сложным текстом». Тут и «режим субтитров» сразу становится недостатком. На выходе получается что-то такое:
Эта FF со своим шрифтом будет любому движку OCR сниться в страшных снах

Можно ли что-то понять из такого результата? Ну, если постараться. Справится ли он с наиболее простыми случаями? С Гугл транслитом — вполне. Однако с азиатскими языками все еще печальнее, в связи с особенностями Win OCR.

Так в чем проблема?

Как уже думаю понятно, что слабое место всего механизма — именно распознавание текста. За это ответственны OCR (Optical character recognition) движки, которые включают обычно в себя два основных модуля:

  • Text detection — определение текста на изображении (его наличие, границы)
  • Text recognition — непосредственно распознавание символов
Text detection в действии: OCR широко применялось в первую очередь в документообороте
Text detection в действии: OCR широко применялось в первую очередь в документообороте

Долгое время задача распознавания текста оставалась крайне несовершенной и ограниченной в областях применения. Так Tesseract, один из наиболее древних движков, использовался по большей части в корпоративной среде для документов, где простейший белый фон бумаги. Microsoft внедрили в Windows более продвинутое решение, но все еще его не хватает для многих «полевых задач» и эффективность снижается на азиатских языках.

Но с бумом нейронок многое изменилось, и в последние годы стало появляться все больше продвинутых OCR решений. Однако ввиду некоторых сложностей все до сих пор тащат в свои конечные приложения примитивные Tesseract и Win OCR.

Что я реализовал?

Во-первых, я интегрировал в приложение одно из самых продвинутых на сегодня open-source OCR решений — EasyOCR.

All-in-one решение с многоступенчатым пре-процессингом и современными Detection / Recognition моделями
All-in-one решение с многоступенчатым пре-процессингом и современными Detection / Recognition моделями

Казалось бы, пихай самый крутой движок и дело сделано? Но есть нюансы.

Нюанс первый: EasyOCR — довольно тяжелое решение (импакт на GPU и оно медленнее остальных).

Я обрабатываю в среднем три фрейма в секунду, и в таком режиме этот движок будет ложить на лопатки как идею real-time подхода, так и производительность системы в целом.

Нюанс второй: EasyOCR не так уж идеален.

У каждого движка есть свои слабые и сильные стороны, которые становятся понятны после часов работы. Tesseract хорош с правильным пре-процессингом и стабилен на простом фоне, Win OCR не дает ложных срабатываний и быстр. EasyOCR — универсален, но даже в простых ситуациях любит делать опечатки в пограничных символах (например, заменять "i" на "1").

Так какая мне в итоге пришла идея? Правильно! Комбинировать использование всех трех движков!

Это позволяет, во-первых, прийти к некоторым оптимизациям: на каждом фрейме не задействовать тяжелый EasyOCR. И, во-вторых, чтобы для каждой итерации шел выбор «лучшего» распознанного результата.

Осталось понять, как выбирать лучший. Тут я задействовал машинное обучение на ~300 тыс. отобранных строк субтитров (<512 символов каждая) под каждый из 5 языков. Там содержатся как эталонные строки, так и различные нагенеренные варианты «с шумом». Довольно простая регрессионная модель без моднявых NLP + Deep learning, т.к. нужна была портативность, но метрики показали вполне хорошие результаты.

В общем, упрощенно обработка каждого фрейма выглядит следующим образом:

На самом деле используется не три, а пять вариаций движков (с разным пре-процессингом)
На самом деле используется не три, а пять вариаций движков (с разным пре-процессингом)

Еще появились сложности из-за способа отображения текста. Я решил, что удобнее будет показывать переведенный текст в неком «окне чата», которое хранит множество последних переведенных строк. MORT в этом плане не парится и просто меняет текст налету.

С таким подходом, без локального кэша, объединения и сравнения фреймов, может получиться такая картина:

Отключен EasyOCR и ряд внутренних алгоритмов
Отключен EasyOCR и ряд внутренних алгоритмов

Здесь показан не худший случай, но тем не менее возникает множество лишних корректировок одних и тех же строк из-за шума и ошибок на разных фреймах. Читать такое неудобно.

Кратко это ключевые проблемы, которые приходилось решать, получилось же нечто следующее.

Встречайте, Translumo — продвинутый экранный переводчик

Основные фичи:

  • Перевод в честном реальном времени: по одному нажатию происходит старт/окончание мониторинга выбранной области.
  • Поддержка и механизм комбинирование трех движков распознавания (Tesseract, Windows OCR, EasyOCR) для лучшего результата.
  • Максимальная простота и универсальность. «Запустил и играешь» (с). Установка всех зависимостей из коробки.
  • Весь спектр переводчиков: Google translate, Yandex translate, Papago Naver, DeepL.
  • Доступные языки: английский, русский, корейский, японский, китайский (упрощенный).

Системные требования:

  • Windows 10 build 19041 (20H1 обновление от 27.05.2020) / Windows 11
  • DirectX11
  • 8 GB ОЗУ (для продвинутого режима с EasyOCR)
  • 5 GB свободного места на диске (для продвинутого режима с EasyOCR)
  • Nvidia GPU с поддержкой CUDA SDK 11.8 (GTX 7xx серия или новее) (для продвинутого режима с EasyOCR)

Да, внедрение мощного движка EasyOCR потребовало неких компромиссов в производительности: с ним приложение жрет почти 4 GB ОЗУ, а в играх с 100% загрузкой ГП оно может давать микрофризы (впрочем, совсем не нужно держать отслеживание текста всегда включенным).

Как пользоваться

Наглядный пример со стариной Стивом

Каждый раз, безусловно, это проделывать не нужно (все настройки сохраняются). Достаточно выбрать область и жмакнуть кнопку старта.

Основные функции доступны через горячие клавиши (пока не конфигурируемы) или контекстное меню в системном трее.

Советы по использованию

Касательно выбора движков распознавания. Рекомендую всегда держать включенным Windows OCR. В виду своих особенностей, он крайне эффективен в качестве первичного движка определения.

Рекомендуемые комбинации OCR (в порядке убывания):

  • Tesseract-Windows OCR-EasyOCR — продвинутый режим с наибольшей точностью распознавания.
  • Tesseract-Windows OCR — значительно менее затратный вариант по производительности. Его будет достаточно для простых ситуаций, когда текст имеет односложный фон, а шрифт хорошо читается.
  • Windows OCR-EasyOCR — для отдельных наиболее сложных случаев, когда Tesseract полностью бесполезен и добавляет лишь лишний шум в результаты.

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

Используйте функционал прокси-списка для избежания блокировки со стороны переводчиков. Да, при слишком большом числе запросов за единицу сервисы могут временно блочить клиент по IP (таким грешит DeepL).

Окно настроек прокси
Окно настроек прокси

Здесь подойдут любые shared/personal IPv4 прокси (которые стоят ~50р. за шутку), 1-2 штук должно хватить. Они будут попеременно использоваться в запросах, чтобы снизить число обращений в единицу времени с одного IP.

Используйте Безрамочный/Оконный режимы в играх (не Полноэкранный). Это необходимо, чтобы окно оверлея с переводом корректно отображалось поверх. Если в игре не предусмотрена такая настройка, можете использовать сторонние программы (например, Borderless Gaming)

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

Технический FAQ

Могут ли забанить за использование приложения в онлайн-играх?

Сам про такое не слышал, по идее это простейший оверлей и захват экрана, НО @Mr. Expert сообщает, что некоторые античиты для онлайн-игр воспринимают плохо даже такие вещи. Лучше уточнять в сообществе конкретной игры.

Получаю ошибку "Failed to capture screen" или ничего не происходит после старта перевода.

Убедитесь, что нужное окно с текстом активно (и в фокусе). Также можете попробовать перезапустить Translumo или переоткрыть нужное окно. Захват экрана идет через DirectX API, оно временами работает довольно капризно.

Получаю ошибку "Text translation is failed" после некоторого времени успешной работы переводчика.

Велика вероятность, что вы получили временную блокировку (~30 мин. у DeepL) за большое число запросов. Переключитесь на другой переводчик или используйте список прокси.

Не могу включить Windows OCR

Убедитесь, что приложение запущено под Администратором. Программа каждый раз проверяет наличие установленных системных языковых пакетов через PowerShell.

Установка/скачивание пакетов для EasyOCR упала с ошибкой

Попробуйте повторить установку под VPN.

Некоторые горячие клавиши не работают

Вероятно, их обработку перехватывают другие приложения.

Получаю ошибку "Text detection is failed (TesseractOCREngine)"

Проверьте, что в пути расположения приложения нет кириллицы

Все ли так идеально

По первичным оценкам удалось добиться главного: универсальности и некого результата почти на всех вариантах использования.

Оно все еще не совершенно. На большинстве рядовых задачах механизм будет работать надежно, но проблемы начинается с безумными вариациями корейских, китайских шрифтов. Там всплывают неточности на каждом этапе: распознавание работает хуже, обученная модель оценки тоже чуть слабее, а переводчики менее совершенны.

Корейские шоу: «удачи в распознавании, брат».
Корейские шоу: «удачи в распознавании, брат».

Тем не менее я еще вижу большое пространство для допиливания всего этого безобразия. TODO лист выглядит пока как то так:

  • Реализация настройки горячих клавиш
  • Добавление большего числа языков
  • Повышение точности распознавания (дообучение EasyOCR, доработка пре-процессинга изображений)
  • Режим единоразового перевода
  • Окно перевода в «режиме субтитров» (временное отображение только актуальной строки перевода)

Скачать

UPD (19.06): Выпустил обновленный релиз 0.8.5, в котором основное внимания уделил улучшениям алгоритма по распознаванию текста с последовательным (побуквенным) появлением.

Если вам пригодилось приложение, буду благодарен за звезду на Github'e.

Написал приложение для экранного перевода текста в режиме реального времени в играх, видео и прочем
3.6K
22
11
11
990 комментариев
2250 ₽

Ты молодец! Делаешь нужное дело, а своих разработчиков нужно поддерживать! Не бросай софтинку, многим она пригодится :)

17
Ответить
2222 ₽

и звёздочку на гитхабе

61
Ответить
1000 ₽

Теперь я знаю как я буду играть в Старфилд
Спасибо, чумба!

333
Ответить