アナログメーター 2(円を検出)
以前の記事に書いたように「機械式アナログメーターの指示値を読み取る」アプリケーションに挑戦中です。
「読み取る」のではなくて「推測する」と言うべきかも知れません。
前回の直線検出に続いて、openCVによるホフ変換の円検出を試しました。
機械式アナログメーター(ガスボンベの圧力ゲージ)の指針の向きを検出すると言う目標に向けて、携帯のカメラで撮影した画像1枚を使い、味見的にどこまでやれそうか感触を確認しています。
円検出は指針の軸とメーターの大きさを推定するために重要な要素だと考えています。
タイトル画像の緑の円と赤い点(中心)が検出結果です。
全部で5個の円を検出したようです。
[[[376 384 276]
[370 380 287]
[382 386 274]
[380 388 277]
[384 390 256]]]
いつもながら、Webページを参考にしています。
今回は、こちらのページを主に参考にしました。
ありがとうございます。
Google Colaboratory
自分のPCに様々な環境を作ることなく、いろいろ試せるのでGoogle Colaboratory で実験しています。
ディレクトリー構造は以下の通りです。
My Drive/Colab/meter1 今回のワークディレクトリ
My Drive/Colab/meter1/images1/CVtest3.jpg サンプル画像
サンプル画像は前回同様なので割愛します。
前回の記事からサンプル画像をダウンロード出来ます。
ColaboratoryにMy Drive をマウントするために、以下を実行して指示に従います。
# drive マウント
from google.colab import drive
drive.mount('/content/drive/')
%cd "/content/drive/My Drive/Colab/meter1"
%ls
ソースコード
次のソースコードで、タイトル画像の結果を得ています。
# HoughCircles関数
import cv2
import numpy as np
%cd "/content/drive/My Drive/Colab/meter1"
INPUT_IMG = './images1/CVtest3.jpg'
src = cv2.imread(INPUT_IMG)
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
gray = cv2.medianBlur(gray, 5)
cv2.imwrite('houghcircles1.jpg', gray)
# HoughCircles(image, method, dp, minDist, param1, param2, minRadius, maxRadius)
# image 入力画像 (シングルチャンネル)
# method ハフ変換の手法 現状、cv2.HOUGH_GRADIENTのみ設定可
# dp 処理時の画像解像度レベル 1:解像度変更なし、2:解像度を半分に変更
# minDist 検出される円の中心同士の最小距離
# param1 Canny() エッジ検出器に渡される2つの閾値の大きい方 低いほど、誤検出が生じる
# param2 円の中心を検出する際の投票数の閾値 低いほど、誤検出が生じる
# minRadius 検出される円の最小半径
# maxRadius 検出される円の最大半径
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT,dp=1,minDist=1,
param1=210,param2=180,minRadius=250,maxRadius=0)
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
# draw the outer circle
cv2.circle(src,(i[0],i[1]),i[2],(0,255,0),2)
# draw the center of the circle
cv2.circle(src,(i[0],i[1]),2,(0,0,255),3)
cv2.imwrite('houghcircles2.jpg', src)
print(circles)
以下のファイルを出力します。
My Drive/Colab/meter1/houghcircles1.jpg 検出準備画像
My Drive/Colab/meter1/houghcircles2.jpg タイトル画像
検出準備画像は以下のような結果でした。
(グレー変換しただけなのでほとんど変化ありません。)
タイトル画像の結果を得るために、検出される円の最小半径(minRadius)を調整しました。
機械式アナログメーター(ガスボンベの圧力ゲージ)の指針の向きを検出すると言う目標ですから、恣意的に最小半径を調整するのは好ましくありません。検出に使う画像のバラツキ範囲を抑えて試してみたいと思います。
現時点で考えているバラツキ範囲
1.全体が写っているメータは1個だけとする。
2.メーターの傾きは±15度以内とする。
3.メーター中心とカメラレンズを結ぶ直線の傾きはメーター面に対して
15度以下とする。
4.撮影画像内のメーター直径(ピクセル)バラツキは±15%以内とする。
5.直射日光や窓越しの屋外風景、照明器具などが写り込まないこと。
(背景及びメーター面への写り込み。)
制限が多いですが、以上の範囲で使えれば、とりあえず稼働させらるように思います。
openCV いろいろ楽しめそうです。