Terasannのチラ裏

「それはTeraさんに聞け」を目指すブログ

画像を小さなブロックに分解するPythonプログラム(ディザ法)

コツコツと書いていきますよ(^^)

まずは分解した結果から。

f:id:kch-bone:20141223001737p:plain

これを4分割すると

f:id:kch-bone:20141223001745p:plain

になります。

そろそろレポートの締め切りがやばいのですが(てか明日)

ディザ法というものを学びましたのでそれをpythonで作ってみたいなと思います。

ディザ法と言うのはざっくり言うと

少ない情報量でそれっぽく見せる

ということなんですはい。

写真で言うとグレースケール画像をモノクロ画像に変換する処理みたいなものですね。

せっかくなんでpythonで書いてみました。

コードだけ見せろ!って方は一番下見てね(・ω<)

今回は画像の一部を近いパターンで置換する手法を取ります。

そのため元の画像を細かなブロックに分けて置き換えていくという処理が必要になってきます。

画像をブロックに分解する関数を書きました。

from PIL import Image
import cv2
import numpy as np

def block_out(matrix, size, block_list):
    #行列分解
    # 8 * 8 = 64 のウィンドウの行列に分解

    if size % 2 == 1:
        print "plz put even . not odd"
        return 0

    block_list1 = []

    block_list1 = np.vsplit(matrix, int(size))

    for i in range(0, int(size)):

        block_list2 = np.hsplit(block_list1[i], int(size))

        for x in range(0, int(size)):
            show(block_list2[x], 2)
            block_list.append(block_list2[x])

matrixにはnumpy形式で$256*256$のサイズで正方行列必須です。 ここはsizeで割り切れる大きさならなんでもオッケーです。 sizeは分割する数です。それらをblock_listに格納します。

なのでもし $matrix=256*256$ で size=64ならば 64*64=4096 個の画像が生成されちゃいます。

これらの画像1つ1つを置換していったら今度は元に戻す処理をしてあげなければ!

以下元に戻す関数

from PIL import Image
import cv2
import numpy as np

def block_in(matrix, size, block_list):
#行列結合

    if size % 2 == 1:
        print "plz put even . not odd"
        return 0

    list1 = []
    #list1に各行の先頭ブロックを追加
    for i, (tmp) in enumerate(block_list):
        if i % size == 0:
            list1.append(tmp)

    tmp = np.array(0)

    for i in range(0, size * size - 1):
        if i % size != 0:
            list1[int(i / size)] = np.hstack((list1[int(i / size)], block_list[i + 1]))

    matrix = list1[0]
    for i in range(1, size - 1):
        matrix = np.vstack((matrix, list1[i]))

基本はこれで元に戻るはず。

以下コード全体のリンク

dither法

ランダムディザ法

f:id:kch-bone:20141223002142p:plain

誤差拡散法

f:id:kch-bone:20141223002200p:plain

でででん!

実際に使うときにはimshowとか使って見てくださいな。

ではでは