Хорош ли ваш английский? Мой – нет. По крайней мере точно недостаточно, чтобы обходиться без переводчика в играх.
Недолгий поиск бесплатных программ в интернете мне не помог. Возможно, я просто плохо искал :) Но когда я поймал себя на мысли, что сейчас возьму в руки сотовый и буду переводить экран с помощью камеры, я понял, что пора спасаться. И путь к спасению - сделать переводчик самому.
Я нашел широко известную в узких кругах программу распознавания текста Tesseract OCR и свободное API для Google Translate. В результате получилась программа, которая может на лету переводить выделенную надпись на экране. Выглядит это примерно так: вы зажимаете горячую клавишу Win+Alt и прямоугольной областью выделяете часть изображения, где находится непонятный текст. Область выделяется, только пока зажата горячая клавиша. Вуаля – перед вами перевод во всплывающей подсказке! Выглядит это примерно вот так:

Можно распознать и с картинки в буфере обмена через меню иконки в трее:

Ссылки:
Собственно проект AssistAnt https://github.com/AantCoder/AssistAnt/releases/latest
Компонент распознавания текста Tesseract OCR https://github.com/tesseract-ocr
Переводчик Google Translate Rest API (Free) с помощью GTranslatorAPI https://github.com/franck-gaspoz/GTranslatorAPI
Если совсем коротко, то это всё :) Некоторые нюансы и альтернативные способы использования есть в пункте приложения «О программе». Дальше опишу технические сложности, с которыми столкнулся в процессе разработки для заинтересовавшихся.

Горячие клавиши всё портят

Какую клавишу на клавиатуре ни возьми: или занята, или неудобна. Если кажется, что обнаружил свободную и удобную, то значит просто не нашел программу, которая уже её использует. Поэтому я не стал биндить горячую клавишу, а решил лишь отлавливать нажатие на Win+Alt. По моему разумению, ни одна программа не использует две эти клавиши отдельно от остальных. Разумеется, если вместе с Win+Alt нажать ещё что-то третье, то мой переводчик не отреагирует.
Такая комбинация хорошо выполняет свою цель: позволяет выделить область на экране, минимально влияя на активную программу. Правда, есть один минус, опишу его в следующем пункте.

Перевод из всплывающих подсказок

В попытке выделить текст двигаем мышкой – она покидает элемент интерфейса – всплывающая подсказка исчезает. Это заставило меня сделать стандартную систему, как при вырезании скриншотов. Если нажать Win+Alt и отпустить, не двигая мышкой, то создается скрин всего экрана, который открывается поверх всех окон. И уже в нем предлагается выделить область для перевода, как при стандартной комбинации Win+Shift+S (правда, реализовано это не столь красиво). Дальше всё как в первом способе: выдается всплывающая подсказка с переводом, за исключением того, что выделенное изображение помещается в буфер обмена (зачем? просто могу).

Плохой разбор мелкого текста

Оказалось, что Tesseract (может быть и все подобные?) плохо распознает текст с высотой строки меньше 20 пикселей. Особенно, когда он с тенью или размытием. Эффекты безусловно очень помогают прочесть надпись человеку, но нейронке не нравятся.
Помучавшись несколько вечеров, накидал сложную комбинацию простых фильтров изображений. После этого мелкий текст иногда стал читаться даже лучше, чем текст среднего размера. Из-за этого решил добавить повторное распознавание без фильтров, если качество распознания было меньше 90%. В конечном итоге вышло вот так:
Первый прогон (хорош для самого мелкого текста):

  • Увеличиваем картинку в 2 раза (красиво, с «высококачественной бикубической интерполяцией»),

  • Переводим в градации серого,

  • Увеличиваем изображение, добавляя пустую рамку в 7 пикселей и пустое пространство справа на 200 (так лучше распознаются короткие слова. Видимо, в вытянутом изображении ожидается меньшее количество строк),

  • Увеличиваем резкость,

  • Увеличиваем картинку ещё в 2 раза,

  • Ещё раз увеличиваем резкость (двойной подход немного уменьшает артефакты).

Второй прогон (обработка попроще, если качество распознания с первого прогона меньше 90%):

  • Увеличиваем картинку в 3 раза,

  • Переводим в градации серого,

  • Увеличиваем резкость

Третий прогон (вдруг при обесцвечивании текст стало не видно, или резкость ухудшает распознаваемость текста):

  • Увеличиваем картинку в 3 раза.

Медленно работает

