見出し画像

アナログメーター 3(物体検出)

以前の記事に書いたように「機械式アナログメーターの指示値を推測するアプリケーションに挑戦中です。

機械式アナログメーター(ガスボンベの圧力ゲージ)の指示値を推測すると言う目標に向けて、携帯のカメラで撮影した画像1枚を使い、味見的にどこまでやれそうか感触を確認しています。

前回の円検出に続いて、OpenCVによる物体検出を試しました。

物体検出は指針の角度から指示値を推測するために、文字盤の中から所定の文字位置を検出するために必要な要素だと考えています。
文字 0 と 10 の位置(座標)と前回の円検出で得た中心座標を結ぶ2本の線分の角度と、前々回の指針の指示角度から、アナログメーターの指示値を推測出来るように思います。

タイトル画像の青い枠が物体として検出された部分です。

この中からテンプレートマッチング等によって3個の 0 を特定出来れば、当初の目的を達成出来そうです。

いつもながら、Webページを参考にしています。
今回は、こちらのページを主に参考にしました。
ありがとうございます。


Google Colaboratory

自分のPCに様々な環境を作ることなく、いろいろ試せるのでGoogle Colaboratory で実験しています。

ディレクトリー構造は以下の通りです。

My Drive/Colab/meter1  今回のワークディレクトリ
My Drive/Colab/meter1/images1/CVtest3.jpg  サンプル画像

サンプル画像は前回同様なので割愛します。
前々回の記事からサンプル画像をダウンロード出来ます。

ColaboratoryにMy Drive をマウントするために、以下を実行して指示に従います。
(セッション開始後に1回実行します。)

# drive マウント
from google.colab import drive
drive.mount('/content/drive/')
%cd "/content/drive/My Drive/Colab/meter1"
%ls

(最後の2行はワークディレクトリに移動して ls を実行しています。)


ソースコード

次のソースコードで、タイトル画像の結果を得ています。

# contour_detect.py
#!/usr/local/bin/python
#! -*- coding: utf-8 -*-

import cv2
import numpy as np

%cd "/content/drive/My Drive/Colab/meter1"

# 指定した画像(path)の物体を検出し、外接矩形の画像を出力します
def detect_contour(path):

   # 画像を読込
   src = cv2.imread(path, cv2.IMREAD_COLOR)

   # グレースケール画像へ変換
   gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)

   # 2値化
   #retval, bw = cv2.threshold(gray, 90, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
   retval, bw = cv2.threshold(gray, 90, 255, cv2.THRESH_BINARY)
   print(retval)
   cv2.imwrite('C_Area1.jpg', bw)

   # 輪郭を抽出
   #   contours : [領域][Point No][0][x=0, y=1]
   #   cv2.CHAIN_APPROX_NONE: 中間点も保持する
   #   cv2.CHAIN_APPROX_SIMPLE: 中間点は保持しない
   contours, hierarchy = cv2.findContours(bw, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)

   # 矩形検出された数(デフォルトで0を指定)
   detect_count = 0

   # 各輪郭に対する処理
   for i in range(0, len(contours)):

       # 輪郭の領域を計算
       area = cv2.contourArea(contours[i])

       # ノイズ(小さすぎる領域)と全体の輪郭(大きすぎる領域)を除外
       if area < 4e2 or 1.2e3 < area:
           continue

       # 外接矩形
       if len(contours[i]) > 0:
           rect = contours[i]
           x, y, w, h = cv2.boundingRect(rect)
           cv2.rectangle(src, (x, y), (x + w, y + h), (255, 0, 0), 2)
           '''
           # 外接矩形毎に画像を保存
           cv2.imwrite('./C_Area/' + str(detect_count) + '.jpg', src[y:y + h, x:x + w])
           '''
           detect_count = detect_count + 1
   '''
   # 外接矩形された画像を表示
   cv2.imshow('output', src)
   cv2.waitKey(0)

   # 終了処理
   cv2.destroyAllWindows()
   '''
   print(detect_count)
   cv2.imwrite('C_Area2.jpg', src)


if __name__ == '__main__':
 detect_contour("./images1/CVtest3.jpg")

検出した物体(矩形内の画像)を取り出すなど、いろいろ試したのでコメント行が残っている点、ご容赦下さい。

実行結果

/content/drive/My Drive/Colab/meter1
90.0
30

以下のファイルを出力します。

My Drive/Colab/meter1/C_Area1.jpg 検出準備画像
My Drive/Colab/meter1/C_Area2.jpg タイトル画像

検出準備画像は以下のような結果でした。

画像1



次はテンプレートマッチングを試す予定です。

何等か参考に成れば幸いです。



出来ればサポート頂けると、嬉しいです。 新しい基板や造形品を作る資金等に使いたいと思います。