乙Py先生のプログラミング教室
初学者のためのプログラミング学習サイト

日向坂46

今回は音声に合わせて
リップシンク動画を作成できる
「Wav2Lip」でリップシンク動画を
作ってみました


解説動画はこちら



はじめに:

Wav2Lip: Accurately Lip-syncing Videos In The Wild

このWav2Lipというライブラリは
動画内の人物の口の形を
音声にあわせて変える事ができます

これを使えば簡単に
リップシンク動画を作る事ができます

音声に合わせて、動画の方を変えられるので
言ってない事を言ってる様に
見せる事ができます


インストール方法

Google Colabでの利用方法です

1.ランタイムのタイプを変更から「GPU」に変更する

CPUでは利用できないようなので
ランタイムの変更から「GPU」
に切り替えておきましょう

2.ライブラリのインストール
結構たくさんあるんですが
次のコードでライブラリ群のインストールが出来ます

Google Drive を利用するので
空き容量は確認しておきましょう
# MiniCondaのインストール
%%bash
MINICONDA_INSTALLER=Miniconda3-py37_4.8.2-Linux-x86_64.sh
MINICONDA_DOWNLOAD_HP=https://repo.anaconda.com/miniconda
MINICONDA_PREFIX=/usr/local
wget $MINICONDA_DOWNLOAD_HP/$MINICONDA_INSTALLER
chmod +x $MINICONDA_INSTALLER
./$MINICONDA_INSTALLER -b -f -p $MINICONDA_PREFIX
# Googleドライブのマウントと作業フォルダへの移動
from google.colab import drive
drive.mount('/content/drive')
%cd '/content/drive/My Drive/'
!mkdir W2L
%cd 'W2L'
# パッケージのインストール
!git clone https://github.com/Rudrabha/Wav2Lip.git
%cd Wav2Lip
!pip install -r requirements.txt
!pip install resampy==0.3.1
3.モデル(wav2lip.pth)を「Wav2Lip/checkpoints」に配置

以下のURLよりモデルをダウンロードして
checkpointsフォルダにアップロードする
モデルのダウンロード先

リンクは「Model」の「Wav2Lip」の「Link」です
ダウンロードやアップロードに時間がかかるので
Google DriveのUIで操作する方が早いかもしれません


4.音声と動画を「Wav2Lip」フォルダの直下に配置

音声(WAV形式) : ファイル名.wav
動画(MP4形式) : ファイル名.mp4
という名称でファイルを置いておきましょう

配置したファイルの確認は
次のコードで行えます

# 音声ファイルの確認
from IPython.display import Audio

audio_file_path = "kosakana.wav"
Audio(audio_file_path)

5.推論を実行

resultsフォルダ内に結果出力されます

!python inference.py \
    --checkpoint_path checkpoints/wav2lip.pth \
    --face 動画ファイル名.mp4 \
    --audio 音声ファイル名.wav

あとは出来上がりを確認してみましょう
どんなリップシンク動画になったのかは
動画をご覧ください

それでは

今回は2枚の静止画から
クッソかわいい動画を作成してみました

解説動画はこちら





今回使用するのは
FILM(Frame Interpolation for Large Motion)
という技術でs

ニューラルネットワークを用いた
フレーム補間技術になります


2枚の静止画の間を繋ぐ様に静止画を作成して
動画化する事ができます

デモなどはこちらから参照する事ができます

FILMのgit

こちらのサイトのデモを使って
静止画を動画化してみました

1フレーム目はこの画像
frame1


2フレーム目はこの画像です
frame2


この間のフレームを補完してくれる訳ですね

出来上がったのはこんな感じ

71dt0-6t2tb


2枚の間の違和感なく
フレームが保管されているのでは
ないでしょうか!!

めちゃくそカワイイですねーーーーー

こんな感じで
2枚の静止画を用意すれば動画にできるので
たくさん用意すれば、動画作品を
作る事も可能ではありそうですね

うまく使えば面白い技術だと思いますので
試したい方はデモサイトを
覗いてみて下さい

それでは

今回はバビ語をマスターしたいなーと思い
バビ語変換を試みてみました。

解説動画はこちら



さて、まずバビ語についてですが
近年では最近見る機会が減りましたが
日向坂46齊藤京子さんが使いこなす
入れ詞の一種です。

一応日向坂46のキャプテン
佐々木久美さんは通訳出来るみたいです。

元々は1970年代初頭の中三トリオ
(森昌子、桜田淳子、山口百恵)が
内緒話をするのに使っていたという
発祥起源説があります。

ルールはいたって簡単で
ば・び・ぶ・べ・ぼを言葉の間に挟んでしゃべる

「はい」→「はばいび」
ア行は「ば」・イ行は「び」・・・
のように言葉にばびぶべぼを挟むだけです。

