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

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

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

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

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

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

Q&A

0回答

294閲覧

tkinter ウィンドウ mainloopを使用しても一瞬で消える

mckie

総合スコア2

OpenCV

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

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

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

0グッド

0クリップ

投稿2023/02/23 04:25

実現したいこと

openCVを使って、カメラ画像を取得し、その画像から色検出、物体検出をするプログラムを
作っています。
snapshotを撮影すると、webカメラのウィンドウは消えてsnapnumに1が入り、色検出、物体検出して、画像と"OK","NG"判断のウィンドウを表示させたいです。
一回目のスナップショットのウィンドウは正しく表示され、正しく終了できますが
二回目のウィンドウ(色検出、物体検出後のOK、NG表示)が一瞬で消えてしまいます。
mainloopは使っていますが、表示できません。
調べてみましたが、わかりませんでした。どなたかわかる方がいらしたらご教授お願いします。

_tkinter.TclError: image "pyimage27" doesn't exist invalid command name "2414419787584disp_image" while executing "2414419787584disp_image" ("after" script)

該当のソースコード

python

1import tkinter as tk 2from tkinter import filedialog 3from PIL import Image, ImageTk, ImageOps # 画像データ用 4import matplotlib.pyplot as plt 5from matplotlib.patches import Polygon 6import numpy as np 7from tkinter import font 8import time 9 10import cv2 11 12class Application(tk.Frame): 13 def __init__(self, master = None): 14 super().__init__(master) 15 self.pack() 16 17 fonts = ("", 14) 18 19 20 self.master.title("OpenCVの動画表示") 21 #self.master.attributes("-zoomed", "1") 22 #self.master.attributes("-zoomed", "1") # ウィンドウタイトル 23 self.master.geometry("1000x500") # ウィンドウサイズ(幅x高さ) 24 #self.master.attributes("-fullscreen", True) 25 26 #self.master.protocol("WM_DELETE_WINDOW", self.click_close) 27 frame1 = tk.Frame(self.master, width=400,height=800) 28 frame1.pack(expand = True,fill=tk.BOTH) 29 30 # frame2 = tk.Frame(self.master, width=400,height=5,bg="beige") 31 # frame2.pack(fill=tk.BOTH,) 32 33 self.button = tk.Button(frame1,text="Snapshot",width=20, height=5, font=fonts,bg="beige" ,command=self.snapshot) 34 self.button.pack(side=tk.BOTTOM,fill=tk.X) 35 36===========================37 38 def disp_image(self): 39 '''画像をCanvasに表示する''' 40 41 # フレーム画像の取得 42 ret, self.frame22 = self.capture.read() 43 44 # BGR→RGB変換 45 cv_image = cv2.cvtColor(self.frame22, cv2.COLOR_BGR2RGB) 46 # NumPyのndarrayからPillowのImageへ変換 47 pil_image = Image.fromarray(cv_image) 48 49 # キャンバスのサイズを取得 50 canvas_width = self.canvas.winfo_width() 51 canvas_height = self.canvas.winfo_height() 52 53 # 画像のアスペクト比(縦横比)を崩さずに指定したサイズ(キャンバスのサイズ)全体に画像をリサイズする 54 pil_image = ImageOps.pad(pil_image, (canvas_width, canvas_height)) 55 56 # PIL.ImageからPhotoImageへ変換する 57 self.photo_image = ImageTk.PhotoImage(image=pil_image) 58 59 # 画像の描画 60 self.canvas.create_image( 61 canvas_width / 2, # 画像表示位置(Canvasの中心) 62 canvas_height / 2, 63 image=self.photo_image # 表示画像データ 64 ) 65 66 #self.button = tk.Button(self.master, text="Snapshot", command=self.pushed_button) 67 # self.button.grid(row=1, column=0, sticky="", pady=10) 68 69 # disp_image()を10msec後に実行する 70 self.disp_id = self.after(10, self.disp_image) 71 72 73 def snapshot(self): 74 filename = "C:/Users/Pictures/mm.png" 75 self.snapnum = 1 76 77 cv2.imwrite( filename,self.frame22) 78 print(filename) 79 self.master.destroy() 80 self.capture.release() 81 #time.sleep(5) 82 #match_suc:match_suc 83 cv2.destroyAllWindows() 84 time.sleep(5) 85 86 87 88 89 90if __name__ == "__main__": 91 root = tk.Tk() 92 app = Application(master = root) 93 app.mainloop() 94 if app.snapnum == 1: 95 96 img = cv2.imread("C:/Users/Pictures/mm.png") # 画像を読み込む。 97 98 # 色基準で2値化する。 99 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # HSV 色空間に変換 100 101 red = cv2.inRange(hsv, np.array([145, 70, 0]), np.array([180, 255, 255])) 102 yellow = cv2.inRange(hsv, np.array([10, 80, 0]), np.array([50, 255, 255])) 103 green = cv2.inRange(hsv, np.array([30, 190, 0]), np.array([90, 255, 255])) 104 blue = cv2.inRange(hsv, np.array([90, 70, 90]), np.array([210, 255, 255])) 105 #white = cv2.inRange(hsv, np.array([108, 21, 0]), np.array([255, 70, 255])) 106 107 # 白だけゴミがあるので、収縮演算 108 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) 109 #white = cv2.erode(white, kernel) 110 111 112 bin_imgs = {'red': red, 'yellow': yellow, 'green': green, 113 'blue': blue, } 114 115 # # 2値化結果を可視化する。 116 # #################################################### 117 # fig, axes_list = plt.subplots(2, 3, figsize=(10, 6)) 118 # axes_list[1, 2].remove() 119 # for ax, (label, bin_img) in zip(axes_list.ravel(), bin_imgs.items()): 120 # ax.axis('off') 121 # ax.set_title(label) 122 # ax.imshow(bin_img, cmap=plt.cm.gray) 123 # #plt.show() 124 125 126 127 128 fig, ax = plt.subplots(figsize=(8, 5)) 129 ax.axis('off') 130 ax.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) 131 count1 = {'red':0,'yellow':0,'green':0,'blue':0} 132 # 輪郭検出し、数を求める。 133 ############################################## 134 for label, bin_img in bin_imgs.items(): 135 contours,hierarchy = cv2.findContours( 136 bin_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 137 # 輪郭を構成する頂点数で誤検出を除く。 138 contours = list(filter(lambda cnt: len(cnt) > 30, contours)) 139 count = len(contours) 140 count1[label] = count 141 print('color: {}, conunt: {}'.format(label, count)) 142 143 # 描画する。 144 for cnt in contours: 145 cnt = np.squeeze(cnt, axis=1) # (N, 1, 2) -> (N, 2) 146 ax.add_patch(Polygon(cnt, fill=None, lw=2., color=label)) 147 plt.savefig("C:/Users/T125/Pictures/L53Hafter.png") 148 #plt.show() 149 150 window = tk.Tk() 151 152 fonts = ("", 14) 153 154 155 window.title("処理結果") 156 #self.master.attributes("-zoomed", "1") 157 #self.master.attributes("-zoomed", "1") # ウィンドウタイトル 158 window.geometry("1200x700") # ウィンドウサイズ(幅x高さ) 159 #self.master.attributes("-fullscreen", True) 160 161 162 163 frame1 = tk.Frame(window,bg="beige",width=1200,height=500) 164 frame1.pack(expand = True,fill=tk.BOTH) 165 166 # frame2 = tk.Frame(self.master, width=400,height=5,bg="beige") 167 # frame2.pack(fill=tk.BOTH,) 168 169 170 171 # Canvasの作成 172 canvas = tk.Canvas(frame1,bg="beige",width=1200,height=500) 173 # Canvasにマウスイベント(左ボタンクリック)の追加 174 #canvas.bind('<Button-1>', self.canvas_click) 175 # Canvasを配置 176 canvas.pack(expand = True, fill = tk.BOTH) 177#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 178 # フレーム画像の取得 179 img = ImageTk.PhotoImage(file = "C:/Users/T125/Pictures/L53Hafter.png") 180 w = img.width # 横幅を取得 181 h = img.height # 縦幅を取得 182 183 #img = img.resize(( int(w * (800/w)), int(h * (800/w)) )) 184 185 186 # PIL.ImageからPhotoImageへ変換する 187 #photo_Image = ImageTk.PhotoImage(img) 188 189 190 # キャンバスのサイズを取得 191 canvas_width = canvas.winfo_width() 192 canvas_height = canvas.winfo_height() 193 194 195 196 # 画像のアスペクト比(縦横比)を崩さずに指定したサイズ(キャンバスのサイズ)全体に画像をリサイズする 197 #pil_image = ImageOps.pad(img, (canvas_width, canvas_height)) 198 199 200 201 canvas.create_image(70, 0, image=img, anchor=tk.NW) 202 canvas.create_image( 203 600, # 画像表示位置(Canvasの中心) 204 250, 205 image=img, 206 anchor = tk.CENTER 207 # 表示画像データ 208 ) 209 210 211 212 # # 画面作成 213 # version = tk.Tcl().eval('info patchlevel') 214 # window = tk.Tk() 215 # window.geometry("1000x800") 216 # window.title("画像表示:" + version) 217 218 219 # # キャンバス作成 220 # canvas = tk.Canvas(window, bg="#deb887", height=600, width=1000) 221 # # キャンバス表示 222 # canvas.place(x=0, y=0) 223 224 # # イメージ作成 225 # img = tk.PhotoImage(file="C:/Users/Pictures/mm_after.png", width=1000, height=600) 226 # # キャンバスにイメージを表示 227 # canvas.create_image(70, 0, image=img, anchor=tk.NW) 228 RedAnswer = 5 229 BlueAnswer = 5 230 YellowAnswer = 5 231 GreenAnswer = 5 232 233 if (count1['red']) >= RedAnswer and \ 234 (count1['yellow']) >= YellowAnswer and\ 235 (count1['green']) >= GreenAnswer and \ 236 (count1['blue']) >= BlueAnswer : 237 font1 = font.Font(family='Helvetica', size=110, weight='bold') 238 label2 = tk.Label(window, text="OK",font=font1,fg="green") #文字ラベル設定 239 label2.pack(side = "bottom") 240 canvas.create_image( 241 600, # 画像表示位置(Canvasの中心) 242 250, 243 image=img, 244 anchor = tk.CENTER 245 # 表示画像データ 246 ) 247 248 else: 249 rednotenough = RedAnswer-(count1['red']) 250 yellowNotEnough = YellowAnswer-(count1['yellow']) 251 greenNotEnough = GreenAnswer-(count1['green']) 252 blueNotEnough = BlueAnswer-(count1['blue']) 253 254 #0以下は0にする 255 rednotenough = max(0,rednotenough) 256 yellowNotEnough = max(0,yellowNotEnough) 257 greenNotEnough = max(0,greenNotEnough) 258 blueNotEnough = max(0,blueNotEnough) 259 260 font0 = font.Font(family='Helvetica', size=20, weight='bold') 261 text0 = "赤色が"+ str(rednotenough) + "個\n"\ 262 "黄色が"+ str(yellowNotEnough) + "個\n"\ 263 "緑が"+ str(greenNotEnough) + "個\n"\ 264 "青が"+ str(blueNotEnough) + "個\n"\ 265 "足りません" 266 267 268 269 label0 = tk.Label(window, text=text0,font=font0,fg="red") 270 label0 .place(relx=0.85,rely=0.75) 271 272 273 font1 = font.Font(family='Helvetica', size=110, weight='bold') 274 label1 = tk.Label(window, text="NG",font=font1,fg="red") #文字ラベル設定 275 label1.pack(side = "bottom") 276 277 278 279 280window.mainloop()

試したこと

最後のmainloop()をifの中に入れてみたり、外してみたりしましたが同じエラーでした。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

mckie

2023/02/27 02:42

コメントありがとうございます。 マルチポストについて理解しておらず、申し訳ございません。 この質問を削除させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

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

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

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

ただいまの回答率
85.44%

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

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

質問する

関連した質問