【画像認識】自分のPCでは動くのに他のPCで認識しない原因は「表示倍率」だった

PythonとOpenCVによる画像認識が、PC Aでは成功しPC Bでは失敗する様子を示したイラスト。原因はWindowsの表示倍率の違いであることを表している 実績・ポートフォリオ

はじめに

画像認識を使った自動化ツールを作ると、よくぶつかる壁があります。自分のPCでは完璧に動くのに、他の人のPCだと画像が見つからない、という問題です。

前回の記事で紹介した、Excelのデータを業務画面へ自動入力するツールでも、同じことが起きました。このツールは、画面に出るエラーマークや保存完了のチェックマークを画像で見つけて、次の動きを決めています。

【スクリプト機能OFFでもOK】SAPへの工数入力をExcelから自動化するツールを作りました
SAPへの工数入力・実績登録を、Excelのボタン1つで自動化するツールを紹介します。 会社でSAPのスクリプト機能が使えなくても動き、エラーの検知や結果の記録も自動です。 デモ動画と導入の流れも掲載しています。

結論からいうと、原因はWindowsの表示倍率でした。PCごとに画面上のアイコンの大きさが数pxずつ違っていて、それだけで画像認識は失敗します。

この記事では、次の3つを解説します。

  • 実際にどんな症状が出たか
  • スクショを使った原因の調べ方
  • 対策の考え方

pyautoguiやOpenCVで画像認識を使っていて、同じ症状で困っている方の参考になればうれしいです。

実際に起きたこと

ツールを作ったPCでは、何日も問題なく動いていました。ところが、同じツールを職場の他のPCで動かすと、次のようなことが起きました。

  • エラーの画面が出ているのに、エラーマークを見つけられない
  • 保存が完了しているのに、完了のチェックマークを見つけられず、ツールが「失敗」と判断して止まる

画面を目で見ると、エラーマークもチェックマークもちゃんと表示されています。人には同じ画面に見えるのに、プログラムだけが見つけられない状態です。

やっかいなのは、エラーも何も出ずに「見つからない」という結果だけが返ってくることです。プログラムの書き間違いなのか、画像の切り方が悪いのか、PCの設定の問題なのか、この時点では分かりません。

原因の調べ方:スクショでアイコンの大きさを測る

原因を突き止めるのに一番役立ったのは、それぞれのPCで画面のスクショを撮って、アイコンの大きさをpx単位で比べることでした。特別なソフトは要りません。

  1. 動くPCと動かないPCで、同じ画面を表示する
  2. それぞれでスクショを撮る(Windowsキー+Shift+S、またはPrintScreen)
  3. ペイントなどの画像ソフトで開き、同じアイコンを範囲選択する
  4. 画面の下に出る選択範囲のサイズ(〇〇×〇〇px)を記録して比べる

実際に測った結果がこちらです。

測ったものPC APC B
エラー画面のアイコン37px43px
保存完了のチェックマーク18×17px15×15px
スクショ全体1931×1019px1920×1029px

人の目では同じに見えるアイコンでも、pxで測ると数pxから6pxほど大きさが違っていました。37pxと43pxなら、約1.16倍の差です。

ここまで分かれば、プログラムの書き間違いではなく、画面の表示の問題だと切り分けられます。

エラーマークの大きさ比較。PC Aは37px、PC Bは43pxで表示され、約1.16倍の差がある
同じエラーマークなのに、PCごとに37pxと43pxに見えていた(PC A 37px/PC B 43px)

見た目はほぼ同じでも、ピクセルで測ると数px違う。これが画像認識の一致率を左右する。

原因:Windowsの表示倍率でアイコンの大きさが変わる

Windowsには、画面の文字やアイコンを大きく表示する「表示倍率」の設定があります。場所は、設定 → システム → ディスプレイ → 拡大/縮小です。100%、125%、150%などが選べ、ノートPCでは125%や150%が最初から選ばれていることもよくあります。

この倍率が違うと、同じアイコンでも画面上の大きさ(px)が変わります。さらに、拡大されたアイコンは輪郭が少しぼやけたり、色の境目が変わったりします。

一方、よく使われる画像認識(pyautoguiのlocateOnScreenやOpenCVのmatchTemplate)は、登録した画像と同じ大きさのものしか探せません。登録した画像を画面の上で少しずつずらしながら重ねて、どれだけ一致するかを測る仕組みだからです。

たとえるなら、37mmの型紙を使って、43mmの絵を探しているような状態です。絵柄は同じでも、重ねると線がずれて、「一致しない」と判断されます。

つまり、次の流れで失敗していました。

  1. ツールを作ったPCで、そのPCの大きさのアイコンを画像として登録する
  2. 表示倍率の違うPCでは、アイコンが別の大きさで表示される
  3. 大きさが合わないので、一致度が上がらず「見つからない」になる

もう一つの落とし穴が、プログラム側が画面の倍率を正しく認識しているかどうかです。倍率を意識していないプログラムには、Windowsが「100%のふり」をして画面を見せることがあります。このとき、スクショの大きさや座標が実際の画面とずれます。先ほどの表で、スクショ全体の大きさまで違っていたのは、この影響も考えられます。

また、業務アプリによっては、アプリ自身が倍率に合わせて独自にアイコンを描き直します。そのため、倍率が125%だからといって、アイコンがちょうど1.25倍になるとは限りません。部品ごとに大きさの変わり方が違うこともあります。