少し細かいルールを追加すると

ー のあとは前の母音のバ行をつける
「らーめん」 → 「らばーばめべんぶ」

小さい「っ」はそのまま
「ついったー」→「つぶいびったばーば」

となります。

さて、これをプログラムに置き換えてみましょう。

コードはこちら
import re

# 文字列の定義
row_a = [s for s in 'あかさたなはまやらわがざだばぱ']
row_i = [s for s in 'いきしちにひみりぎじぢびぴ']
row_u = [s for s in 'うくすつぬふむゆるんぐずづぶぷ']
row_e = [s for s in 'えけせてねへめれげぜでべぺ']
row_o = [s for s in 'おこそとのほもよろをごぞどぼぽ']
row_kya = re.split('(..)','きゃぎゃしゃじゃちゃぢゃにゃひゃびゃぴゃみゃりゃ')[1::2]
row_kyu = re.split('(..)','きゅぎゅしゅじゅちゅぢゅにゅひゅびゅぴゅみゅりゅ')[1::2]
row_kyo = re.split('(..)','きょぎょしょじょちょぢょにょひょびょぴょみょりょ')[1::2]

# 辞書の定義
dict_a = { k:k+'ば' for k in row_a}
dict_i = { k:k+'び' for k in row_i}
dict_u = { k:k+'ぶ' for k in row_u}
dict_e = { k:k+'べ' for k in row_e}
dict_o = { k:k+'ぼ' for k in row_o}
dict_kya = { k:k+'ば' for k in row_kya}
dict_kyu = { k:k+'ぶ' for k in row_kyu}
dict_kyo = { k:k+'ぼ' for k in row_kyo}
babigo_dict = {**dict_a, **dict_i, **dict_u, **dict_e, 
               **dict_o, **dict_kya, **dict_kyu, **dict_kyo}

# 逆変換辞書の定義
icd_a = { k+'ば':k for k in row_a}
icd_i = { k+'び':k for k in row_i}
icd_u = { k+'ぶ':k for k in row_u}
icd_e = { k+'べ':k for k in row_e}
icd_o = { k+'ぼ':k for k in row_o}
icd_kya = { k+'ば':k for k in row_kya}
icd_kyu = { k+'ぶ':k for k in row_kyu}
icd_kyo = { k+'ぼ':k for k in row_kyo}
icd_dict1 = {**icd_a , **icd_i , **icd_u , **icd_e , **icd_o }
icd_dict2 = {**icd_kya , **icd_kyu , **icd_kyo}
icd_dict3 = {'ーば':'ー' , 'ーび':'ー' , 'ーぶ':'ー' , 'ーべ':'ー' , 'ーぼ':'ー'}
b_dict = {**icd_dict1 , **icd_dict2 , **icd_dict3}
# 文章をバビ語に変換する
def change_babigo(text):
    babigo,out = '',''
    for i,s in enumerate(text):
        if s in row_a + row_i + row_u + row_e + row_o:
            if ''!=out:
                babigo += babigo_dict[out]
            if i == len(text)-1:
                babigo += babigo_dict[s]
            out = s
        elif s in ['っ']:
            babigo += babigo_dict[out] + s
            out = ''
        elif s in ['ゃ','ゅ','ょ']:
            out += s
            babigo += babigo_dict[out]
            out = ''
        elif 'ー'==s:
            tmp = babigo_dict[out]
            babigo += tmp + 'ー' + tmp[-1]
            out = ''
        elif s in ['、','。']:
            if ''!=out:
                babigo += babigo_dict[out]
                babigo += s
            out = ''
    return babigo
text = "らーめんだいすき、さいとうきょうこです。"
print(change_babigo(text))
らばーばめべんぶだばいびすぶきび、
さばいびとぼうぶきょぼうぶこぼでべすぶ。
text = "あたしのなまえは、かすがです。"
print(change_babigo(text))
あばたばしびのぼなばまばえべはば、
かばすぶがばでべすぶ。


こんな感じで文章をバビ語に変換できます。
制約として「ひらがな」だけを
変換することができます。
「ひらがな推し」なので・・・


次に、バビ語を通訳してみましょう。

バビ語の文章を元に戻すのも考えてみました。

こんな感じになりました。
# バビ語を元の文章に戻す
def babigo_reverse(babigo):
    for k,v in icd_dict2.items():
        babigo = babigo.replace(k,' ' + k + ' ')
    for k,v in icd_dict1.items():
        babigo = babigo.replace(k,' ' + k + ' ')
    babigo = babigo.replace('  ',' ')
    tmp = babigo.split(' ')
    out = ''
    for t in tmp:
        if t in b_dict:
            out += b_dict[t]
        else:
            out += t
    return out
