Python
OpenCV

Pythonで画像処理(その3)

前フリ

以前に書いた記事の続きを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()

lenna_20170917.png


本日のまとめ

2値化するための閾値を求めて、その閾値でカットオフしてみた。

本日のコード