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

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

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

PyAutoGUIは、Windows、Mac OS、Linuxに対応した、Python用のGUI自動化ライブラリです。

OpenCV

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

2回答

2602閲覧

スクリーンショットに対するOpenCVのテンプレートマッチングの精度が悪い

Asky

総合スコア17

PyAutoGUI

PyAutoGUIは、Windows、Mac OS、Linuxに対応した、Python用のGUI自動化ライブラリです。

OpenCV

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/10/24 09:36

前提・実現したいこと

画面の一部をスクリーンショットでキャプチャして,事前に用意した画像のどのあたりにキャプチャした内容が含まれているか判定したいです.

発生している問題

テンプレートマッチングの精度が低く,全く異なる位置とテンプレートマッチングします.
スクリーンショットを一旦書き込んで再読み込みするととりあえずは解消しますが,処理速度を速くしたいのとファイルの作成は出来るだけ控えたいので,別の方法でこの問題を解消したいです.

該当のソースコード

デスクトップ画面のゴミ箱のあたり(left, top, width, height) = (60, 20, 40, 40)をスクリーンショットでキャプチャして,
事前に用意しておいたデスクトップ画像のどこにキャプチャとの類似領域が存在するか判定するプログラムです.

最終的には,画面に次々現れる大量のアイコンを順にキャプチャして,事前に用意した全アイコンを表状に並べた画像中からキャプチャした対象とマッチするものを発見するプログラムにするつもりです.

Python

1import pyautogui 2import cv2 3import numpy as np 4 5IMG_DESKTOP = cv2.imread("desktop.png") 6 7if __name__ == '__main__': 8 # スクリーンショット 9 cap = pyautogui.screenshot(region = (60, 20, 40, 40)) 10 11 # 方法1 12 print("方法1") 13 result = cv2.matchTemplate(IMG_DESKTOP, np.uint8(cap), cv2.TM_CCOEFF_NORMED) 14 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) 15 top_left = max_loc 16 print("位置:", top_left) 17 print("類似度:", max_val) 18 19 # 方法2 20 print("方法2") 21 cap.save("cap.png") 22 img_tmp = cv2.imread("cap.png") 23 result = cv2.matchTemplate(IMG_DESKTOP, img_tmp, cv2.TM_CCOEFF_NORMED) 24 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) 25 top_left = max_loc 26 print("位置:", top_left) 27 print("類似度:", max_val) 28

結果

方法1 位置: (67, 644) 類似度: 0.3924467861652374 方法2 位置: (60, 20) 類似度: 0.9999991059303284

試したこと

上のコードの方法1のようなファイル読み書きをしない方法で実装したいです.
方法1と方法2を10000回繰り返すと,方法1の方が50秒も速く終わりました.
しかし上の結果の通り,方法1では(60, 20)とはまったく違う場所をマッチングしました.類似度も小さいです.

uint8へのキャストがマズいのかと思い,np.uint8をnp.float32に変えてみましたが,以下のようなエラーが返され,キャストはnp.float32では良くなさそうだというところまでは来ましたが,それ以上長時間手詰まりになってしまいました.

cv2.error: OpenCV(4.4.0) C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-9d_dfo3_\opencv\modules\imgproc\src\templmatch.cpp:1163: erro163: error: (-215:Assertion failed) (depth == CV_8U || depth == CV_32F) && type == _templ.type() && _img.dims() <= 2 in function 'Template'cv::matchTemplate'

補足情報(FW/ツールのバージョンなど)

python 3.8.5
opencv-python 4.4.0.44
PyAutoGUI 0.9.52

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

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

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

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

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

guest

回答2

0

pyautogui.screenshot が返すデータのフォーマットが何なのか知りませんが,OpenCVのMatとして扱うためには適切な変換が必要なのではないでしょうか.

ググったらこんなの出ました.

投稿2021/11/22 03:15

fana

総合スコア11996

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

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

0

経験上の話ですけどテンプレートマッチは事前にどういうふうにマッチさせたい画像を前処理するかで
精度が変わってくると思ってます。デスクトップ画面だと画像なので白黒に変換するのが効きそうです。
私の手前記事なのですが、
https://qiita.com/ykato/items/0d78275187a3d79bb18c
https://github.com/yasutakatou/webcamops/blob/master/webcamops.py
こんな風に形を白黒でハッキリさせたうえで、類似度の計算方法をcv2.TM_CCORRに変えたりで精度はあげられると思います。という具体的なコード修正でなくて、精度向上のためのネタとなりますがいかがでしょうか?

投稿2020/10/24 11:07

yasutakatou

総合スコア446

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問