#はじめに
SNSアカウントの画像をそろそろ変えたいな、と思ってPythonでやりました。コードを残しておきます。
内容は以下の3つの
- 画像を読み込む
- 画像をモノクロにして出力する
- 画像をドットにして出力する
になります。注意はあまりないのですが、ドット化は多少時間がかかります。(1分程度?PCのスペックによる)
##準備
各自実行する場合は以下の点に注意してください。
- もととなる画像をアップロードしておく
- コードにおける画像ファイル名の変更(以下では shiro.jpg としています。)
##画像を読み込む
画像を準備して読み込みます。
私はJupiter Notebookでやっています。その場合は画像を準備して、あらかじめNotebookにアップロードしておきます。
import numpy as np
import matplotlib.pyplot as plt
import cv2
#画像の読み込み
img = plt.imread('shiro.jpg')
type(img)
img.size
plt.imshow(img) #画像の表示
plt.show()
##モノクロ加工をして出力する
次にモノクロ(白黒)加工して出力します。
def img_show(img : np.ndarray, cmap = 'gray', vmin = 0, vmax = 255, interpolation = 'none') -> None:
plt.imshow(img, cmap = cmap, vmin = vmin, vmax = vmax, interpolation = interpolation) #画像を表示
plt.show()
plt.close()
img = plt.imread('shiro.jpg')
img_mid_v = np.max(img, axis = 2)/2 +np.min(img, axis = 2)/2
img_show(img_mid_v)
img = plt.imread('shiro.jpg')
##ドット化する
ドット化します。好みしだいで"dst = pixel_art(img, 0.1, 4)"の数字をいじってみると面白いかもしれません。
実行するとJupiter Notebookに'shiro_mozaiku.jpg'といったファイルが出力されます。
# 減色処理
def sub_color(src, K):
Z = src.reshape((-1,3))
Z = np.float32(Z)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
ret, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
center = np.uint8(center)
res = center[label.flatten()]
return res.reshape((src.shape))
# モザイク処理
def mosaic(img, alpha):
h, w, ch = img.shape
img = cv2.resize(img,(int(w*alpha), int(h*alpha)))
img = cv2.resize(img,(w, h), interpolation=cv2.INTER_NEAREST)
return img
# ドット絵化
def pixel_art(img, alpha=2, K=4):
img = mosaic(img, alpha)
return sub_color(img, K)
# 入力画像を取得
img = cv2.imread("shiro.jpg")
# ドット絵化 画像の粗さ, 色の粗さ
dst = pixel_art(img, 0.1, 4)
# 結果を出力
cv2.imwrite("shiro_mozaiku.jpg", dst)
from PIL import Image
mozaiku_shiro = Image.open('shiro_mozaiku.jpg')
mozaiku_shiro
#雑談
なかなかいいものができたなぁ、という感じです。旅行に行った時の写真ですが、城など建築物はうまくモザイク・ドット化できそうですね。その他、人物や風景などはどうなるかわからないですが試しにやってみると面白いかもしれませんね。