note.nkmk.me

Python, NumPy(OpenCV)で画像を二値化処理

Date: 2018-02-08 / tags: Python, OpenCV, 画像処理, NumPy

画像をNumPy配列ndarrayで読み込むと、簡単に画素値を計算して処理できる。ここでは閾値で白黒に分ける二値化処理について説明する。

サンプルコードではPillowで画像を読み込んでndarrayに変換しているが、OpenCVで画像を読み込んでも基本的には同じ。カラー画像を扱う場合は色の順番が違うので注意。

画像を白黒に変換して使う。

import numpy as np
from PIL import Image

im = np.array(Image.open('data/src/lena_square.png').convert('L').resize((256, 256)))
print(type(im))
# <class 'numpy.ndarray'>

lena gray

スポンサーリンク

画像の二値化処理の基本

NumPy配列ndarrayに対して比較演算子を使うと、各要素(画像の場合は各画素値)に対して比較した結果のブール値(True, False)のndarrayが得られる。

th = 128
im_bool = im > th
print(im_bool)
# [[ True  True  True ...,  True  True False]
#  [ True  True  True ...,  True  True False]
#  [ True  True  True ...,  True False False]
#  ..., 
#  [False False False ..., False False False]
#  [False False False ..., False False False]
#  [False False False ..., False False False]]

True1False0とみなされるので、画像として保存する場合は符号なし8ビット(uint8)のMax値255をかける。比較した結果がTrueの画素値は255(白)、Falseの画素値は0(黒)となる。

im_bin_128 = (im > th) * 255
print(im_bin_128)
# [[255 255 255 ..., 255 255   0]
#  [255 255 255 ..., 255 255   0]
#  [255 255 255 ..., 255   0   0]
#  ..., 
#  [  0   0   0 ...,   0   0   0]
#  [  0   0   0 ...,   0   0   0]
#  [  0   0   0 ...,   0   0   0]]

しきい値を変更して処理を行い、横に連結して保存する。

im_bin_64 = (im > 64) * 255
im_bin_192 = (im > 192) * 255

im_bin = np.concatenate((im_bin_64, im_bin_128, im_bin_192), axis=1)
Image.fromarray(np.uint8(im_bin)).save('data/dst/lena_numpy_binarization.png')

結果はこんな感じ。

Python NumPy OpenCV binarization

画像の二値化処理の応用

RGB各色に異なる値をかけると、カラフルな画像にもできる。

im_bool = im > 128
h, w = im.shape

im_dst = np.empty((h, w, 3))

r, g, b = 255, 128, 32

im_dst[:, :, 0] = im_bool * r
im_dst[:, :, 1] = im_bool * g
im_dst[:, :, 2] = im_bool * b

Image.fromarray(np.uint8(im_dst)).save('data/dst/lena_numpy_binarization_color.png')

Python NumPy OpenCV binarization color

ブール値のndarrayに対して否定演算子~を適用することも可能。

r, g, b = 128, 160, 192

im_dst[:, :, 0] = im_bool * r
im_dst[:, :, 1] = ~im_bool * g
im_dst[:, :, 2] = im_bool * b

Image.fromarray(np.uint8(im_dst)).save('data/dst/lena_numpy_binarization_color2.png')

Python NumPy OpenCV binarization color2

最後にOpenCVの関数cv2.imwrite()で画像を保存する場合は色の並びをBGRにしておく必要があるので注意。

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事