babigo = 'らばーばめべんぶだばいびすぶきび、さばいびとぼうぶきょぼうぶこぼでべすぶ。'
print(babigo_reverse(babigo))
らーめんだいすき、さいとうきょうこです。


ということで、バビ語に変換と
バビ語から元に戻すプログラムを
作ってみました。

これでニュースなども全部
バビ語にすることができますね!!!!

今回はバビ語マスターのための
バビ語変換プログラムでした。

それでは。

 

今回はあの
丹生ちゃんのタルタルチキンしりとりを
再現するプログラムを考えてみました。

解説動画はこちら



知らない人のために補足しておくと
日向坂46の丹生あかりちゃんには
なんかしらの言葉をしりとりで
タルタルチキンに繋げる・・・
という特技があります。

それをプログラムで再現します。

さて、今回のテーマはしりとりです。
しりとりをプログラムで行うには
単語のデータがないとうまくはいきません。

そこでMeacbの辞書を使って
しりとりを行えるような
プログラムを作っていきたいと思います。

Google Colab上で動くようなコードになってます。

まず最初はMecabをインストールします。
Mecabは形態素解析用のライブラリで
これには辞書が含まれています。

その辞書を使っていくわけですね。
GoogleColabにMecabをインストールするのは
次のコードです。
# MeCab と 辞書(mecab-ipadic-NEologd)のインストール 
!apt-get -q -y install sudo file mecab libmecab-dev mecab-ipadic-utf8 git curl python-mecab > /dev/null
!git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git > /dev/null 
!echo yes | mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -n > /dev/null 2>&1
!pip install mecab-python3 > /dev/null
!ln -s /etc/mecabrc /usr/local/etc/mecabrc
!echo `mecab-config --dicdir`"/mecab-ipadic-neologd"

インストールできたかどうか
確かめてみましょう。

次のコードで実行確認ができます。
# テスト
import MeCab
import random

sample_txt = "鬼滅の刃の炭次郎"
path = "-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd"
m = MeCab.Tagger(path)
print("Mecab ipadic NEologd:\n",m.parse(sample_txt))
Mecab ipadic NEologd:
 鬼滅の刃 名詞,固有名詞,一般,*,*,*,鬼滅の刃,キメツノヤイバ,キメツノヤイバ
助詞,連体化,*,*,*,*,の,ノ,ノ
名詞,固有名詞,人名,姓,*,*,炭,タン,タン
次郎 名詞,固有名詞,人名,名,*,*,次郎,ジロウ,ジロー
EOS


いい感じで形態素解析出来ていますね。

形態素解析は文章を単語に分割しますが
辞書に無い固有名詞はより細かい単語に
分割されてしまいます。

この場合、「鬼滅の刃」がそれに当たります。
この辞書は「鬼滅の刃」が辞書登録されていますね。

この辞書データを使ってしりとり用の
辞書データを作っていきます。
# ここのパスは要チェック
dic_path = '/content/mecab-ipadic-neologd/build/mecab-ipadic-2.7.0-20070801-neologd-20200910/mecab-user-dict-seed.20200910.csv'
dic_data = {}
with open(dic_path) as _f:
    for i,row in enumerate(_f):
        rows = row.replace('\n','').split(',')
        word = rows[0]
        yomi = rows[11]
        hinsi = rows[4]
        
        # 品詞の分類
        if '記号' in m.parse(word[0]):
          continue
        # 名詞かつ ンやーでない 数字でもないものだけ登録
        if '名詞' in hinsi and len(yomi)>2 and 'ン'!=yomi[-1] and 'ー'!=yomi[-1] and not any([a.isnumeric() for a in word]):
          #print(rows)          
          s_word = yomi[0]
          e_word = yomi[-1]
          if s_word in dic_data:
            tmp_s = dic_data[s_word]
            if e_word in tmp_s:
              tmp_e = tmp_s[e_word]
              tmp_e.append({'word':word,'yomi':yomi})
            else:
              tmp_e = [{'word':word,'yomi':yomi}]
            tmp_s[e_word] = tmp_e
            dic_data[s_word] = tmp_s
          else:
            tmp_e = [{'word':word,'yomi':yomi}]
            dic_data[s_word] = {s_word:tmp_e}
これで辞書データが出来ました。
辞書のパスは変わる可能性があるので
うまく合わせてください。

次にしりとりを行う関数の定義です。

最初の単語を入力して
次の単語をしりとりとして
繋がるようなモノを選んで
最後の言葉につなげるようにします。
# 最初の終わりと最後のワードの始まりの文字
def word_b_and_e(target_word,last_word):
  targets = m.parse(target_word)
  targets = targets.replace('\nEOS\n','').split('\n')
  target_e = targets[-1].split(',')[-2][-1]
  lasts = m.parse(last_word)
  lasts = lasts.replace('\nEOS\n','').split('\n')
  lasts_s = lasts[0].split(',')[-2][0] if lasts[0].split(',')[-2]!='*' else lasts[0].replace('\t',',').split(',')[0][0]
  return target_e,lasts_s

