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

opencv

見えたら天才
そんな画像があります。

ステレオグラムと言う
立体視画像です。

今回はそれを作っていきます。
解説動画はこちら



さてまずこの立体視というものですが
立体的な視覚を得る方法のことで
画像を立体的に見ることになります。

この立体的に見える画像のことを
ステレオグラム(英: stereogram)
立体画、立体図と呼んでいます。

立体的な印象をもつように描かれた
平面に描かれた図や絵あるいは写真
のことです。

こんなドット絵を見たことないでしょうか?
4つのドットの中二つが重ね合わさるように見ると
立体的に浮かび上がるように見えると思います。
download


コツとしては
右目で左側を見て、左目で右側を見るイメージ
うまく行くと点が浮かび上がってくると思います。

スマホだと厳しいかもしれないので
タブレットやPCで見てみると良いでしょう。


それではここからステレオグラムを
作っていきましょう。

今回作るやつは
ランダム・ドット・ステレオグラム
(英: Random dot stereogram, RDS)

一見ノイズのようにしか見えない画像が
うまく焦点を合わせると
立体が浮かび上がってくる画像です。

レーダー技術者から知覚研究に転じた
ユレス・ベーラさんによって
考案された手法だそうです。

今回はこちらのサイトの手法をそのまま
お借りしています。

参考



まずは背景となるドット画像の用意です。

ライブラリはopencvなどを使用します。
インストールしていないと動かないので
無い方はインストールしてください。
import numpy as np
import matplotlib.pyplot as plt
import cv2
%matplotlib inline

numpyを用いて背景ドット画像を作る関数です。
def make_dots(shape=(16, 16), levels=64):
    return np.random.randint(0, levels - 1, shape) / levels

dots = make_dots(shape=(64, 64))
plt.figure(figsize=(8,8))
plt.imshow(dots, cmap='gray')
plt.show()
dots

最初は円形の画像を浮かび上がらせる
ステレオグラムを作りましょう。

円形画像を作ります。
def make_img(shape=(400, 600)):
    img = np.zeros(shape, dtype=np.float)
    cv2.circle(img, (int(shape[1]/2), int(shape[0]/2)), 100, (255 ,255, 255), -1)
    return img

img = make_img()
plt.figure(figsize=(8,8))
plt.imshow(img, cmap='gray')
plt.show()

dotimg

ステレオグラムを作成する関数です。
こちらは参考サイトのものをそのまま転記しています。
def normalize(depthmap):
    "Normalizes values of depthmap to [0, 1] range."
    if depthmap.max() > depthmap.min():
        return (depthmap - depthmap.min()) / (depthmap.max() - depthmap.min())
    else:
        return depthmap

def make_autostereogram(depthmap, pattern, shift_amplitude=0.1, invert=False):
    "Creates an autostereogram from depthmap and pattern."
    depthmap = normalize(depthmap)
    if invert:
        depthmap = 1 - depthmap
    autostereogram = np.zeros_like(depthmap, dtype=pattern.dtype)
    for r in np.arange(autostereogram.shape[0]):
        for c in np.arange(autostereogram.shape[1]):
            if c < pattern.shape[1]:
                autostereogram[r, c] = pattern[r % pattern.shape[0], c]
            else:
                shift = int(depthmap[r, c] * shift_amplitude * pattern.shape[1])
                autostereogram[r, c] = autostereogram[r, c - pattern.shape[1] + shift]
    return autostereogram

最後に実行です。
このコードで円形ステレオグラムが
作成できると思います。
img = make_img()
autostereogram = make_autostereogram(img, dots)
plt.figure(figsize=(8,8))
plt.imshow(autostereogram, cmap='gray')
plt.show()
en

さて、注視すると円が浮かび上がってきませんでしょうか?

目安が無いので難易度は高いですが
見えない方は4つのドットで練習すると
見えるようになるかもしれません。

続いて文字を立体画像にしてみましょう。
まずは文字です。

