PythonとOpenCVで矩形の中のラベルを抽出する方法

画像認識で物体抽出ってあるじゃん?
AIの学習の疑問
矩形の中のラベルを抽出したいんだけど、どうやればできるの?
AIの学習の疑問

物体抽出はOpenCVというフレームワークで簡単に実現できるよ。OpenCVの使い方を説明するね。
AIの学習の疑問への回答

1.OpenCVとは

OpenCVとは

OpenCVはインテルが開発・公開したオープンソースのコンピュータビジョン向けライブラリです。画像処理・画像解析および機械学習等の機能を持つC/C++、Java、Python、MATLAB用ライブラリを備えています。2009年にWillow Garageに開発が移管された後、2015年現在はItseezがメンテナンスしています。

【OpenCVの公式サイト】
https://opencv.org/

OpenCVで出来ること

  • 画像フィルタリング
  • 幾何学的画像変換
  • 描画機能
  • 色空間変換
  • OpenCVのカラーマップ
  • 平面区画
  • ヒストグラム
  • 構造解析と形状記述子
  • モーション分析とオブジェクト追跡
  • 特徴検出
  • 物体検出

OpenCVの主だった機能はディープラーニングではない

物体抽出、画像認識と聞くと流行りの深層機械学習(ディープラーニング)を思い浮かべるかもしれませんが、OpenCVは基本的にディープラーニングは使っていません。
OpenCVは画像解析ライブラリ+機械学習ライブラリで、ロジスティック回帰や多層パーセプトロンなど機械学習を行うためのライブラリも備えていますが、画像解析をディープラーニングで行っている分けではありません。

2.OpenCVを使って矩形の中のラベルを抽出する

試したこと

↓↓↓ 画像の中から赤い矩形に囲まれた部分だけを抽出する
OpenCVによる矩形キャプチャ

OpenCVの実装(Python)

import cv2
import numpy as np

# ①画像の読み込み
src = cv2.imread("target.jpg", cv2.IMREAD_COLOR)
# ②RGBをHSVに変換
img_HSV = cv2.cvtColor(src, cv2.COLOR_BGR2HSV_FULL)
# ③赤い矩形以外をフィルタ
imgH = img_HSV[:, :, 0]
imgS = img_HSV[:, :, 1]
maskIMG = np.zeros(imgH.shape, dtype=np.uint8)
maskIMG[((imgH < 20) | (imgH > 200)) & (imgS > 128)] = 255

# ④矩形の位置情報を取得
contours, hierarchy = cv2.findContours(maskIMG , cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)

# ⑤矩形の位置情報を元に元の画像を切り抜く
detect_count = 0
for i in range(0, len(contours)):
    area = cv2.contourArea(contours[i])
    if area < 1e3 or 1e5 < area:
        continue
    if len(contours[i]) > 0:
        rect = contours[i]
        x, y, w, h = cv2.boundingRect(rect)
        cv2.imwrite('result.jpg', src[y:y + h, x:x + w])
        detect_count = detect_count + 1
        break

実行結果

result.jpg

OpenCVによる矩形キャプチャ

できましたー

3.ソースの解説

①画像の読み込み (imread)

OpenCVで画像を読み込むにはimreadを使います。
src = cv2.imread("target.jpg", cv2.IMREAD_COLOR)

  • 第1引数 : 画像ファイルパス
  • 第2引数 : 画像の読み取り方法を指定するフラグ
    • cv2.IMREAD_COLOR:カラー画像をロードします。画像の透明度は無視されます。これはデフォルトのフラグです。
    • cv2.IMREAD_GRAYSCALE:グレースケールモードで画像を読み込みます
    • cv2.IMREAD_UNCHANGED:アルファチャネルを含む画像をロードします

②RGBをHSVに変換(cvtColor)

RGB色空間は画像解析では扱い辛いのでHSV色空間に変換します。色空間の変換はcvtColorを使います。
img_HSV = cv2.cvtColor(src, cv2.COLOR_BGR2HSV_FULL)

  • 第1引数 : 8ビット符号なし整数型,16ビット符号なし整数型( CV_16UC... ),または単精度浮動小数型の入力画像
  • 第2引数 : 色空間の変換コード
    • cv2.COLOR_BGR2GRAY:RGB→Gray変換
    • cv2.COLOR_BGR2HSV:RGB→HSV変換

HSV色空間についてはこちらを参照ください。
wikipedia:HSV色空間

③赤い矩形以外をフィルタ

赤色の画像だけに絞り込みます。指定の色の画像だけに絞りこむにはHSV色空間のHを見ることで行えます。

imgH = img_HSV[:, :, 0]
imgS = img_HSV[:, :, 1]
maskIMG = np.zeros(imgH.shape, dtype=np.uint8)
maskIMG[((imgH < 20) | (imgH > 200)) & (imgS > 128)] = 255

元の画像

OpenCVによる矩形キャプチャ

赤色のみに絞り込んだ画像

OpenCVによる矩形キャプチャ

④矩形の位置情報を取得

矩形の位置情報を取得するにはfindContoursを使います。
contours, hierarchy = cv2.findContours(maskIMG , cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)

  • 第1引数 : 8ビット符号なし整数型,16ビット符号なし整数型( CV_16UC... ),または単精度浮動小数型の入力画像
  • 第2引数 : 輪郭を検索する方法
    • cv2.RETR_EXTERNAL: 一番外側の輪郭のみ抽出する。
    • cv2.RETR_LIST: すべての輪郭を抽出するが、階層構造は作成しない。
    • cv2.RETR_CCOMP: すべての輪郭を抽出し、2階層の階層構造を作成する。
    • cv2.RETR_TREE: すべての輪郭を抽出し、ツリーで階層構造を作成する。
  • 第3引数 : 輪郭点の近似手法
    • CHAIN_APPROX_NONE:輪郭線上のすべての点を検出する
    • CHAIN_APPROX_SIMPLE: 輪郭の冗長な点を削除して、必要最小限の点を検出する

⑤矩形の位置情報を元に元の画像を切り抜く

矩形の位置が分かったので、その位置情報を元に元の画像を切り抜いて、矩形に囲まれたところのみを抽出します。
今回は、最初に見つかった矩形のみを抽出しました。

detect_count = 0
    # 矩形の数だけループ
    for i in range(0, len(contours)):
        # 小さい矩形と大きすぎる矩形は無視
        area = cv2.contourArea(contours[i])
        if area < 1e3 or 1e5 < area:
            continue
        if len(contours[i]) > 0:
            # 矩形の位置情報(x, y, w, h)を取得
            rect = contours[i]
            x, y, w, h = cv2.boundingRect(rect)
            # 元の画像を矩形の位置情報で切り抜く
            cv2.imwrite('result.jpg', src[y:y + h, x:x + w])
            detect_count = detect_count + 1
            break

取得された画像

OpenCVによる矩形キャプチャ

本日は以上となります。少しでもお役にたてたら幸いです。
宜しくお願いします

広告




スポンサーリンク
広告




広告




シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
広告