В фильтрах многое требует доработки. Они как были сделаны на скорую руку, так и остались. Очевидно, что если выделить больше половины экрана, то программа начинает уходить в себя, пытаясь применить все эти фильтры (особенно хорошо подвешивает увеличение кол-ва пикселей в 16 раз).
Поэтому, а также из-за того, что как правило, в крупных выделенных областях экрана и шрифт также крупный, был добавлен выбор фильтров на основе размера изображения:

  • Если размер изображения больше миллиона пикселей (ширина*высота), то не обрабатываем его, а отправляем на распознавание как есть.

  • Если изображение больше 20000 пикселей, то увеличиваем только в 3 раза. В этом случае во всплывающей подсказке после % появляется *.

  • Если размер изображения меньше указанного в предыдущем пункте, то применяем все описанные выше фильтры. В этом случае во всплывающей подсказке после % появляется * с числом прогонов, которые понадобились, чтобы добиться качества распознавания выше 90%.

Утечка памяти

Иногда проще убить, чем прокормить. Так я и поступил, не желая возиться с утечкой памяти в чужих библиотеках (правда же в чужих?..) Теперь, спустя пять минут с момента последнего обращения к переводчику, программа автоматически перезапустится, и уж точно освободит всю память. Если же её будут интенсивно использовать на слабых компьютерах, то должен помочь перезапуск после 20 переводов: программа ждет 30 секунд после последней активации (чтобы дать прочитать текст) и перезапускается. Надеюсь, это будет достаточно незаметно для пользователя.

Переносы строк

Спасибо комментаторам @aborouhin, @danilasar и другим – открыли мне глаза на ухудшение качества перевода из-за переноса строк. Google Translate видя текст на разных строках воспринимает его как отдельные предложения. Первая мысль: отказаться от Google Translate удалить переносы строк. Но тогда переводчик может начать воспринимать, например, списки как единое предложение. А даже если и нет, то мы теряем форматирование текста.
Вдоволь помучив переводчик появилось такое решение: на место переноса вставить спец. разделитель, который переводчик не может игнорировать, но и предложение не разрывает.
Это решение дало хороший результат, но оно не идеальное, так как переводчик не может свободно менять слова в предложении.

Вот пример старого варианта с двумя строками:
Okay—now we're going
to check your reflexes.
Хорошо, теперь мы собираемся
чтобы проверить свои рефлексы.

Пример хорошего перевода:
Okay—now we're going to check your reflexes.
Ладно, сейчас мы проверим твои рефлексы.