text=の部分
引数で指定して変えれば他の文字にできます。
def make_text_img(shape=(400, 600), text='p y'):
    img = np.zeros(shape, dtype=np.float)
    font = cv2.FONT_HERSHEY_SIMPLEX
    cv2.putText(img, text, (100, 250), font, 5, (255,255,255), 30, cv2.LINE_AA)
    return img

text_img = make_text_img()
plt.figure(figsize=(8,8))
plt.imshow(text_img, cmap='gray')
plt.show()
py_text

これをステレオグラムにします。
autostereogram = make_autostereogram(text_img, dots)
plt.figure(figsize=(8,8))
plt.imshow(autostereogram, cmap='gray')
plt.show()
py

さてPYの文字が浮かび上がってきませんでしょうか?


最後にクイズです。
これは何と書いてあるでしょうか?

心が汚れている方は読めるはずですwwwwwww
sex


見えた方は動画のコメント欄にでも
コメントしていただけると嬉しいです。

見えたときは興奮、感動すること
間違いない!!!

気合と根性と集中力があれば
見えます。

頑張ってくださいね。
それでは。



今回はアッチの方の女優さんの
最強平均顔を作っていきたいと
思いまーーーす。


解説動画はこちら



こちらもコードはGoogleColabで
試せる様になっています。

まずはライブラリのインストールです。
!pip install facemorpher

次にdlibを動かすために必要な
datファイルをダウンロードします。
!wget http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2 -O shape_predictor_68_face_landmarks.dat.bz2

ダウンロードが終わると
colabでファイル確認ができると思います。

ダウンロードを終えたら
ファイルの解凍です。
!tar jxf shape_predictor_68_face_landmarks.dat.bz2

これでbz2からdatになりました。

続いて環境変数のセットアップです。
!export DLIB_DATA_DIR=/content

最後に画像様のフォルダを作成しましょう。
!mkdir img

これで準備が整いました。

画像はimg配下にフォルダをいくつか作り
その中にpngやjpg形式で入れています。

平均顔のコードの実行方法ですが
まずはライブラリのインポートです。
import facemorpher

メソッドの実行方法としては
次の様になっています。

画像はリスト型でパスを指定します。
facemorpher.averager([画像パス],background='背景',plot=True) 

試しに2つのファイルを指定して
平均顔を作成してみると
# 画像を2つ指定して平均顔作成
facemorpher.averager(['img/1/zinnai1.png', 'img/1/watabe2.png'], 
                     background='transparent',plot=True)
uwaki2
こんな感じで実行されます。

フォルダ内の画像を全て使って
平均顔を作る場合はglobライブラリを使って
画像パスを指定します。

import glob
img_path = glob.glob('img/1/*png')

# フォルダ内の画像で平均顔作成
facemorpher.averager(img_path,background='transparent',plot=True)
uwaki3
さてここからは
本題に入っていきましょう。

今回使用したのはアッチの方の
女優さんのお顔の画像です。

集めるのはFANZAさんの
画像を使用しています。

ご自身で真似したい方は
うまく集めてみてください。


まずは新人おすすめからです。

新人女優

2月1日更新
対象者は以下の女優さんたちです。

堀内未果子 白峰ミウ 長谷川柚月 麻生マーガレット奈々美
香乃萌音 沙和れもん 吉野里奈 青山真子
川北メイサ 栗山さや 陳美恵 楠蘭

すいません一人も知らないです。
お顔はこうなりました。
result_new
新人さんと言う事で初々しさが
感じられるお顔立ちでしょうか!!!



続いて
月間ランキング
2021/2月20日更新

対象はTOP10の方々です。

深田えいみ 美谷朱里 枢木あおい 星奈あい 篠田ゆう
三上悠亜 伊藤舞雪 波多野結衣 蓮実クレア 奏音かのん

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

result_ranking
深田えいみさんだけ
メガネをかけているので
メガネのラインが顔入っちゃってますねwww

やや笑顔な感じになり
ここが新人との経験の差になる感じがしますねー



続いて
FANZAのおすすめ女優

対象者の名前は割愛しますが
新人 + ランカー他の総勢26名で
構成されているようです。

平均顔はこうなりました。
result_fanza
これがいわゆる
FANZA顔と言うやつですね!!!!!
素晴らしい

