実現したいこと
・麻雀の牌譜検定の為のツール作成
・画面キャプチャーで牌をスキャン
・用意した牌の画像と照らし合わせ、重複した箇所に赤い四角で囲む
・その後に、牌の画像の名前を出力(5m等)
・テキストとして5m6m2p3p7s等になる
・何か解決に向けてアイディアがありましたらお教え願いたいです。
前提
プログラミング初心者です。
Pycharmを用いてpython3で作成しています。
発生している問題・エラーメッセージ
重複した画像に対して、テキストとして表示されない。
例:5m5m6m7m8m4p5p5s4s6s7s8s9sの牌を読み取らせているのに、出力結果は5m6m7m8m4p5p5s4s6s7s8s9sとなる。
該当のソースコード
python3
1from typing import List 2 3import pyautogui 4import cv2 5import numpy as np 6 7# 画面キャプチャーの実行 8image = pyautogui.screenshot() 9 10# 画像の保存 11image.save('screenshot.png') 12 13# 入力画像の読み込み 14img = cv2.imread('screenshot.png') 15 16# テンプレート画像のファイルパスをリストで用意 17template_file_paths = ['5m.png', '6m.png', '7m.png', '8m.png', '4p.png', '5p.png', '5s.png', '4s.png', '5s.png', '6s.png', '7s.png', '8s.png', '9s.png'] 18 19# 各テンプレート画像について処理 20detected_templates: list[str] = [] 21for template_file_path in template_file_paths: 22 # テンプレート画像の読み込み 23 template = cv2.imread(template_file_path) 24 25 # テンプレートマッチングの実行 26 result = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED) 27 28 # 最大のマッチング位置を検出 29 threshold = 0.8 # 類似度の閾値 30 locations = np.where(result >= threshold) 31 locations = list(zip(*locations[::-1])) 32 33 # マッチング位置を描画 34 for loc in locations: 35 h, w = template.shape[:2] 36 top_left = loc 37 bottom_right = (top_left[0] + w, top_left[1] + h) 38 cv2.rectangle(img, top_left, bottom_right, (0, 0, 255), 2) 39 40 # マッチングした画像のテンプレート画像のファイル名を取得 41 template_file_name = template_file_path.split('/')[-1] # ファイル名のみ抽出 42 43 # 新しく検出した画像に対してのみファイル名を出力 44 if template_file_name in detected_templates: 45 continue # 既に検出したものはカウントしない 46 else: 47 detected_templates.append(template_file_name) 48 count = len(locations) 49 if count > 0: 50 print((template_file_name[:-4]) * min(count, 1), end='') 51 52# 結果を表示 53cv2.imshow('result', img) 54cv2.waitKey(0) 55 56# ウィンドウを閉じる 57cv2.destroyAllWindows()
試したこと
検知されるごとに、テキストを出力する。(重複していない牌に関しても重複して表示され失敗)
ChatGPTに見てもらう
4時間粘ったものの進展無し
考察
ファイル名で指定している為ややこしいことになっている(?)
print((template_file_name[:-4]) * min(count, 1), end='')
min(count, 1) としているので、同じ牌がある場合には最初の牌以外は全て無視されてしまうことになります。
コメント本当にありがとうございます。
printの後は色々試してみたんですが、重複して返してしまうんですよね。
回答くださった方の
print(''.join([item[1] for item in sorted(detected_templates)]))
ですと、識別したい牌が
5m5m6m7m8m4p5p4s5s6s7s8s9sの場合、
5m5m5m5m5m5m5m5m5m5m5m5m5m5m5m5m5m5m6m6m6m6m6m6m6m6m6m6m6m7m7m7m7m7m7m7m7m7m8m8m8m8m8m8m8m8m8m8m8m4p4p4p4p4p5p4s4s4s4s4s5s5s5s5s5s6s6s6s6s6s7s7s7s7s7s8s8s8s8s8s9s9s9s9s9s9s9sと出力されてしまいます。
1つしかない画像であっても、重複して検知されてしまっているのでしょうか。

回答1件
あなたの回答
tips
プレビュー