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)には昨年タイに行ったときに撮影した遺跡の写真を使いました.
original.png
binary_cv2.png
binary_npy.png
簡単な解説
OpenCVの二値化はthresholdというメソッドに画像を渡すだけです. このメソッドの返り値は2つありますが,処理後の画像は2番目になるようです. 引数の詳細については下記リンクを参照してください.
Miscellaneous Image Transformations — OpenCV 2.4.13.2 documentation
OpenCVを使わない場合は,numpy.whereというメソッドを活用します. このメソッドは引数の条件を満たすインデックスを返却します. つまり上記の例ではorg_imgの中から閾値よりも大きい要素のインデックスを返却しています. そのインデックスの部分を255,それ以外を0にすることで二値化画像を生成しています.