teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

マルチスレッド化したが、エラーが発生した。

2020/03/20 09:14

投稿

falcon_titan
falcon_titan

スコア14

title CHANGED
File without changes
body CHANGED
@@ -93,4 +93,116 @@
93
93
 
94
94
  #関数を実行
95
95
  save_frame_camera_cycle(0, 'camera_data', 'camera_capture_cycle', 15)
96
- ```
96
+ ```
97
+
98
+ アドバイスを受け、マルチスレッドで実行するようにプログラムを変更しました。
99
+ ```python
100
+ import cv2
101
+ import os
102
+ import datetime
103
+ from sklearn import svm
104
+ import pickle
105
+ from PIL import Image
106
+ import numpy as np
107
+ import tkinter as tk
108
+ from tkinter import font
109
+ import threading
110
+
111
+ # ウィンドウ表示の定義
112
+ def print_text():
113
+ root = tk.Tk()#ウィンドウを作る
114
+
115
+ root.title("ティッシュ認識システム") #タイトルの変更
116
+ root.geometry("300x100") #サイズの指定
117
+
118
+ font1 = font.Font(family='Helvetica', size=20, weight='bold') #フォントを設定
119
+
120
+ text = tk.StringVar()#textをStringVar関数にする
121
+
122
+ if result ==1:
123
+ text.set("これはティッシュです")
124
+
125
+ else:
126
+ text.set("これは床です")
127
+
128
+ label = tk.Label(textvariable = text, font = font1) #ラベルを追加
129
+ label.pack()
130
+
131
+ root.mainloop() #実行して表示
132
+ print("a")
133
+
134
+ # 画像認識の学習データを読み込む
135
+ filename = 'tissue_model_1.sav'
136
+ clf = pickle.load(open(filename, 'rb'))
137
+
138
+ # 変数の定義
139
+ size = 16
140
+
141
+ # 認識システムを関数で定義
142
+ def save_frame_camera_cycle(device_num, dir_path, basename, cycle, ext='JPG', delay=1, window_name='frame'):
143
+ cap = cv2.VideoCapture(1)# カメラは1(usbカメラ)を用いる
144
+
145
+ if not cap.isOpened():#カメラが見つからなかった場合
146
+ return#中止する 
147
+
148
+ os.makedirs(dir_path, exist_ok=True)
149
+ base_path = os.path.join(dir_path, basename)
150
+
151
+ n = 0
152
+ while True: #Trueでずっとループさせる
153
+ ret, frame = cap.read()
154
+ cv2.imshow(window_name, frame)
155
+ if cv2.waitKey(delay) & 0xFF == ord('q'):# qが押されたら終了する
156
+ break
157
+ if n == cycle:#cycleとnが同じ数になったら写真を保存する
158
+
159
+ cv2.imwrite('{}_{}.{}'.format(base_path, datetime.datetime.now().strftime('%Y%m%d%H%M%S%f'), ext), frame)#画像を保存
160
+ cv2.imwrite('picture.' + ext, frame)#画像を1時的に保存
161
+ img = Image.open('picture.JPG')#画像を開く
162
+ img = img.resize((size,size))#リサイズ
163
+ ary = np.array(img).reshape(-1,)#一次元の配列にする
164
+ global result
165
+ result = clf.predict(ary)#認識
166
+ print(result)#結果を表示
167
+
168
+ print_text(result = result)
169
+
170
+ n = 0
171
+ n += 1
172
+
173
+ cv2.destroyWindow(window_name)
174
+
175
+ #関数を実行
176
+ t1 = threading.Thread(target = save_frame_camera_cycle, args = (0, 'camera_data', 'camera_capture_cycle', 15))
177
+ t2 = threading.Thread(target = print_text,)
178
+ t2.start()
179
+ t1.start()
180
+ ```
181
+ しかし、
182
+ ```python
183
+ Exception in thread Thread-12:
184
+ Traceback (most recent call last):
185
+ File "C:\Users\ユーザー名\Anaconda3\lib\threading.py", line 916, in _bootstrap_inner
186
+ self.run()
187
+ File "C:\Users\ユーザー名\Anaconda3\lib\threading.py", line 864, in run
188
+ self._target(*self._args, **self._kwargs)
189
+ File "<ipython-input-8-c90b360b3e2d>", line 19, in print_text
190
+ font1 = font.Font(family='Helvetica', size=20, weight='bold') #フォントを設定
191
+ File "C:\Users\ユーザー名\Anaconda3\lib\tkinter\font.py", line 93, in __init__
192
+ tk.call("font", "create", self.name, *font)
193
+ RuntimeError: main thread is not in main loop
194
+
195
+ C:\Users\ユーザー名\Anaconda3\lib\site-packages\sklearn\utils\validation.py:395: DeprecationWarning: Passing 1d arrays as data is deprecated in 0.17 and will raise ValueError in 0.19. Reshape your data either using X.reshape(-1, 1) if your data has a single feature or X.reshape(1, -1) if it contains a single sample.
196
+ DeprecationWarning)
197
+ Exception in thread Thread-11:
198
+ Traceback (most recent call last):
199
+ File "C:\Users\ユーザー名\Anaconda3\lib\threading.py", line 916, in _bootstrap_inner
200
+ self.run()
201
+ File "C:\Users\ユーザー名\Anaconda3\lib\threading.py", line 864, in run
202
+ self._target(*self._args, **self._kwargs)
203
+ File "<ipython-input-8-c90b360b3e2d>", line 69, in save_frame_camera_cycle
204
+ print_text(result = result)
205
+ TypeError: print_text() got an unexpected keyword argument 'result'
206
+ ```
207
+ と、結果となるresultをTkinterウィンドウの関数が受け取ることができませんでした。
208
+ 変数を共有するには、どうしたらよいでしょうか?