Пример с подстановкой (в переводе ## заменяется на перенос строки):
Okay—now we're going ## to check your reflexes.
Ладно, теперь мы собираемся ## проверить твои рефлексы.

Вроде бы самое интересное описал. Сам проект можно посмотреть на гитхабе: https://github.com/AantCoder/AssistAnt
Скажу с лишним хвастовством – программа классная. Мне с моим ужасным знанием английского очень помогает.


P.S. Если есть какие-то комментарии, идеи, что можно улучшить или предложения по поводу производительности, то напишите мне здесь или в Issues на гитхаб.

UPD 27.11.2022: Добавил раздел Переносы строк, обновил картинку

Комментарии (30)


  1. danilasar
    25.11.2022 20:38
    +1

    Насколько я помню, Тессеракт может в значительно большее количество языков. При дальнейшем развитии программы, думаю, было бы неплохо добавить поддержку тех языков, которые доступны и в этой библиотеке, и в Google Translate API.
    P. S. Что касается утечек памяти, суицид - тоже не выход) Если, опять же, программа будет развиваться, с этим нужно бороться прежде всего.


    1. Ant00 Автор
      25.11.2022 22:18

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


    1. Ant00 Автор
      25.11.2022 22:22
      +1

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


      1. funca
        26.11.2022 01:30
        +1

        Обычно так и поступают - отправляют в отдельный процесс и периодически перезапускают.

        Кстати в MacOS функция распознавания текста на картинках уже примерно год как встроена в стандартный просмоторщик. Аналогично работает в браузере и некоторых других приложениях. Выглядит так, что при выделении мышкой области на изображении она выделяется как обычный текст. Иногда на сайтах уже не понятно где текст текстом, а где картинкой.


  1. aborouhin
    25.11.2022 20:40

    Любопытно, как в примере с картинок в посте Вы умудрились получить неправильный перевод (как минимум лишнее "чтобы"), если текст, судя по картинке с messagebox'ом, распознан корректно, и Google Translate, если ввести в него этот текст, переводит его тоже корректно. Это какой-то неправильный API...


    1. danilasar
      25.11.2022 20:44
      +2

      Очень похоже на то, что программа перевела эти две строчки по отдельности, не пытаясь их объединить в целое предложение.


      1. Ant00 Автор
        25.11.2022 20:52

        Нет, объединяю в единый текст. На перевод могут влиять переносы строк


        1. danilasar
          25.11.2022 20:54
          +3

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


          1. Ant00 Автор
            25.11.2022 22:07
            +1

            Думаю действительно будет лучше, если убрать переносы строк...


            1. funca
              26.11.2022 01:32

              Форматирование текста перед отправкой нужно готовить самому - он ведь только переводчик, а не угадыватель грамматики и пунктуации. Куски разделенные переносами строк воспринимает как разные фрагменты.

              У бесплатного Google Translate API было ограничение на количество запросов. До некоторой степени решалось с помощью пула проксей или тор. Сервис из этого не сделать, но для мелко-домашнего применения годилось.


    1. Ant00 Автор
      25.11.2022 20:50

      Всё как есть в самом гугл переводчике

      Вот текст в виде текста:

      Okay—now we're going
      to check your reflexes.


      1. aborouhin
        25.11.2022 21:04

        Действительно, Гугл Транслейт не может понять, что разрыв строки тут не несёт смыслового значения. Удивлён - для перевода текста, скопированного из PDF или plain text с заданной максимальной шириной строки, это ж боль :(

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


        1. Ant00 Автор
          25.11.2022 22:08

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


          1. truetunkin
            25.11.2022 23:49

            В такой ситуации возможно самым простым решение будет просто переехать на нормальный переводчик, без танцев с бубном, переносами строк, тем более определением фраз. У яндекс переводчика есть неплохой api - https://yandex.ru/dev/translate/doc/dg/reference/translate.html

            У bing переводчика вроде тоже.


        1. AlexCzech01
          26.11.2022 11:34

          Потому что для него разрыв строки несет смысловое значение - для него это начало нового предложения.

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


          1. aborouhin
            26.11.2022 14:57

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


  1. DinoZavr2
    25.11.2022 21:28
    -1

    Странный юмор.. Нет, всё таки нормальный.


  1. 314159abc
    25.11.2022 23:49

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


  1. janvarev
    26.11.2022 00:40
    +1

    Крайне рекомендую Maverick OCR Helper с поддержкой: английского и японского, а также DeepL (что качественней).
    Тыкаем на ~, рисуем прямоугольник, из которого будет распознаваться.
    Можно сделать активные области на клавиши 1-0 + графическую обработку изображения - чтобы распознавалось Тессерактом лучше.

    Видюшка с объяснением, как работать.

    Если нужно, я для него даже локальный HTTP API написал.


    1. Ant00 Автор
      26.11.2022 08:44
      +1

      Воот! Я знал, что плохо искал, спасибо! :)

      Скачал, бегло посмотрел. Программа классная, особенно облегченная Ёлочка. Пожалуй, я бы свою не писал, если бы её видел: почти полные аналоги. Вот их различия, которые я увидел сразу:

      • Занять горячую клавишу Ё это слишком жестко. Хотя можно Alt+ или Ctrl+, но всё ещё не идеально (по моему скромному мнению)

      • Перевод более гладкий. Вероятно, из-за лишних переносов строк у меня. Нужно поправить :)

      • Чуть хуже, чем у меня, интеграция с программами: он делает скрин, для выделения области в нем, из-за чего программа с которой переводят, теряет фокус. Присутствуют нажатия не на хоткей: это и дольше, и мешает игровому процессу.

      • Красивое, настраиваемое окошко. Перевод можно выделить и скопировать. У меня это нужно сделать методом выделения области, а потом нажать в трее Перевести. Наверное, нужно поменять на копирование сразу перевода в буфер.

      • Я как-то не так сделал выделение по скрину :) Оно у меня немного тормозит

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

      • Мелкий текст обе программы одинаково хорошо видят.

      • Нет функции перевода по тексту из компонента WinAPI (у меня это Win+Alt и после +Ctrl). Не то чтобы это минус, программа то по переводу изображений. Но в некоторых, преимущественно старых, программах, где это можно сделать, взять для перевода текст выглядит логичней.

      • У меня можно отдельно перевести и/или распознать текст и картинку по меню в трее


  1. j_larkin
    26.11.2022 11:33
    +2

    Сколько сил тратят люди только для того, чтобы не тратить сил на изучение языка )


    1. 314159abc
      27.11.2022 22:50
      +1

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


  1. Arhammon
    26.11.2022 11:33

    С точки зрения совершенствования английского - интереснее вариант не переводчика, а именно словаря.


  1. Ant00 Автор
    27.11.2022 15:25

    UPD 27.11.2022: Добавил раздел Переносы строк, обновил картинку


  1. mrkaban
    28.11.2022 07:42
    +1

    Спасибо за разработку свободной программы! Записал себе, дома посмотрю.


    1. Ant00 Автор
      28.11.2022 08:12

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


  1. in11w
    28.11.2022 10:56
    +1

    Давно пользуюсь аналогом https://github.com/OneMoreGres/ScreenTranslator

    Сейчас, похоже, сломался - перевод не отображает.


    1. Ant00 Автор
      28.11.2022 12:32

      Спасибо за ссылку


  1. ferini
    28.11.2022 14:33

    Хорошая программа, удачи вам в её развитии!


  1. gibaca
    28.11.2022 16:27

    Главное не теряйте энтузиазм! либо нужно найти способ монетизации!