OpenCVでパルス数をカウントする
ラズパイやICの出力するパルス数をオシロスコープでカウントすることがありますが、数個ならともかく数が多くなってくると目視では厳しくなります。
一番簡単なのは、立ち上がりエッジのコーナーの部分でテンプレートマッチングを行うことで、マッチした数がパルス数になります。
に対して、テンプレートのマッチングをすると、
import cv2 as cv
import numpy as np
img = cv.imread("pulse.png")
img_gray = cv.imread("pulse.png", 0)
template = cv.imread("template.png", 0)
w,h = template.shape[::-1]
res = cv.matchTemplate(img_gray, template, cv.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where(res >= threshold)
print(f"pulse count {len(loc[0])}")
for pt in zip(*loc[::-1]):
cv.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
cv.imshow("", img)
cv.waitKey(0)
cv.destroyAllWindows()
pulse count 12
ルーラーが交差するところもヒットしてしまいましたが、これはルーラーを非表示にすれば済む話です。実際には8個なのにカウントが12になっているのは、ひとつのエッジを2回カウントしている箇所があるためです。
テンプレートマッチングは、対象画像上でテンプレート画像をスライドさせて、マッチングする(相互相関の値が大きい)箇所を抽出する方法です。今回はシンプルなテンプレートなので、ピークから1ピクセルスライドしただけでは相互相関が十分に下がらない(マッチングしてしまう)結果になっています。
実際、先頭のエッジの座標(50,222)周辺の相互相関は、以下のようになっていて
(49,222) 0.63255876
(50,222) 0.9331638
(51,222) 0.83463985
(52,222) 0.55312735
ひとつのエッジを2回カウントしていることがわかります。
近くのマッチングを除外するようにすると、
count = 0
prev = (0,0)
for pt in zip(*loc[::-1]):
if pt[0] - prev[0] > w or pt[1] - prev[1] > h:
cv.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
count += 1
prev = pt
print(f"pulse count {count}")
実行結果
pulse count 8
パルス数をカウントすることができました。
ちなみに、マッチングの手法は複数ありますが、今回は正規化相互相関(TM_CCOEFF_NORMED)を使っています。どれを使うかは、好みの部分が大きいと思います。
今回のテンプレートマッチングは、リプルを含むエッジを検出できないなど、汎用性に欠けます。その都度テンプレートを作成すればよいのですが、もう少しよい方法があると思います。
Author And Source
この問題について(OpenCVでパルス数をカウントする), 我々は、より多くの情報をここで見つけました https://qiita.com/shirokumaneko/items/906807380a6853494246著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .