/LipReading-RussianLang

Lip-Reading: recognition Russian speech only by video-file input

Primary LanguagePython

Структура проекта

  • README.md - Описание репозитория
  • requirements.txt - Список зависимостей
  • DejaVuSans.ttf - Шрифт DejaVuSans (нужен чтобы писать русским текстом на кадрах)
  • Документация
    • FORMALIZATION.MD - формальное описание работы: проблематика, цели, задачи, развитие и пр.
    • DESCRIPTION.MD - комментарии, описание, полезные ссылки
    • maus_phonemes_info.txt - информация по фонемам с сервиса MAUS
    • maus_service_help.txt - документация по запросам к сервисам MAUS
  • Скрипты
    • get_info_from_youtube.py - получения с Youtube-видео: русских суббтитров в txt формате (без знаков препинания, парсинг из srt),исходного видео в mp4, обрезанного видео (передаются секунды до и после) в mp4, дорожки обрезанного видео в wav
    • get_maus_textgrid.py - получение разметки аудиодорожки в формате textGrid при помощи MAUS-TextAlignment
    • create_words_phonemes_dict.py - создание из словаря слов - словаря слово->фонемная транскрипция
    • get_phonemes_duration_stat.py - получение статистики по длительности фонем в кадрах (в разрезе каждой фонемы и в целом): min,max,mean,std,sum,sum_percent
    • get_phonewords_frames.py - получение файлов: русских слов по кадрам (из транскрипции), фонем по кадрам (самих фонем и ключей из словаря - нужно для классификатор в дальнейшем), фонемных транскрипций по кадрам
    • get_phonemes_duration_stat.py - получение статистике по количеству встреч фонем: сколько раз использовалась фонема, независимо от длины в кадрах
    • work_with_frames_funcs.py - библиотека с функциями по работе с кадрами
    • get_lips_video.py - получение видео губ из видео с лицом. ! Сейчас добавляется пустой кадр, если губ нет !
    • label_frames.py - добавление на видео текста из файла текста по фонемам
    • create_json_dataset.py - создание JSON-датасета (фонема, номер кадра, массив точек губ)
    • create_image_dataset.py - создание набора изображений губ с ключем фонем\фонемой в названии файла
    • get_draw_points_video.py - отрисовка точек губ на видео
    • get_lips_count_stat.py - получение статистики по количеству массивов точек губ (количеству кадров, на которые были распознаны губы) по фонемам
    • stretch_txts.py - объединение txt файлов из папки в один txt файл
    • stretch_jsons.py - объединение json файлов из папки в один json файл
  • Cловари
    • words_phonemes_1_5kk.txt - словарь {слово; фонемная транскрипция}. Содержит 1531154 слов. Удалены слова с пробелами и несловарными символами (кроме -), слова с - слиты в одно слово (- заменено на пустоту)
    • phonemes_with_examples.txt - словарь фонем с примерами слов
    • phonemes_keys.txt - словарь фонем с ключами
  • Датасет

Использование

Ссылка на Notebook (GoogleColaboratory) с классификацией по точкам

https://colab.research.google.com/drive/1TdXWQGwHd95oNEJWwLWHYQXE3HO7QaId?usp=sharing

Права по ссылке - только на просмотр. Чтобы использовать (изменять): либо нажать "Open in playground" - изменения не сохраняться, но можно менять; либо File->Save a copy in Drive и уже редактировать свой вариант

Ссылка на Notebook (GoogleColaboratory) для обработки Youtube-видео

https://colab.research.google.com/drive/10owAQGEvE1HsZrmy-CrpTw9AWc1c_MO4?usp=sharing

Права по ссылке - только на просмотр. Чтобы использовать (изменять): либо нажать "Open in playground" - изменения не сохраняться, но можно менять; либо File->Save a copy in Drive и уже редактировать свой вариант

Ссылка на Notebook (GoogleColaboratory) для соединения информации по нескольким видео

https://colab.research.google.com/drive/1mVKpLafqLHSBH2wS4ZJcBE0h1ZK3lqVi?usp=sharing

Права по ссылке - только на просмотр. Чтобы использовать (изменять): либо нажать "Open in playground" - изменения не сохраняться, но можно менять; либо File->Save a copy in Drive и уже редактировать свой вариант

Установка (клонирование)

git clone https://github.com/Ustelemov/LiReading-RussianLang

Установка зависимостей

Для установки всех требуемых зависимостей воспользуйтесь командой:

pip install -r requirements.txt

Получение информации с Youtube-видео

python get_info_from_youtube.py \
--u 'https://www.youtube.com/watch?v=bYMnnpJdNiU&t' \
--p '/content/outfolder' \
--s 0 \
--e 197
  • --u - ссылка на видео {Обязательный аргумент}
  • --p - путь к папке, в которую будет помещен файлы.txt. Дефолтно: /default
  • --s - секунда старта для обрезки видео. Дефолтно: 0. Если оставить нулем или указать 0 явно (то есть, если s==e==0), то файл будет использован целиком
  • --e - секунда окончания для обрезки видео. Дефолтно: 0. Если оставить нулем или указать 0 явно (то есть, если s==e==0), то файл будет использован целиком
  • --a - авто-сгенерированный субтитры брать или нет. Дефолтно:True

Файлы:

  • video_ytb.mp4 - исходный файл, скачанный с ютуба
  • video.mp4 - обрезанный файл из video_ytb.mp4, используется для извлечение аудиодорожки (если файл не обрязается - то данный файл не создается, для извлечения аудиодорожки используется исходный файл)
  • audio.wav - аудиодорожка, созданная по video.mp4
  • subtitles.txt - русские суббтитры (если есть, если нет - в консоли появится соответствующее сообщение), полученные с Youtube

Получение разметки аудиодорожки в формате textGrid при помощи MAUS-TextAlignment

python get_maus_textgrid.py \
--a '/content/outfolder/audio.wav' \
--t '/content/outfolder/subtitles.txt' \
--o '/content/outfolder/maus_out.TextGrid'
  • --a - путь к wav файлу {Обязательный аргумент}
  • --t - путь к txt файлу текстовой аннотации (транскрипции для wav файла) {Обязательный аргумент}
  • --o - путь для выходного TextGrid-файла, который будет создан. Дефолтно: /default/maus_out.TextGrid

Cоздание из словаря слов - словаря слово->фонемная транскрипция

python create_words_phonemes_dict.py \
--i '/content/words_1_5kk.txt' \
--o '/content/words_phonemes_1_5kk.txt'
  • --i - путь к входному файлу словоря {Обязательный аргумент}
  • --o - путь для выходного файла словаря слов->фонемной транскрипции. Дефолтно: /default/out_words.txt

Создание русских слов по кадрам (из транскрипции), фонем по кадрам (самих фонем и ключей из словаря - нужно для классификатор в дальнейшем), фонемных транскрипций по кадрам

python get_phonewords_frames.py \
--p '/content/outfolder/frames_align' \
--t '/content/outfolder/maus_out.TextGrid' \
--d '/content/LiReading-RussianLang/dicts/phonemes_keys.txt'
  • --p - путь к выходной папке, в которую буду помещены файлы. Дефолтно: /default
  • --t - путь к TextGrid файлу {Обязательный аргумент}
  • --f - кол-во FPS в видео. Дефолтно 25.0
  • --d - путь к словарю фонем с ключами {Обязательный аргумент} Файлы:
  • phonemekeys_frames.txt - ключи фонем по кадрам
  • phonemes_frames.txt - фонемы по кадрам
  • phonemeswords_frames.txt - фонемные транскрипции по кадрам
  • words_frames.txt - слова по кадрам

Cкрипт для получения статистики о встречи фонем

python get_phonemes_appearence_stat.py \
--p '/content/outfolder/appearence_stat' \
--d '/content/LiReading-RussianLang/dicts/phonemes_keys.txt' \
--f '/content/outfolder/frames_align/phonemes_frames.txt'
  • --p - путь к выходной папке, в которую буду помещены файлы. Дефолтно: /default
  • --d - путь к словарю фонем с ключами {Обязательный аргумент}
  • --f - путь к файлу фонем по кадрам {Обязательный аргумент}
  • --e - требуется ли исключить фонемы (стандартно <:p>) из рассмотрения. Дефолтно: False

