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

opencv

今回は最近ハマっているフワちゃんの顔を
色々な人の顔のパーツと交換してみました。

解説動画はこちら



フワちゃん
最近めっちゃくちゃ好きで
よく見かけます。

テレビでよく見かけるのは
好感度が高いからなんだと思います。

ではなぜ好感度が高いのか?

顔のパーツにヒントが有るのではないかと
睨んでいます!!

と言う訳で
顔のパーツを交換するプログラムを作って
検証してみました。

交換できるパーツは
・目
・鼻
・口
この3つです。

色んな人と顔のパーツを交換してみると
仮説としては


口元の力が強い

んじゃないかと言う仮説です。

まずは自分の大好きな人同士で
スクリーンショット 2020-08-16 16.40.23

クロちゃんにフワちゃんだと
綺麗なクロちゃんですねーーー

好感度が千倍くらいになっていそうwww。

スクリーンショット 2020-08-16 16.40.42

ナダルにフワちゃんは
キンコメ今野さんっぽさが出ますね。

スクリーンショット 2020-08-16 16.40.56

石原さとみさんに
フワちゃんを混ぜると
なーんか、西野七瀬さん感が有るんですけど
類似度は30%くらいでしょうか?

色々変えて試したところ
口元を変えた時の印象の変化が大きいと感じました。

逆にフワちゃんに他の人の顔を合成してみると

スクリーンショット 2020-08-16 16.41.11

一気にフワちゃん感が消失しますね。
口元を変えた時の印象が一番大きいと感じました。

と言うことで
彼女の印象を強めているパーツは



なんだろうと思います。

マスクとかしていたら
魅力は半減してしまいますね!!!

クロちゃんにフワちゃんを合成した時の
口元の変化も大きいので

彼女の魅力、印象の大きいパーツは
口で決まりです!!

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

お盆でも暇なので
色々な歴史上の人物を
全部クロちゃんに変えてみました。

解説動画はこちら


 
色々試してみました。

・幕末の人
・絵
・外人
・大統領

全部行けちゃいましたねーー

さっすがクロちゃん
めちゃくちゃ素材として優秀です。

何に合成しても
違和感なし!!

出来上がったやつを
1つ2つ載せておきますで。

リョーマ
download-12


ペリ井さん
download-5


ザビ
download-6


大統領とかのやつは
色々怒られそうな感じしますよね(笑)ー

他にも色々ありますんで
残りは動画の方を
見ていただければと思います。

それでは!!

GOTOキャンペーンと言うことで
各都道府県の標章の中で

ケツに入れたら痛そうな奴を
プログラムで探してみました。

解説動画はこちら





まずは画像ですが

県章一覧

この画像を使ってみます。
Japanese_Prefectural_Emblem

これが県の標章だそうです。
そんなものがあるとは知りませんでしたが
これをケツに入れるには
ケツの穴の大きさが間に合わないので
仮想で考えます。


どうやってケツに入れたら
痛いかどうかを考えればよいでしょうか?

画像の輪郭から角度を求めてあげて
その角度が少ないやつが痛そうですよね。

と言うわけで
この画像を縦横で切り分けて保存しました。
(6x8画像)

1県ずつ
輪郭を求めてみます。

輪郭を求めるコードは次の通りで
opencvを用いています。

%matplotlib inline
import cv2
import numpy as np
import matplotlib.pyplot as plt

file_path = 'img/5_7.png'
img = cv2.imread(file_path)

