2021/1/31

カレーライスの画像からカレーとライスを抽出する(OpenCV ヒストグラムの逆投影法)


はじめに

ヒストグラムの逆投影法を用いると画像の中から特定のオブジェクトを探して抽出することができます。 この記事ではカレーライスの画像からカレーとライスの範囲を抽出するサンプルを通してヒストグラムの逆投影法を試します。

OpenCV-Python Tutorialsの下記記事を参考にしています。

Histogram - 4 : Histogram Backprojection

前提条件

  • macOS: BigSur 11.1
  • Python: 3.9.0
  • numpy: 1.19.5
  • opencv-python: 4.5.1.48

カレーライスの画像

これが今回用いるカレーライスの画像です。 この画像からカレーとライスの部分をそれぞれ抽出します

サンプルコードはカレーを抽出する処理ですが、ライスも同様に抽出できます。

手順

  1. カレーライス画像読み込み
  2. カレーのオブジェクトを範囲指定
  3. カラーヒストグラムの計算
  4. ヒストグラムを正規化し逆投影を適用
  5. モルフォロジー変換
  6. しきい値とマスク処理

1. カレーライス画像読み込み

まずは対象の画像(カレーライス)を読み込みます。

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('curry.jpg')
cv2.imshow("image", img)

カレーライスの画像

2. カレーのオブジェクトを範囲指定

カレーライスのうちカレーの範囲を選択します。

# curry axios
cx = 2000
cy = 2000
cw = 250
cv2.rectangle(img, (cx, cy), (cx + cw, cy + cw), (255, 0, 0),thickness=3)
curry_asset = img[cy:cy + cw, cx:cx + cw]
cv2.imshow("2-1", img)
cv2.imshow("2-2.jpg", curry_asset)

カレーライスの画像

カレーライスの画像

3. カラーヒストグラムの計算

検索対象(カレーライス)と検索したいオブジェクト(カレー) の両方のカラーヒストグラムを計算します。

hsv = cv2.cvtColor(curry_asset,cv2.COLOR_BGR2HSV)
hsvt = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
# calculating object histogram
roihist = cv2.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] )
cv2.imshow("3-1", hsv)
cv2.imshow("3-2", hsvt)

カレーライスの画像

カレーライスの画像

4. ヒストグラムを正規化し逆投影を適用

# normalize histogram and apply backprojection
cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX)
dst = cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1)
cv2.imshow("4", dst)

カレーライスの画像

5. モルフォロジー変換

正方形のカーネルを作成しモルフォロジー演算処理

# Now convolute with circular disc
disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(10,10))
cv2.filter2D(dst,-1,disc,dst)
cv2.imshow("5", dst)

カレーライスの画像

6. しきい値とマスク処理

# threshold and binary AND
ret, thresh = cv2.threshold(dst, 255, 255, 255)
thresh = cv2.merge((thresh, thresh, thresh))
res = cv2.bitwise_and(img, thresh)
cv2.imshow("6", res)

カレーライスの画像

カレーライスの画像

同様の処理でライスも抽出します。

カレーライスの画像

カレーライスの画像からカレーとライスを抽出できました。

参考