Информация:

    1. Сколько раз фонема появлялась - график phonemes_appears_count.png с количество встреч каждой фонемы + расписанное в phonemes_appears_info.txt по каждой фонеме количество
    1. Процент появлений от общего числа появлений - график phonemes_appears_percent с процентом встреч от общего количества встреч по каждой фонеме + расписанная в phonemes_appears_info.txt информация по каждой фонеме
    1. Минимальное количество появлений - min в phonemes_appears_info.txt
    1. Максимальное количество появлений - max в phonemes_appears_info.txt
    1. Среднее количество появлений - mean в phonemes_appears_info.txt -6. Среднее квадратичное отклонение количества появлений - std в phonemes_appears_info.txt

Скрипт для получения статистики по длительности фонем в кадрах

python get_phonemes_duration_stat.py \
--p '/content/outfolder/duration_stat' \
--d '/content/LiReading-RussianLang/dicts/phonemes_keys.txt' \
--f '/content/outfolder/frames_align/phonemes_frames.txt'
  • --p - путь к выходной папке, в которую буду помещены файлы. Дефолтно: /default
  • --d - путь к словарю фонем с ключами {Обязательный аргумент}
  • --f - путь к файлу фонем по кадрам {Обязательный аргумент}
  • --e - требуется ли исключить фонемы (стандартно <:p>) из рассмотрения. Дефолтно: False

Информация

    1. Относительно каждой фонемы информация по длительности в кадрах:
    • 1.1. Минимальная длительность в кадрах по каждой фонеме - min в phonemes_duration_stat.txt, график - min_duration_graph.png
    • 1.2. Максимальная длительность в кадрах по каждой фонеме - max в phonemes_duration_stat.txt, график - max_duration_graph.png
    • 1.3. Средняя длительность в кадрах по каждой фонеме - mean в phonemes_duration_stat.txt, график - mean_duration_graph.png
    • 1.4. Отклонение длительности в кадрах по каждой фонеме - std в phonemes_duration_stat.txt, график - std_duration_graph.png
    • 1.5. Сумма длительности в кадрах по каждой фонеме - sum в phonemes_duration_stat.txt, график - sum_duration_graph.png
    • 1.6. Процент длительности фонемы в кадрах относительно всех кадров - sum_percent в phonemes_duration_stat.txt, график - sum_duration_percent_graph.png
    1. Общая статистика по всем фонемам:
    • 2.1. Минимальная длительность в кадрах - min в phonemes_duration_stat.txt (блок общей статистики)
    • 2.2. Максимальная длительность в кадрах - max в phonemes_duration_stat.txt (блок общей статистики)
    • 2.3. Средняя длительность в кадрах - mean в phonemes_duration_stat.txt (блок общей статистики)
    • 2.4. Отклонение длительности в кадрах - std в phonemes_duration_stat.txt (блок общей статистики)

Получение видео губ

python get_lips_video.py \
--i '/content/outfolder/video.mp4' \
--o '/content/outfolder/lips_only_depressed_200f.mp4' \
--d True \
--c 200
  • --i - путь к входному видео-файлу с говорящим лицом, с которого будем получать губы {Обязательный аргумент}
  • --o - путь для выходного файла {Обязательный аргумент}
  • --w - ширина выходного файла (и соотвественно ширина файлов губ). Дефолтно: 320
  • --h - высота выходного файла (и соответственно высота файлов губ). Дефолтно: 240
  • --c - количество кадров, которые следует обработать. -1 - обрабатывать все кадры. Дефолтно:-1
  • --d - нужно ли депрессировать качество (размер) видео до 854х480. True - нужно. Дефолтно: False

Добавление аудиодорожки к видеофайлу

Для добавление аудиодорожи видео к файлу можно воспользоваться библиотекой ffmpeg

ffmpeg -i '/content/out.mp4' -i '/content/pedagog/audio.wav' '/content/outout.avi'
  • первый -i параметр (/content/out.mp4) - путь к .mp4 видео-файлу
  • второй -i параметр (/content/pedagog/audio.wav) - путь к .wav аудио-файлу
  • /content/outout.avi - путь к .avi выходном файлу

Добавление текста на видео

Текст добавляется по кадрово из файла, где каждая строчка - текст на кадр. Требуется равное количеству кадрам количество строчек в файле

