Pythonでいろいろやってみる

Pythonを使った画像処理や機械学習などの簡単なプログラムを載せています。

画像をマトリックス風に変換する

画像を映画「マトリックス」の仮想現実シーンのように変換します。反転した緑色のカタカナで表現された印象的なシーンをまねします。
変換する画像をエッジ検出しエッジ部分を反転した緑色のカタカナで置き換えます。

関連記事

アスキーアートを自動生成する

環境
  • windows10 home
  • Anaconda 3/ jupyter notebook 5.6.0
  • Python 3.7.0
  • Pillow 5.2.0
  • OpenCV 4.0.0
準備

画像ファイルはフリー写真素材ぱくたそからダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリにファイル名’hand.jpg'で保存しました(元画像のサイズは800x1583)。

f:id:T_A_T:20200611210025j:plain

コード

pillowでカタカナの文字列を画像化し180°回転 、変換したい画像をOpenCVで読み出しcv2.Cannyでエッジ検出、エッジ画像の画素値を調べエッジがあれば反転文字列のランダムな文字に置き換えます。

from PIL import Image, ImageDraw, ImageFont
import cv2
import numpy as np
import random

font_size = 24  # フォントサイズ
text = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン1234567890#%&$'  # 文字列
font = ImageFont.truetype('C:\Windows\Fonts\msgothic.ttc', font_size)  # フォントの指定
im = Image.new('RGB', (int(len(text)/2*font_size), font_size), (0, 0, 0))  # 下地となるイメージオブジェクトの生成
draw = ImageDraw.Draw(im)  # drawオブジェクトを生成
draw.text((0, 0),text, fill=(80, 255, 80), font=font)  # 文字列を画像に描画 
im_rotate = im.rotate(180)  #180°回転
im_rotate.save('text.png')  # 画像をファイル名'text.png'で保存

text_img = cv2.imread('text.png')  # 反転文字画像の読み出し  
img = cv2.imread('hand.jpg',0)  # 変換する画像をグレースケールで読み出し
height, width = img.shape  # 画像の高さ幅取得
edges = cv2.Canny(img,50,150)  # 画像のエッジ検出

# font_sizeの整数倍にエッジ画像をリサイズ
resize_x = width//font_size*font_size
resize_y = height//font_size*font_size
resize = cv2.resize(edges,(resize_x, resize_y)) 

matrix = np.zeros((resize_y, resize_x, 3), np.uint8) # リサイズしたエッジ画像と同じサイズの黒画像を生成

# エッジ画像を置き換える文字のサイズに分割して
# エッジがあれば(画素値が0でなければ)ランダムに選んだ反転文字に置き換える
for y in range(0, resize_y, font_size):
    for x in range(0, resize_x, int(font_size/2)):
        if np.amax(resize[y:y+font_size, x:x+int(font_size/2)])>0: # ブロックごとの画素最大値が1以上か判定
            pos = int(random.random()*len(text))*int(font_size/2)
            matrix[y:y+font_size, x:x+int(font_size/2)] = text_img[0:font_size, pos:pos+int(font_size/2)]

cv2.imwrite('matrix.png', matrix)  # 画像を保存
実行結果

元画像、エッジ検出画像(途中経過)、変換画像を並べました。ランダムな緑色の反転文字で置き換わっています。 f:id:T_A_T:20200611210557p:plain


別の画像で試してみます。 f:id:T_A_T:20200611211254j:plain

コード
from PIL import Image, ImageDraw, ImageFont
import cv2
import numpy as np
import random

font_size = 8 # フォントサイズ
text = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン1234567890#%&$'  # 文字列
font = ImageFont.truetype('C:\Windows\Fonts\msgothic.ttc', font_size)  # フォントの指定
im = Image.new('RGB', (int(len(text)/2*font_size), font_size), (0, 0, 0))  # 下地となるイメージオブジェクトの生成
draw = ImageDraw.Draw(im)  # drawオブジェクトを生成
draw.text((0, 0),text, fill=(80, 255, 80), font=font)  # 文字列を画像に描画 
im_rotate = im.rotate(180)  #180°回転
im_rotate.save('text.png')  # 画像をファイル名'text.png'で保存

text_img = cv2.imread('text.png')  # 反転文字画像の読み出し  
img = cv2.imread('keisansyou.jpg',0)  # 変換する画像をグレースケールで読み出し
height, width = img.shape  # 画像の高さ幅取得
edges = cv2.Canny(img,50,200)  # 画像のエッジ検出

# font_sizeの整数倍にエッジ画像をリサイズ
resize_x = width//font_size*font_size
resize_y = height//font_size*font_size
resize = cv2.resize(edges,(resize_x, resize_y)) 

matrix = np.zeros((resize_y, resize_x, 3), np.uint8) # リサイズしたエッジ画像と同じサイズの黒画像を生成

# エッジ画像を置き換える文字のサイズに分割して
# エッジがあれば(画素値が0でなければ)ランダムに選んだ反転文字に置き換える
for y in range(0, resize_y, font_size):
    for x in range(0, resize_x, int(font_size/2)):
        if np.amax(resize[y:y+font_size, x:x+int(font_size/2)])>0: # ブロックごとの画素最大値が1以上か判定
            pos = int(random.random()*len(text))*int(font_size/2)
            matrix[y:y+font_size, x:x+int(font_size/2)] = text_img[0:font_size, pos:pos+int(font_size/2)]

cv2.imwrite('matrix.png', matrix)  # 画像を保存
実行結果

f:id:T_A_T:20200611211556p:plain

以下のサイトを参考にさせていただきました

Pythonの文法メモ > 【OpenCV】画像読み出しとサイズ・画素情報取得、切り抜き、貼り付け、チャネル操作
Pythonの文法メモ > 【OpenCV】画像サイズを変更するresize
Pythonの文法メモ > 【Numpy】インデックス・スライスによるndarray要素の取得

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村