質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

1330閲覧

Python OpenCV で実装するオリジナルマーカーのマッチングが非常に重くなる

vibrato

総合スコア52

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

1クリップ

投稿2017/12/07 17:11

###改善案をご教授願いたい

少し前にこちらで、OpenCVで任意の画像をオリジナルマーカーとして読み込む方法を質問させていただきました。
(その時の投稿:https://teratail.com/questions/103524)

おおまかに説明すると
任意画像Aをマーカーとしたとき、マーカーを読取った結果、"任意画像A"と出力される機能
の実装を目指しています。この機能の実装は

  • 枠の抽出
  • 台形補正
  • テンプレートマッチング

これらの方法で実現可能であると親切に教えていただきました。

様々なページを参考に組み合わせた結果、認識率に改善の余地があるものの希望の動作に成功致しました。
ただタイトルにもある通り非常に重くなるのです。原因は以下。

###主要因

  • マッチング対象が多い(マーカーは今後増やし続ける)
  • 任意の画像であるためサイズがバラバラ

原因はこの2点であると推測でき、同時にこの2点は必須機能となります。

###要因の解釈

python

1# 全部を書くと読みづらくなると思いますので意味合いだけ明示します 2 3cam = cv2.VideoCapture(0) 4while True: 5 6 orig = cam.read()[1] 7 copy = orig.copy() 8 9 for img in マッチング対象画像パスlist: 10   marker = imread(img, 0) 11 size = (img.shape[0], img.shape[1]) 12 13 補正結果 = 台形補正(copy, 台形かど座標4, size) 14 15 if matching(補正結果, marker) is マッチングしていたら: 16 print("matching!!") 17 プログラム終了

伝わっていただけると嬉しいですが、
while True:を一回通る度に、マッチング対象画像の数だけ、台形補正を行い、マッチング判定を行っている
という構造になっており、sizeを取得するために、このような構造をとっています。

読取るマーカーのサイズが様々なので、sizeを固定してしまうと、ほとんどの場合で縦横比がズレてしまい、マッチングに成功しないので、自分の知識・知恵ではこの構造をとらざるを得ない状態です;

###質問まとめ

  • マッチング対象が多い(マーカーは今後増やし続ける)
  • 任意の画像であるためサイズがバラバラ

この二つを条件をクリアしたまま、処理を軽くする方法または考え方はないものでしょうか?
是非皆様の知恵をお貸し下さい。宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

テンプレートマッチングの実用上の問題は速度だというようなことをよく見かける気がします。
今回のコードの場合、台形補正の演算の一部をサボれそうだというのはLouiS0616さんのおっしゃるとおりだと思います。

それでも遅いというのならまず、スケール不変性のあるような特徴量に変換することが考えられます。
有名なものだとHOG,SIFT,SURFなどでしょうか。どれもOpenCVに実装されていたような気がします。
http://www.vision.cs.chubu.ac.jp/cvtutorial/PDF/02SIFTandMore.pdf
スケール不変性を持てばサイズ変更の必要はなくなります。
マーカーのサイズを前処理することも考えられます。

画像のマッチングというのは遅いことが多いので、もっとシンプルなもので候補を絞り込むことも重要です。
人の顔の認識にHaar-like検出器が有名だと思います。
https://qiita.com/nonbiri15/items/c8e666c4964d09ace652
人以外の例でフィルタを使ったもの。
https://www.slideshare.net/TakeshiHasegawa1/20151016ssmjpikalog
https://www.slideshare.net/TakeshiHasegawa1/ikalog20161125nsstudy
木構造のようにマーカーを分類しておけば、フィルタによって判定すべきマーカーを絞り込めます。

マッチングというのは難しいものでして、最もスコアが高いものが正解というのが一般的な判断基準かと思います。
ですので、マッチしたら終了というのは精度の観点から不満があるかもしれません。
また、マーカーの種類を増やしていく予定ならば、マーカーのかず倍だけ計算が増えていくので、テンプレートマッチングがすごく不利です。
マーカー間を区別する特徴量を抽出しておけば、判定したい画像に対して特徴量を算出して、後は特徴量間の距離を計算するだけになります。
主成分分析(PCA)のような手法が有効です。

あまりないとは思いますが、マーカーのピクセル数が多いと距離の計算に時間がかかりますので、荒くなりすぎない程度に粗視化することも考えられます。


python

1makers = [] 2sizes = [] 3for img in 4 markers.append(imread(img, 0)) 5 サイズ補正 6 7cam = cv2.VideoCapture(0) 8while True: 9 orig = cam.read()[1] 10 copy = orig.copy() 11 12 台形の補正 13 サイズ補正 14 15 # 後はマッチング速度を改善するだけ 16 for marker in markers: 17 if matching(補正結果, marker) is マッチングしていたら: 18 print("matching!!") 19 プログラム終了 20

投稿2017/12/08 02:06

編集2017/12/08 02:16
mkgrei

総合スコア8560

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

とりあえずマーカー読出しを外部に切り出しては?
また、マーカーのサイズがばらばらでも、台形補正部分はまとめて出来ると思います。

Python

1makers = [] 2sizes = [] 3for img in 4 markers.append(imread(img, 0)) 5 sizes.append((img.shape[0], img.shape[1])) 6 7cam = cv2.VideoCapture(0) 8while True: 9 orig = cam.read()[1] 10 copy = orig.copy() 11 12 台形の補正はここでやってしまう 13 14 for marker, size in zip(markers, sizes): 15 サイズ補正 16 if matching(補正結果, marker) is マッチングしていたら: 17 print("matching!!") 18 プログラム終了

投稿2017/12/07 17:27

LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

vibrato

2017/12/08 03:25 編集

回答ありがとうございます!!!!!!! 自分なりに少し手を加えましたが、頂いた助言により、改善しました!! SIZE = (○○○, ×××) resized_markers = [] for img in マッチング対象画像パスlist: ........marker = imread(img, 0) ........marker = cv2.resize(marker, SIZE) ........resized_markers.append(marker) cam = cv2.VideoCapture(0) while True: ....orig = cam.read()[1] ....copy = orig.copy() ....補正結果 = 台形補正(copy, 台形かど座標4点, SIZE) ....for marker in resized_markers: ........if matching(補正結果, marker) is マッチングしていたら: ............print("matching!!") ............プログラム終了 補正のサイズを固定しておいて、マーカーの方をそのサイズに合わせるという発想は、自分には無かったです! 的確なアドバイス誠にありがとうございました!!おかげさまで処理が大変軽くなりました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問