画像をマトリックス風に変換する
画像を映画「マトリックス」の仮想現実シーンのように変換します。反転した緑色のカタカナで表現された印象的なシーンをまねします。
変換する画像をエッジ検出しエッジ部分を反転した緑色のカタカナで置き換えます。
関連記事
環境
準備
画像ファイルはフリー写真素材ぱくたそからダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリにファイル名’hand.jpg'で保存しました(元画像のサイズは800x1583)。
コード
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) # 画像を保存
実行結果
元画像、エッジ検出画像(途中経過)、変換画像を並べました。ランダムな緑色の反転文字で置き換わっています。
別の画像で試してみます。
コード
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) # 画像を保存
実行結果
以下のサイトを参考にさせていただきました
Pythonの文法メモ > 【OpenCV】画像読み出しとサイズ・画素情報取得、切り抜き、貼り付け、チャネル操作
Pythonの文法メモ > 【OpenCV】画像サイズを変更するresize
Pythonの文法メモ > 【Numpy】インデックス・スライスによるndarray要素の取得