画像を点描画に変換する
画像を点描画に変換します。飛び飛びに円を描いて点描化します。円の色を設定するために、元画像の縮小画像を作りその配列から元画像の飛び飛びの色を取得します。
使った関数・メソッド
- cv2.imread() : 画像ファイルの読み出し
- ndarray.shape() : ndarrayの形状取得
- numpy.ones() : 全要素の値が1のndarrayの生成
- cv2.resize() : 画像サイズの変更
- cv2.imwrite() : 画像を保存する
環境
準備
画像ファイルはフリー写真素材ぱくたそからダウンロードさせていただき、ファイル名'kabuki_cho.jpg'でjupyter notebookファイル(***.ipynb)と同じディレクトリに保存しました。
kabuki_cho.jpg
コード
import cv2 # OpenCVのインポート import numpy as np # numpyをnpという名前でインポート fname = "kabuki_cho.jpg" # 画像ファイル名 scale_factor = 8 # 縮小処理時の縮小率 white_rate = 1.8 # 隙間量の設定(描画する円の縮小率) img = cv2.imread(fname) # 画像を読み出しオブジェクトimgに代入 # オブジェクトimgのshapeメソッドの1つ目の戻り値(画像の高さ)をimg_heightに、2つ目の戻り値(画像の幅)をimg_widthに代入 img_height,img_width=img.shape[:2] img_white = np.ones((img_height, img_width, 3), np.uint8)*255 # imgと同じサイズの白画像を生成 img_reduction = cv2.resize(img,None,fx = 1/scale_factor,fy = 1/scale_factor) # 縮小率の倍率で画像を縮小 img_reduction_height,img_reduction_width = img_reduction.shape[:2] # 縮小画像の高さ、幅を取得 for y in range(img_reduction_height): # 縮小画像の高さ画素数分繰り返す for x in range(img_reduction_width): # 縮小画像の幅画素数分繰り返す b = int(img_reduction[y,x,0]) # 縮小画像のBの輝度を取得 g = int(img_reduction[y,x,1]) # 縮小画像のGの輝度を取得 r = int(img_reduction[y,x,2]) # 縮小画像のRの輝度を取得 x_circle = x*scale_factor # 円のx座標を設定 y_circle = y*scale_factor # 円のy座標を設定 cv2.circle(img_white, (x_circle, y_circle), int(scale_factor/white_rate), (b,g,r), -1) # 円の描画 cv2.imwrite("dot.jpg",img_white) #画像をファイル名random_circle.pngで保存
実行結果
このままだと等間隔に点が並んでいて味気ないので点の位置にばらつきを与えてみます。また円の大きさを大きくして隙間を少なくしてみます。
コード
import cv2 # OpenCVのインポート import numpy as np # numpyをnpという名前でインポート import random # randomのインポート fname = "kabuki_cho.jpg" # 画像ファイル名 scale_factor = 8 # 縮小処理時の縮小率 white_rate = 1.5 # 隙間量の設定(描画する円の縮小率) img = cv2.imread(fname) # 画像を読み出しオブジェクトimgに代入 # オブジェクトimgのshapeメソッドの1つ目の戻り値(画像の高さ)をimg_heightに、2つ目の戻り値(画像の幅)をimg_widthに代入 img_height,img_width=img.shape[:2] img_white = np.ones((img_height, img_width, 3), np.uint8)*255 # imgと同じサイズの白画像を生成 img_reduction = cv2.resize(img,None,fx = 1/scale_factor,fy = 1/scale_factor) # 縮小率の倍率で画像を縮小 img_reduction_height,img_reduction_width = img_reduction.shape[:2] # 縮小画像の高さ、幅を取得 for y in range(img_reduction_height): # 縮小画像の高さ画素数分繰り返す for x in range(img_reduction_width): # 縮小画像の幅画素数分繰り返す b = int(img_reduction[y,x,0]) # 縮小画像のBの輝度を取得 g = int(img_reduction[y,x,1]) # 縮小画像のGの輝度を取得 r = int(img_reduction[y,x,2]) # 縮小画像のRの輝度を取得 x_frac = random.random()*3 # 円のx座標のばらつきを設定 y_frac = random.random()*3 # 円のy座標のばらつきを設定 x_circle = int(x*scale_factor+x_frac) # 円のx座標を設定 y_circle = int(y*scale_factor+y_frac) # 円のy座標を設定 cv2.circle(img_white, (x_circle, y_circle), int(scale_factor/white_rate), (b,g,r), -1) # 円の描画 cv2.imwrite("dot.jpg",img_white) #画像をファイル名random_circle.pngで保存
実行結果
絵画っぽくなりました。
以下のサイトを参考にさせていただきました
Pythonの文法メモ > 【OpenCV】画像読み出しとサイズ・画素情報取得、切り抜き、貼り付け、チャネル操作
Pythonの文法メモ > 【OpenCV】円を描画するcircle
Pythonの文法メモ > 【OpenCV】画像サイズを変更するresize