前フリ
以前に書いた記事の続きを1年ぶりに。
- Pythonで画像処理(その1)
- Pythonで画像処理(その2)
OpenCVを使って2値化するところは、OpenCVのドキュメントをそのまんま、Pythonで画像処理(その1)で書いたのだけれど、「2値化」ではなく、「2値化する際の閾値を求めて、その閾値以下の画素を切り捨てて表示する」とか、そんなことをやってみる。
画像の2値化
lennaの画像を2値下する。
import cv2
lenna = "4.2.04.tiff"
orig = cv2.imread(lenna, 0)
img = cv2.medianBlur(orig, 5)
ret,th = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
thが2値化された画像で、retが閾値である。
閾値以下の画素の切り捨て
単純に考えると、以下のようなコードでできそう。
height, width = img.shape
for y in range(height):
for x in range(width):
if img[y, x] < ret:
img[y, x] = 0
ただし、このコードには問題がある。numpyのarrayにforを適用すると、めっちゃ遅い。
なので、もっと速くできる方法はないか?というと、もちろんある。
low_idx = img < ret
img[low_idx] = 0
これで、画像を比較してみると、こんな感じ。
from matplotlib import pyplot as plt
plt.subplot(1,3,1)
plt.imshow(orig, cmap='gray'), plt.title('Original')
plt.subplot(1,3,2)
plt.imshow(img, cmap='gray'), plt.title('Threshold')
plt.subplot(1,3,3)
plt.imshow(th, cmap='gray'), plt.title('Binarize')
plt.show()
本日のまとめ
2値化するための閾値を求めて、その閾値でカットオフしてみた。