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

画像を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'>

画像の二値化処理の基本

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]]

Trueは1、Falseは0とみなされるので、画像として保存する場合は符号なし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')

結果はこんな感じ。

画像の二値化処理の応用

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')

ブール値の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')

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

シェア

関連カテゴリー

Python OpenCV 画像処理 NumPy

Pythonでの画像処理、Pillow, NumPy, OpenCVの違いと使い分け Python, OpenCV, NumPyで画像のアルファブレンドとマスク処理 Python, OpenCV, Pillow(PIL)で画像サイズ(幅、高さ)を取得 Python, OpenCVで図形描画(線、長方形、円、矢印、文字など) Python, OpenCVで幾何変換(アフィン変換・射影変換など) NumPyでRGB画像の色チャンネルを分離して単色化、白黒化、色交換 NumPy配列ndarrayをシフト(スクロール)させるnp.roll Python, OpenCVで三角形・四角形領域を変形して別画像に貼り付け NumPy配列ndarrayをタイル状に繰り返し並べるnp.tile Python, OpenCVでBGRとRGBを変換するcvtColor Python, OpenCVで画像ファイルの読み込み、保存(imread, imwrite) Python, OpenCVで顔検出と瞳検出(顔認識、瞳認識) Python, OpenCVで画像を縦・横に連結 (hconcat, vconcat, np.tile) Python, NumPyで画像処理(読み込み、演算、保存) Python, OpenCVで画像にモザイク処理(全面、一部、顔など)

Last Updated: 6/26/2019, 10:34:03 PM