Pythonでいろいろやってみる

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

画像でモザイク画を作る(フォトモザイク)

 画像をモザイク画に変換します。様々な色合いの画像を用意し15x10ピクセルに縮小、置き換え用画像にします。変換する画像を15x10ピクセルの碁盤目状のセルに分割し各セルのBGR平均値を出し、BGR平均値の近い置き換え用画像に置き換えます。

環境
  • windows10 home
  • Anaconda 3/ jupyter notebook 6.4.6
  • Python 3.8.12
  • numpy 1.21.5
  • OpenCV 4.5.5
準備

 変換する画像はフリー写真素材ぱくたそからダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリにフォルダ'photos'を作成しその中に保存しました。

mamechi.jpg

 置き換え用画像は色味の異なる画像30枚、同じくフリー写真素材ぱくたそからダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリにフォルダ'images'を作成しその中に保存しました。

コード

 変換する画像の15x10ピクセルに分割し、各セルのB,G,R値の平均を求めます。置き換え用画像30枚のB,G,R値と比較し、最も近い置き換え用画像を選びます。近さは
B値の差の二乗 + G値の差の二乗 + R値の差の二乗
により求め、この値が最も小さい置き換え用画像を選びます。
 

import os
import cv2
import numpy as np

# 置き換え用画像格納リスト
image_list = []

# 置き換え用画像BGR平均値格納リスト
bgr_list = []  

# セルのサイズ
xpitch = 15
ypitch = 10

# imagesフォルダ内のファイルのリスト生成
files = os.listdir('images/')  
# imagesフォルダからファイル名を1つずつ取り出して処理
for i in files:     
    pic = cv2.imread('images/'+i)    
    resize = cv2.resize(pic, (xpitch, ypitch))
    image_list.append(resize)
    bgr_list.append(np.mean(resize, axis=(1,0)))
    
# 変換する画像を読み出し、セルサイズの整数倍にリサイズ
# 同じサイズの黒画像(replace)を変換後画像用に作成
pic = cv2.imread('mamechi.jpg')
height, width, channel = pic.shape
resize = cv2.resize(pic, (width//xpitch*xpitch, height//ypitch*ypitch))
replace = np.zeros((height//ypitch*ypitch, width//xpitch*xpitch, 3), np.uint8)

# 変換する画像をセルサイズに分割して読み出し、各セルのBGR平均値を算出
# 置き換え用画像と比較し、最も近い画像を選択、変換後画像に張り付ける
for y in range(0, height//ypitch*ypitch, ypitch):
    for x in range(0, width//xpitch*xpitch, xpitch):
        part = pic[y:y+ypitch, x:x+xpitch]
        bgr = np.mean(part, axis=(1,0))
        min_distance = 195075
        for i in range(len(image_list)):
            j = image_list[i]
            k = bgr_list[i]
            distance = ((bgr[0]-k[0])**2+
                        (bgr[1]-k[1])**2+
                        (bgr[2]-k[2])**2)
            if distance<min_distance:
                min_distance = distance
                choice = j  
        replace[y:y+ypitch, x:x+xpitch] = choice

# 変換後画像の保存
cv2.imwrite('replace.jpg', replace)   
実行結果

モザイク画に変換された画像(replace.jpg)が保存されます


もう少しモザイク画を滑らかにするために、①xpitch = 9 ypitch = 6に変更②モザイク用画像を30→47枚に増やしました。だいぶ滑らかになりました。

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

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

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

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