あとはotupyの好きな女優さんの
平均顔なんかもやってますで
よろしければ動画の方をどうぞ

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






最近トムブラウンの合体ネタに
ハマってしまったので
今日は合体ネタです。


解説動画はこちら



プログラミングで
合体ネタを試してみようと思います。

単純に平均顔を作るだけです。

画像をたくさん用意するのが
面倒くさいので
1vs1で合体(平均)します。

平均顔のコードを
頑張って作って頂くと
同じように出来ます!!!

興味がある方はコメントください。

では
合体!!!
スクリーンショット 2020-11-21 16.39.55

スクリーンショット 2020-11-21 16.39.08

スクリーンショット 2020-11-21 16.39.18

スクリーンショット 2020-11-21 16.39.28

スクリーンショット 2020-11-21 16.39.38

半々に合成してますが
なかなか特徴が濃いですよねー

目鼻立ちなどは
より濃い人が浮き出る感じになるようです。

詳しくは動画の方を
みてみて下さい。

それでは。

今回は久しぶりに
画像加工で遊んでみました。

解説動画はこちら



ソースコードはこちら
import numpy as np 
import cv2
import math
from ipywidgets import interact, IntSlider , Select
import matplotlib.pyplot as plt
%matplotlib inline

x1 = IntSlider(value=1, min=1, max=20, step=1, description='x:',)
y1 = IntSlider(value=1, min=1, max=20, step=1, description='y:',)
files = ['kurochan.jpg','nadaru.png','inachan.jpg','ayase.jpg','gakky.jpg']
selected = Select(description='画像', options=files, rows=5,)

def show_plot(col1, col2 , col3):
    img = cv2.imread('img/' + col3)
    (h, w, c) = img.shape
    flex_x = np.zeros((h,w),np.float32)
    flex_y = np.zeros((h,w),np.float32)
    for y in range(h):
        for x in range(w):
            flex_x[y,x] = x + math.sin(x/30) * col1
            flex_y[y,x] = y + math.cos(y/30) * col2
    dst = cv2.remap(img,flex_x,flex_y,cv2.INTER_LINEAR)
    dst = cv2.cvtColor(dst , cv2.COLOR_BGR2RGB)
    plt.figure(figsize=(10,10))
    plt.tick_params(labelbottom=False,labelleft=False,labelright=False,labeltop=False)
    plt.imshow(dst)
    plt.show()

interact(show_plot, col1=x1, col2=y1 , col3 = selected)

実行していただくと
スクリーンショット 2020-11-14 16.04.16

こんな感じでメニューが出るようになっています。
このプログラムの直下にあるimgフォルダの中の
画像を参照するようにしているので
画像を用いる際はfiles変数の右の
ファイル名などを変更して下さい。

実行後は画像名をクリックすると
画像が切り替わります。

x,yは横、縦方向の画像の歪み度を変更します。
大きい数値の方が歪むようになります。

どんな感じになるかと言うと
download
download-1
download-2

かなり別人になるかなーと思いますが
若干元の人の特徴が残っているのが
面白いかなーと思います。

是非遊んでみて下さい。

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

次期総理を決める戦いの真っ最中ということで
スガさんをムキムキにしてみました。

解説動画はこちら



官房長官たるもの
強くなければならないですからね!!

opencvを用いれば画像の加工とかできますので
やりたい方は頑張ってみてくださいね。

ディープフェイクレベル1の問題です。
つまり、誰でも出来てしまうような
レベルの問題だということですね。


プログラムを作ってやってみた結果
良い出来の一部をお送りしたいと思います。

往年の映画スターに合成
スクリーンショット 2020-09-06 15.03.51

一国の総理大臣として
力で問題を解決してくれそうな顔つきですねーー

スクリーンショット 2020-09-06 15.04.01

こちらも往年の映画スターに合成
東南アジアの問題を現地に乗り込んで
解決してくれそうな趣があります。

せっかくだから
毛を生やしてみましょう。

スクリーンショット 2020-09-06 15.04.40


全然生えませんでしたーーーー
誠にすいまメーーんwww

このページのトップヘ