LoginSignup
3
0

More than 1 year has passed since last update.

【画像処理】Numpyでモルフォロジー演算

Posted at

Numpyでモルフォロジー演算を実装してみます。

まず、使用する画像を読み込んでグレースケール画像に変換します。

import numpy as np
import matplotlib.pyplot as plt

original_image = plt.imread(image_name)
if np.issubdtype(original_image.dtype, np.floating):
  original_image = (original_image * 255).astype(np.uint8)
gray_image = (0.2116 * original_image[:,:,0] + 0.7152 * original_image[:,:,1] + 0.0722 * original_image[:,:,2]).astype(np.uint8)
plt.imshow(gray_image, cmap='gray')

GrayImage.png

二値画像も作成します。二値画像作成の詳細については以下の記事を参照してください。
【画像処理】Numpyで大津の二値化(判別分析法) - Qiita

def thresholding(image, threshold):
  return np.where(image <= threshold, 0, 255)

binary_image = thresholding(gray_image, 128)
plt.imshow(binary_image, cmap='gray')

BinaryImage.png

収縮 (Erosion)

前景(白)を一回り小さくするモルフォロジー演算を収縮(Erosion)と呼びます。注目画素とその近傍画素の最小値を注目画素の値にします。

def erode(image, boundary='edge'):
  pad_image = np.pad(image, 1, boundary)
  areas = np.lib.stride_tricks.as_strided(pad_image, image.shape + (3, 3), pad_image.strides * 2)
  return np.min(areas, axis=(2, 3))

収縮を二値画像に適用します。

erode_binary_image = erode(binary_image)
plt.imshow(erode_binary_image, cmap='gray')

ErodeBinaryImage.png

収縮をグレースケール画像に適用します。

erode_gray_image = erode(gray_image)
plt.imshow(erode_gray_image, cmap='gray')

ErodeGrayImage.png

膨張 (Dilation)

前景(白)を一回り大きくする処理を膨張(Dilation)と呼びます。注目画素とその近傍画素の最大値を注目画素の値にします。

def dilate(image, boundary='edge'):
  pad_image = np.pad(image, 1, boundary)
  areas = np.lib.stride_tricks.as_strided(pad_image, image.shape + (3, 3), pad_image.strides * 2)
  return np.max(areas, axis=(2, 3))

膨張を二値画像に適用します。

dilate_binary_image = dilate(binary_image)
plt.imshow(dilate_binary_image, cmap='gray')

DilateBinaryImage.png

膨張をグレースケール画像に適用します。

dilate_gray_image = dilate(gray_image)
plt.imshow(dilate_gray_image, cmap='gray')

DilateGrayImage.png

オープニング (Opening)

複数回の収縮のあとに、同じ回数膨張する処理をオープニング(Opening)と呼びます。

def opening(image, n=2, boundary='edge'):
  for i in range(n):
    image = erode(image, boundary)
  for i in range(n):
    image = dilate(image, boundary)
  return image

オープニングを二値画像に適用します。

opening_binary_image = opening(binary_image)
plt.imshow(opening_binary_image, cmap='gray')

OpeningBinaryImage.png

オープニングをグレースケール画像に適用します。

opening_gray_image = opening(gray_image)
plt.imshow(opening_gray_image, cmap='gray')

OpeningGrayImage.png

クロージング (Closing)

複数回の膨張のあとに、同じ回数収縮する処理をクロージング(Closing)と呼びます。

def closing(image, n=2, boundary='edge'):
  for i in range(n):
    image = dilate(image, boundary)
  for i in range(n):
    image = erode(image, boundary)
  return image

クロージングを二値画像に適用します。

closing_binary_image = closing(binary_image)
plt.imshow(closing_binary_image, cmap='gray')

ClosingBinaryImage.png

クロージングをグレースケール画像に適用します。

closing_gray_image = closing(gray_image)
plt.imshow(closing_gray_image, cmap='gray')

ClosingGrayImage.png

トップハット (Top-Hat)

元の画像からオープニングを施した画像を引く処理をトップハット(Top-Hat)と呼びます。
トップハット画像にはオープニングにより削除された値が残ります。

def tophat(image, n=2, boundary='edge'):
  opening_image = opening(image, n, boundary)
  return image - opening_image

トップハットを二値画像に適用します。

tophat_binary_image = tophat(binary_image)
plt.imshow(tophat_binary_image, cmap='gray')

TophatBinaryImage.png

トップハットをグレースケール画像に適用します。

tophat_gray_image = tophat(gray_image)
plt.imshow(tophat_gray_image, cmap='gray')

TophatGrayImage.png

ブラックハット (Black-Hat)

クロージングを施した画像から元画像を引く処理をブラックハット(Black-Hat)と呼びます。
ブラックハット画像にはクロージングより追加された値が残ります。

def blackhat(image, n=2, boundary='edge'):
  closing_image = opening(image, n, boundary)
  return closing_image - image

ブラックハットを二値画像に適用します。

blackhat_binary_image = blackhat(binary_image)
plt.imshow(blackhat_binary_image, cmap='gray')

BlackhatBinaryImage.png

ブラックハットをグレースケール画像に適用します。

blackhat_gray_image = blackhat(gray_image)
plt.imshow(blackhat_gray_image, cmap='gray')

BlackhatGrayImage.png


実装したコードはGoogle Colabratoryに置いてあります。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0