# 次のワードを選択する
def nect_select(target_e):
  next_dic = dic_data[target_e]
  next_e_word = random.choice(list(next_dic.keys()))
  next_ends = next_dic[next_e_word]
  next_word_dic = random.choice(next_ends)
  return next_e_word,next_word_dic

# しりとり5
def siritori5(target_word,last_word):
  for a in range(10):
    try:
      words_route = [target_word]
      target_e , lasts_s = word_b_and_e(target_word,last_word)
      next_target = target_e
      for i in range(2):
        next_e_word , next_word_dic = nect_select(next_target)
        words_route.append('{0}({1})'.format(next_word_dic['word'],next_word_dic['yomi']))
        next_target = next_e_word

      lasts = random.choice(dic_data[next_target][lasts_s])
      words_route.append('{0}({1})'.format(lasts['word'],lasts['yomi']))
      words_route.append(last_word)
      for w in words_route:
        print(w)
      break
    except:
      pass

これでしりとりを行う準備が出来ました。

あとは実行です。
最初の単語と
最後につなげる単語を用意しておきます。


今回は始まりを「鬼滅の刃」
終わりを「タルタルチキン」にします。

結果はランダムで選ばれます。
# 実行
target_word = '鬼滅の刃'
last_word = 'タルタルチキン'
siritori5(target_word,last_word)
鬼滅の刃
バイエルン国立バレエ(バイエルンコクリツバレエ)
エドゥアードヴェジンヌ(エドゥアードヴェジンヌ)
沼尻健太(ヌマジリケンタ)
タルタルチキン

鬼滅の刃
馬簾水母(バレンクラゲ)
ゲッコウガ(ゲッコウガ)
ガジンフジタ(ガジンフジタ)
タルタルチキン

鬼滅の刃
vanellope(バネロペ)
ペドロバルボーザ(ペドロバルボーザ)
ザカリウス親方(ザカリウスオヤカタ)
タルタルチキン


・・・・

なんか聞いたことの無い単語ばかり

たまにまともな奴がでやりしますんで
試したい方は
何回もやり直してみて下さい。

今回は丹生ちゃんの
タルタルチキンしりとりを再現する
プログラムでした。

いやータルタルチキン
最高ですねーーー

今日はここまでです
それでは。


最近坂道グループの番組を
毎週見ているので
気になってしまいまして

3グループの平均顔を
作ってみました。

解説動画はこちら


平均顔を求めるには
画像を入手しないといけません。

スクレイピング等で
取得することができますが
特定のサイトを取得するコードを
公開することができませんので
やりたい方はご自身で作ってみて下さい。

平均顔のコードは
いつも使っている奴です。

さて、それでは
平均顔を求めていきましょう。

まずは乃木坂46です。

現在46名いるようですね
平均顔はこうなりました。

download-3
目鼻達がくっきり!!!
顔はやや丸顔で
髪は肩より下くらいまでの
方が多いのですかね。

メンバーのどの方に近いのかは
分かりませんです、ご意見くださいませ。

さてお次は櫻坂46
最近改名したのかな?!
事情はよく分かりませんが
26名のみのようです。

平均顔はこうなりました。

download-2

笑顔がなく
ほっそりとした印象ですね。

髪もやや短めな感じでしょうか
少し暗い印象も感じますね。

口元のブレも無いので
皆さん近しい顔立ちなんでしょう。

こういう顔の方が
櫻坂さんに向いている顔なのかも
しれませんねえ。

お次は日向坂46
現在大注目のグループです。

メンバーは22名でした。

さて、平均顔は
download-1

若くてフレッシュ!!
顔はややシャープ目な印象で
目鼻口元とも揃っていて
非常に可愛らしい。

2020年のアイドル
と言った感じでしょうか。


最後に自分の好みの平均顔を作ってみました。

この娘なら写真指名するなー
っていう好みでの選抜です。

メンバーは
小坂_菜緒
佐々木_久美
濱岸_ひより
齊藤_京子
渡邉_美穂
加藤_史帆

以上6名の平均です。


どうなるか・・・

download

22名の平均と大きくは
変わらないと思いますが
自分はこちらの方が好みですねーー

ちなみにゲスな話ですが
どのグループでも
平均化すると可愛くなります。

歪さ、がアレなので
それが無くなると
良くなる訳ですねー。

さて、皆様は
どのチームの平均顔が
好みでしょうか?!

コメントなどいただければ
幸いです。

本日はここまでです
それでは。

このページのトップヘ