# 領域抽出
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, binarized = cv2.threshold(gray_img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
contours, _ = cv2.findContours(binarized, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 領域描画
line_color , line_size = (0, 255, 0),1
plt.figure(figsize=(16,9))
cv2.drawContours(img, contours, -1, line_color , line_size)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
download

こんな形で輪郭が抽出されます。
findContoursで輪郭を求めることが出来ます。

輪郭を描画するには各点の座標がなければ
出来ないので、複数の座標が取得できています。

あとは3点があれば角度の計算ができますよね。
download-3

角度を求めて、その平均を各県で計算します。

次のようなコードで角度の計算をしています。

res = {}
for x in range(6):
    for y in range(8):
        file_path = 'img/{0}_{1}.png'.format(x,y)
        img = cv2.imread(file_path)
        img = img[10:140,10:145]

        # 領域抽出
        gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        _, binarized = cv2.threshold(gray_img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
        contours, _ = cv2.findContours(binarized, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

        tmp = []
        for i in range(len(contours[0])-2):
            a,b,c = contours[0][i][0],contours[0][i+1][0],contours[0][i+2][0]
            ba = [abs(a[0]-b[0]),abs(a[1]-b[1])]
            bc = [abs(c[0]-b[0]),abs(c[1]-b[1])]
            cos_s = (ba[0]*bc[0] +  ba[1]*bc[1]) / (np.sqrt(ba[0]**2 + bc[0]**2) * np.sqrt(ba[1]**2 + bc[1]**2))
            
            dig = np.degrees(np.arccos(cos_s))
            if dig>5:
                tmp.append(dig)
        
        if not np.isnan(np.mean(tmp)):
            res[file_path]=np.mean(tmp)

さて
これで全県の県章の
平均角度が求まりました。

あとはこれのいっちゃんちっさい奴が
ケツに入れたら痛い奴のはずです。

結果は・・・

download-1

デーーん

第一回
ケツに入れたら痛そうな県章選手権の覇者は
千葉県に決まりました!!!!!


千葉県人として
誇り高いですねーーー
素晴らしい

森田さーーん
見てますかーーwwww

と言うわけで
無事、千葉県が
ケツに入れたら痛いそうでした。

今回はこれまでです。

それでは。

opencvで顔をすげ替えます。


解説動画はこちら


今回やったのは

男はつらいよの寅さん
進撃の巨人の誰か知らない人?
キングダムの主人公
翔んで埼玉の主人公
かぐや様は告らせたいの主人公
ファブルの主人公
エンドゲームのトニースターク
バズ・ライトイヤー
平たい顔の人

となっておリマス。

ここに載せると怒られそうなので
動画を見てくだされ!!

それでは。

今話題沸騰中の
カイロ大学の卒業証書っぽい画像を作ってみましょう。

解説動画はこちら



 今回の画像加工はopencvを用います。

インストールなどしていない方は
インストールが必要です。

早速やり方をみてみましょう。

まずは画像を適当にWEBから拾って来ます。
・証書の土台となる写真の画像
・上に貼り付ける写真の画像

この2つを用意します。

やっていることは簡単。
ベースの証書画像の上に証明写真用の画像を
貼り付けているだけです。

コードはこんな感じになります。
import cv2
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
%matplotlib inline

# 画像の読み込み
img = cv2.imread('ベース画像のパス')
img2 = cv2.imread('証明写真のパス')

# 貼り付ける画像をリサイズ(サイズはうまく調整してね)
x_i2 , y_i2 = 180 , 200
img2 = cv2.resize(img2,(x_i2 , y_i2))

# 貼り付け先のオフセットを設定して貼り付ける(ここの数値も調整してね)
x_off , y_off = 100 , 170
img[y_off:y_off+y_i2 , x_off:x_off+x_i2] = img2

# 描画
plt.figure(figsize=(20,16))
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()

こんな感じになりました。
スクリーンショット 2020-06-28 15.24.01


これだと、証明写真を貼っただけなので
スタンプが無いですねーー。

スタンプも押さないと
それっぽくならないので
スタンプも押します。

別途スタンプの画像を透過PNGで用意して
上から貼り付けます。

# 画像の読み込み
img = cv2.imread('ベース画像のパス')
img2 = cv2.imread('証明写真のパス')
rogo = cv2.imread('ロゴ画像のパス',-1)

# 顔写真のリサイズと貼り付け(数値はうまく調整してね)
x_i2 , y_i2 = 180 , 200
img2 = cv2.resize(img2,(x_i2 , y_i2))
x_off , y_off = 100 , 170
img[y_off:y_off+y_i2 , x_off:x_off+x_i2] = img2

# 背景をPIL形式に変換
back = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
back = Image.fromarray(back).convert('RGBA')

# rogoをPIL形式に変換(数値はうまく調整してね)
x_i3 , y_i3 = 150,150
rogo = cv2.resize(rogo,(x_i3 , y_i3))
rogo = cv2.cvtColor(rogo, cv2.COLOR_BGRA2RGBA)
rogo = Image.fromarray(rogo).convert('RGBA')

# 画像を合成
location = (40,280)
tmp = Image.new('RGBA', back.size, (255, 255, 255, 0))
tmp.paste(rogo, location, rogo)
img = Image.alpha_composite(back, tmp)

# 描画
plt.figure(figsize=(20,16))
plt.imshow(img)
plt.show()

さて出来上がりは・・・
スクリーンショット 2020-06-28 15.24.21


いい感じにロゴもスタンプされていますね!!

画像の合成にはopencvはとても便利です。

暇な方は遊んでみるととても面白いですよ!
それでは。


このページのトップヘ