ytbilly3636’s 研究備忘録

機械学習,Python,ガンダムなど

Pythonによる画像の二値化

こんにちは.久しぶりの技術系ネタです.

先日研究室でこのような会話がありました.

メンバ「Pythonで画像の二値化ってどうやってる?」
わたし「OpenCVのメソッドを使ってます」
メンバ「そっか……OpenCV入れないといけないのか」
わたし「あ,ちょっと待ってください!」
(しばらく経って)
わたし「OpenCV無しでもできました」
メンバ「ありがとう,お礼にお菓子をあげよう」

ということで,お菓子をもらえたのでここで共有しておきます.

実装したコード

実行にはNumpyとOpenCVの導入が必要です.

$ sudo apt-get install python-numpy
$ sudo apt-get install libopencv-dev python-opencv

下記のコードでは, 画像(image_example.jpg)をグレースケールモードで読み込み, OpenCVの二値化処理とOpenCVを使わない二値化処理を行っています. 閾値は適当に127としました.

#!/usr/bin/python
#-*- coding:utf-8 -*-

import numpy as np
import cv2

# original image (gray scale image)
org_img = cv2.imread('image_example.jpg', 0)

# preference
THRESHOLD = 127
MAXVALUE  = 255

# binarization using opencv
_, bin_cv2 = cv2.threshold(org_img, THRESHOLD, MAXVALUE, cv2.THRESH_BINARY)

# binarization not using opencv
bin_npy = np.zeros(org_img.shape, org_img.dtype)
bin_npy[np.where(org_img > THRESHOLD)] = MAXVALUE

# check
cv2.imwrite('original.png',   org_img)
cv2.imwrite('binary_cv2.png', bin_cv2)
cv2.imwrite('binary_npy.png', bin_npy)

結果

入力画像(image_example.jpg)には昨年タイに行ったときに撮影した遺跡の写真を使いました. f:id:ytbilly3636:20170325234024j:plain

original.png f:id:ytbilly3636:20170325234130p:plain

binary_cv2.png f:id:ytbilly3636:20170325234158p:plain

binary_npy.png f:id:ytbilly3636:20170325234216p:plain

簡単な解説

OpenCVの二値化はthresholdというメソッドに画像を渡すだけです. このメソッドの返り値は2つありますが,処理後の画像は2番目になるようです. 引数の詳細については下記リンクを参照してください.

Miscellaneous Image Transformations — OpenCV 2.4.13.2 documentation

OpenCVを使わない場合は,numpy.whereというメソッドを活用します. このメソッドは引数の条件を満たすインデックスを返却します. つまり上記の例ではorg_imgの中から閾値よりも大きい要素のインデックスを返却しています. そのインデックスの部分を255,それ以外を0にすることで二値化画像を生成しています.