Help us understand the problem. What is going on with this article?

【Google Colab】OpenCVでBounding Box検出

はじめに

OpenCVで物体のBounding Boxを検出してみました。

機械学習で物体検出のモデルを作成する際には、画像にBounding Boxとラベルを付けた情報が必要となります。このアノテーション作業の効率化に役立てばと思います。

画像はPixabayのフリー画像を使用しました。
また、以下を前提としてしています。

  • 対象とする物体は1つ(複数存在する場合、以下のコードでは最大のものを取得)
  • 背景は白色もしくはそれに類する色(異なる場合、hsvで指定する値の範囲を変更する)

環境

言語はPython、環境はGoogle Colaboratoryを使用します。

コード

コード全体は以下です。

import cv2
import numpy as np

from google.colab.patches import cv2_imshow

img_path = "/path/to/image_file"

img = cv2.imread(img_path)

img2 = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 0], dtype = "uint8")
upper = np.array([255, 50, 255], dtype = "uint8")
img2 = cv2.inRange(img2, lower, upper)
img2 = cv2.blur(img2, (2, 2))
ret, img2 = cv2.threshold(img2, 0, 255, cv2.THRESH_BINARY)
img2 = cv2.bitwise_not(img2)
contours, hierarchy = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = max(contours, key=lambda x: cv2.contourArea(x))
x, y, w, h = cv2.boundingRect(contours)
img = cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 3)
cv2_imshow(img)

結果は以下です。

image.png

説明

以下、コードの内容を説明します。

まず、必要なライブラリをインストールします。

import cv2
import numpy as np

from google.colab.patches import cv2_imshow

次に、画像を読み込みます。
元画像を表示すると以下になります。

img_path = "/path/to/image_file"

img = cv2.imread(img_path)
cv2_imshow(img)

image.png

次に、以下の操作を行います。

  • 画像をRGBからHSVに変換(RGBとHSVの関係についてはこちら
  • H,S,Vの値が指定した範囲内の色の部分のみ取り出す
  • ノイズ除去のため、blur(ぼかし)処理を行う(「ぼかし、平滑化」についてはこちら
  • 二値化する(「二値化」についてはこちら
  • 白黒反転する

この画像を表示すると以下になります。

img2 = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 0], dtype = "uint8")
upper = np.array([255, 50, 255], dtype = "uint8")
img2 = cv2.inRange(img2, lower, upper)
img2 = cv2.blur(img2, (2, 2))
ret, img2 = cv2.threshold(img2, 0, 255, cv2.THRESH_BINARY)

img2 = cv2.bitwise_not(img2)

cv2_imshow(img2)

image.png

最後に、以下の操作を行います。

  • findContoursで輪郭を検出
  • 検出した輪郭のうち、最大のものを取得
  • 輪郭の外接矩形(Bounding Box)を取得
  • Bounding Boxを描画

最終的に、Bounding Boxを描画した図を得ます。

contours, hierarchy = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = max(contours, key=lambda x: cv2.contourArea(x))
x, y, w, h = cv2.boundingRect(contours)
img = cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 3)
cv2_imshow(img)

image.png

参考

h_yuma
都内でエンジニアとして働いています。
wit
ひとびとの明日を今日より健康にする
https://www.asken.inc/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away