試したことと結果

原因にたどり着くまでに、いくつか回り道をしました。同じ症状で悩んでいる方の時間の節約になるよう、試した順に書いておきます。

試したこと結果
エラーマークの画像を小さく切り直すエラーマークは見つかるようになったが、完了のチェックマークは見つからないまま
プログラムに倍率を正しく認識させる1行を足す別のPCで、今度はそれまで見つかっていたエラーマークが見つからなくなった
表示倍率や文字サイズの設定を、PC同士でそろえる改善しない
大きさが違っても見つけられる探し方に変えるすべてのPCで、エラーマークも完了のチェックマークも見つかるようになった

ここで分かったのは、一つの大きさに合わせるやり方では、どこかのPCで必ずずれるということです。あるPCに合わせると、別のPCで合わなくなります。表示倍率の設定をそろえても、アプリ側の描き方の違いまではそろいません。

そこで「大きさを合わせる」のをやめ、大きさが違う前提で探す方向に切り替えたところ、ようやく安定しました。

対策の考え方

対策は、手軽なものから順に3つあります。実際には組み合わせて使います。あわせて、やってはいけない対策も紹介します。

そのPCで画像を撮り直す

一番手軽なのは、動かないPCでアイコンの画像を撮り直すことです。そのPCの大きさの画像になるので、その場では動きます。

ただし、PCの台数分だけ画像を用意することになります。表示倍率を変えたり、モニターをつなぎ替えたりすると、また動かなくなります。とりあえず動かしたいときの応急処置と考えてください。

プログラムに倍率を正しく認識させる

Pythonなら、プログラムの先頭に次の1行を入れます。

import ctypes
ctypes.windll.user32.SetProcessDPIAware()

これでWindowsが「100%のふり」をしなくなり、スクショの大きさや座標が実際の画面と一致します。画像認識やマウス操作を使うなら、入れておくべき1行です。

ただし、先ほどの表のとおり、これだけでは解決しませんでした。ズレはなくなりますが、アイコンが実際にPCごとに違う大きさで表示されていることは変わらないからです。むしろ、本当の大きさの違いがそのまま見えるようになります。

大きさが違っても見つけられる探し方にする

最終的に効いたのがこれです。登録した画像を1つの大きさで探すのではなく、少し小さくしたり大きくしたりしながら何通りかの大きさで探し、一番よく一致したものを採用するやり方です。

先ほどのたとえでいえば、37mm、40mm、43mm…と型紙を何枚も用意しておき、一番ぴったり重なったもので判断するイメージです。

この方法に変えたあと、実際のスクショで一致度(1.00が完全一致)を測ると、次のようになりました。

画像画面に出ているとき出ていないとき
エラーマーク0.81〜0.880.47〜0.53
完了のチェックマーク0.89〜1.000.50前後

「出ているとき」と「出ていないとき」の差がはっきり開いたので、判定の基準(0.70〜0.80)で迷わず切り分けられます。正しい大きさで探せば、一致度はちゃんと高く出るということです。

やってはいけない対策:判定の基準を下げる

見つからないときについやりたくなるのが、判定の基準(pyautoguiの confidence など)を下げることです。

これはおすすめしません。基準を下げると、似ているだけの別のものまで「見つかった」と判断するようになります。上の表でも、出ていないときでも0.5前後の一致度は出ています。自動入力でこれが起きると、エラーを見逃したまま入力を続けてしまうので、見つからないより危険です。

まとめ

画像認識が他のPCで失敗するときは、まず表示倍率を疑ってみてください。

  • 原因:Windowsの表示倍率によって、アイコンの大きさがPCごとに数pxずつ違う
  • 調べ方:両方のPCでスクショを撮り、同じアイコンの大きさをpxで比べる
  • 対策:倍率を正しく認識させたうえで、大きさが違っても見つけられる探し方にする
  • 注意:判定の基準を下げてごまかすと、エラーの見逃しにつながる

自分のPCだけでテストしていると、この問題には気づけません。画像認識を使うツールを他の人に配るときは、表示倍率の違うPCで一度動かしてみることをおすすめします。

ツールについて

今回の対策を入れた自動入力ツールの紹介は、こちらの記事にまとめています。

【スクリプト機能OFFでもOK】SAPへの工数入力をExcelから自動化するツールを作りました
SAPへの工数入力・実績登録を、Excelのボタン1つで自動化するツールを紹介します。 会社でSAPのスクリプト機能が使えなくても動き、エラーの検知や結果の記録も自動です。 デモ動画と導入の流れも掲載しています。

ツール全体の作り方(画面を確認しながら入力する仕組み、設定をExcelで管理する方法、止まらない・暴走しないための工夫など)は、noteで解説しています。

自分で作る時間がない方には、御社の画面に合わせた設定代行もココナラで受け付けています。画面のスクショを送っていただくだけで、無料で見積もりします。

この記事を書いた人:かく助
製造業の現場責任者(10年以上)(仕上げ特級技能士)を務める「現場系エンジニア」。
現場の課題や仕様を熟知した上で、AI(Claude等)をコーディングの補助ツールとして使いこなし、VBA/Pythonによる業務自動化や自社用Webシステムを自力で構築・運用中。
「現場のリアルな課題×テクノロジー」をテーマに、実践的な自動化ノウハウを発信しています。

実績・ポートフォリオ
kakusukeをフォローする

コメント