python label_frames.py \
--i '/content/outfolder/lips_only_depressed_200f.mp4' \
--o '/content/outfolder/lips_phonemed_depressed_200f.mp4' \
--f '/content/LiReading-RussianLang/DejaVuSans.ttf' \
--t '/content/outfolder/frames_align/phonemes_frames.txt' \
--a True
  • --i - путь к входному видео-файлу, на кадры которого будет добавлен текст
  • --o - путь для выходного файла {Обязательный аргумент}
  • --f - путь к ttf файлу шрифта (для того, чтобы писать русскими буквами используется DejaVuSans.tff)
  • --t - путь к текстовому файлу текста по кадрам
  • --a - разрешено ли разное количество кадров в видео и в тексте по кадрам (если разное, в видео меньше - из текстового файла будут брать соответствующее первое количество записей

Создание датасета губ (изображение + фонем\ключ фонемы в названии)

python create_image_dataset.py \
--i '/content/outfolder/video.mp4' \
--p '/content/outfolder/image_dataset' \
--k '/content/outfolder/frames_align/phonemes_frames.txt' \
--w 240 \
--h 240 \
--c 200 \
--d True
  • --i - путь к входному видео-файлу, с которого будут брать изображения губ {Обязательный аргумент}
  • --o - путь для папки, куда буду добавлены изображеня {Обязательный аргумент}
  • --k - путь к файлу фонем\ключей фонем (с него буду браться названия для файлов) {Обязательный аргумент}
  • --w - ширина выходного изображения. Дефолтно: 320
  • --h - высота выходного изображения Дефолтно: 240
  • --c - количество кадров, которые следует обработать (когда не хотим создавать датасет, а просто посмотреть фото). -1 - обрабатывать все кадры. Дефолтно:-1
  • --d - нужно ли депрессировать качество (размер) видео до 854х480. True - нужно. Дефолтно: False

Создание JSON датасета (фонема, номер кадра, массив точек губ)

python create_json_dataset.py \
--i '/content/outfolder/video.mp4' \
--o '/content/outfolder/json.json' \
--k '/content/outfolder/frames_align/phonemes_frames.txt' \
--d True
  • --i - путь к входному видео-файлу, с которого будут получены точки губ {Обязательный аргумент}
  • --o - путь к выходному JSON-файлу {Обязательный аргумент}
  • --k - путь к файлу фонем по кадрам {Обязательный аргумент}
  • --d - нужно ли депрессировать качество (размер) видео до 854х480. True - нужно. Дефолтно: False

Отрисовка точек губ на видео

python get_draw_points_video.py \
--i '/content/outfolder/video.mp4' \
--o '/content/outfolder/lip_points_on.mp4' \
--c 200 \
--d True
  • --i - путь к входному видео-файлу, с которого будут получены точки губ {Обязательный аргумент}
  • --o - путь к выходному файлу {Обязательный аргумент}
  • --c - количество кадров, которые следует обработать. -1 - обрабатывать все кадры. Дефолтно:-1
  • --d - нужно ли депрессировать качество (размер) видео до 854х480. True - нужно. Дефолтно: False

Получение статистики по количеству массивов точек губ (количеству распознаных кадров) по фонемам из JSON файла

python get_lips_count_stat.py \
--i '/content/outfolder/text.json' \
--o '/content/outfolder/json_stat'
  • --i - путь к входному JSON-файлу
  • --o - путь к выходной папке, в которую буду помещенны файлы

Информация:

  • Количество массивов точек губ по фонемам в текстовом представление (столбец фонем\столбец количества) phonemes_wlips_count_stat.txt
  • График распределения количества массивов точек губ по фонемам - wlips_count_graph.png

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

python stretch_txts.py \
--i '/content/input' \
--o '/content/result.txt'

Файлы будут записаны в порядке сортировки по пути, то есть нужно сделать файлы с одинаковыми именами, а порядок указать цифрами, например text1.txt будет записан раньше, чем text2.txt

--i - путь к папке с txt-файлами, которые требуется объеденить --o - путь к выходному txt-файлу

Соеденить JSON-файлы из папки в один (нужно для JSON-датасетов, когда видео разбивается на несколько)

python stretch_jsons.py \
--i '/content/input' \
--o '/content/result.json'

Файлы будут записаны в порядке сортировки по пути, то есть нужно сделать файлы с одинаковыми именами, а порядок указать цифрами, например json1.json будет записан раньше, чем json2.json

--i - путь к папке с JSON-файлами, которые требуется объеденить --o - путь к выходному JSON-файлу

Todo-лист

  • 1. Создать файл с зависимостями - requirements.txt
  • 2. Создать скрипт для получения с Youtube-видео: русских суббтитров в txt формате (без знаков препинания, парсинг из srt),исходного видео в mp4, обрезанного видео (передаются секунды до и после) в mp4, дорожки обрезанного видео в wav
  • 3. Создать скрипт для получения разметки аудиодорожки в формате textGrid при помощи MAUS-TextAlignment
  • 4. Создать скрипт для получения из словаря слов - словаря слово->фонемная транскрипция
  • 5. Добавить словари: слова->транскрипции по фонемам, словарь фонем (с ключом и значением, для работы классификатора), словарь фонем с примерами использования
  • 6. Создать скрипт для получения файлов: русских слов по кадрам (из транскрипции), фонем по кадрам (самих фонем и ключей из словаря - нужно для классификатор в дальнейшем), фонемных транскрипций по кадрам
  • 7. Создать скрипт для получения статистики о встречи фонем:
    • 7.1. Сколько раз фонема появлялась
    • 7.2. Процент появлений от общего числа появлений
    • 7.3. Минимальное количество появлений
    • 7.4. Максимальное количество появлений
    • 7.5. Среднее количество появлений
    • 7.6. Среднее квадратичное отклонение количества появлений
  • 8. Создать скрипт для получения статистики по длительности фонем в кадрах:
    • 8.1. Относительно каждой фонемы информация по длительности в кадрах:
      • 8.1.1. Минимальная длительность в кадрах по каждой фонеме
      • 8.1.2. Максимальная длительность в кадрах по каждой фонеме
      • 8.1.3. Средняя длительность в кадрах по каждой фонеме
      • 8.1.4. Отклонение длительности в кадрах по каждой фонеме
      • 8.1.5. Сумма длительности в кадрах по каждой фонеме
      • 8.1.6. Процент длительности фонемы в кадрах относительно всех кадров
    • 8.2. Общая статистика по всем фонемам:
      • 8.2.1. Минимальная длительность в кадрах
      • 8.2.2. Максимальная длительность в кадрах
      • 8.2.3. Средняя длительность в кадрах
      • 8.2.4. Отклонение длительности в кадрах
  • 9. Создать библиотеку с функциями по работе с кадрами
  • 10. Создать скрипт по получение видео выровненных губ (+возможность добавить звуковую дорожку)
  • 11. Создать скрипт для добавление на видео данных (текста) из файлов фонем\слов\фонемных транскрипций по кадрам
  • 12. Создать скрипт для создания датасета: изображение губ + номер фонемы в названии
  • 13. Создать скрипт для создания JSON датасета с координатам губ по кадрам
  • 14. Создать скрипт для отрисовки точек губ на видео
  • 15. Создать скрипт для получения статистики о количестве точек губ по каждой фонеме (получение из JSON-файла)
  • 16. Создать Notebook GoogleColaboratory для подготовки датасета. Обработать первое видео (добавить информацию в репозиторий)
  • 17. Обработать большое видео: подготовить транскрипцию, обработать (получить JSON-датасет), залить в репозиторий
  • 18. Создать скрипт для соединения txt-файлов из папки в один
  • 19. Создать скрипт для соединения JSON-файлов из папки в один
  • 20. Создать GoogleColaboratory по классификации:
    • 20.1. Визуализировать распределение признаков
    • 20.2. Рассчитать общую классификацию (всех фонем)
    • 20.3. Рассчитать классфикацию без паузы
    • 20.4. Рассчитать классификацию паузы и остальных фонем
    • 20.5. Расчитать среднюю попарную классификацию
  • 21. Придумать решение проблемы c фонемами а и о. Пример проблемы:
    • аббатскому;a b b a t s k a m u
    • аббатскою;a b b a t s k o j u