回答編集履歴
5
解説!
answer
CHANGED
@@ -1,8 +1,29 @@
|
|
1
1
|
やりたいことがあまり初心者向けとは思えないのですが、
|
2
2
|
`multiprocessing`や`ProcessPoolExecutor`/`asyncio`でググるとサンプルソースがヒットするかもです。
|
3
3
|
|
4
|
+
■原因
|
5
|
+
`root.mainloop()` # ←の行でGUI入力待ちのブロッキングをしているからです。
|
6
|
+
そのため、`while`ループ内の`ret, frame = cap.read()`の行が実行されません。
|
7
|
+
参考:[Use TkInter without mainloop](https://gordonlesti.com/use-tkinter-without-mainloop/)
|
8
|
+
|
9
|
+
■対策
|
10
|
+
| | |
|
11
|
+
|:--|:--:|
|
12
|
+
|動画の処理を行う部分|cap.read()|
|
13
|
+
|tkinter表示部|root.mainloop()|
|
14
|
+
|
15
|
+
を分割してマルチスレッド/マルチプロセスで並列化すれば解消されるかと。
|
16
|
+
ここまでが、動画検知を行いながら+αの処理も行う方法
|
17
|
+
|
18
|
+
> Tkinterにて警告を出したい
|
19
|
+
|
20
|
+
そして、質問文のこの要件があるので、動画検知側から`tkinter`側に通知する必要があります。
|
21
|
+
そのために`multiprocessing#Queue`を使った、`producer-consumer`デザインパターンを使用しました。
|
22
|
+
|
23
|
+
---
|
24
|
+
|
4
25
|
あまり動作確認していませんが、サンプルコードを置いておきます。ご参考まで。
|
5
|
-
個人的には、プロセスを分けた方が良いのではとも。
|
26
|
+
個人的には、`python`のプロセスを分けた方が良いのではとも。
|
6
27
|
|
7
28
|
```Python
|
8
29
|
# -*- coding: utf-8 -*-
|
4
typoと初心者さんみたいなので、デザインパターン名を追加。
answer
CHANGED
@@ -102,10 +102,11 @@
|
|
102
102
|
if not file_path: # isEmpty
|
103
103
|
return
|
104
104
|
print(file_path)
|
105
|
+
※ producer-consumer デザインパターン
|
105
106
|
queue = Queue()
|
106
107
|
producer = Process(target=produce, args=(queue, file_path))
|
107
|
-
|
108
|
+
consumer = Process(target=consume, args=(queue,))
|
108
|
-
|
109
|
+
consumer.start() # ※ コンシューマから先に起動
|
109
110
|
producer.start()
|
110
111
|
producer.join() # ※ プロデューサーはjoinで終了待ちを行う。
|
111
112
|
|
3
ざっくばらんは方言みたいなので言葉を変更
answer
CHANGED
File without changes
|
2
ざっくばらんは方言みたいなので言葉を変更
answer
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
やりたいことがあまり初心者向けとは思えないのですが、
|
2
2
|
`multiprocessing`や`ProcessPoolExecutor`/`asyncio`でググるとサンプルソースがヒットするかもです。
|
3
3
|
|
4
|
-
|
4
|
+
あまり動作確認していませんが、サンプルコードを置いておきます。ご参考まで。
|
5
5
|
個人的には、プロセスを分けた方が良いのではとも。
|
6
6
|
|
7
7
|
```Python
|
1
追記
answer
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
やりたいことがあまり初心者向けとは思えないのですが、
|
2
|
-
multiprocessing
|
2
|
+
`multiprocessing`や`ProcessPoolExecutor`/`asyncio`でググるとサンプルソースがヒットするかもです。
|
3
3
|
|
4
4
|
とりあえず、ざっくばらんに書いたサンプルコードを置いておきます。ご参考まで。
|
5
5
|
個人的には、プロセスを分けた方が良いのではとも。
|
@@ -24,7 +24,7 @@
|
|
24
24
|
|
25
25
|
while True:
|
26
26
|
ret, frame = capture.read()
|
27
|
-
if not ret: # readの戻り値は絶対に確認すること!!!!!!!!!!!
|
27
|
+
if not ret: # ※readの戻り値は絶対に確認すること!!!!!!!!!!!
|
28
28
|
break
|
29
29
|
edframe = frame
|
30
30
|
cv2.putText(edframe, 'test', (0, 50),
|
@@ -51,6 +51,7 @@
|
|
51
51
|
else:
|
52
52
|
pass
|
53
53
|
print(wide) # , end=" ")
|
54
|
+
# ※ queueに追加 表示したい文字列なり数字なりEOF以外ならなんでも良い。
|
54
55
|
queue.put("attention!!!!")
|
55
56
|
else:
|
56
57
|
pass
|
@@ -62,23 +63,23 @@
|
|
62
63
|
k = cv2.waitKey(1)
|
63
64
|
if k == 27:
|
64
65
|
break
|
65
|
-
# EOF
|
66
|
+
# ※ EOF
|
66
67
|
queue.put(None)
|
67
68
|
print("produce END")
|
68
69
|
cv2.destroyAllWindows()
|
69
70
|
|
70
71
|
|
71
72
|
def on_message(queue:Queue):
|
72
|
-
root.withdraw() # 非表示
|
73
|
+
root.withdraw() # ※ 非表示
|
73
|
-
item = queue.get(True) # タイムアウトを指定するかはどうかは仕様によるかと。
|
74
|
+
item = queue.get(True) # ※ タイムアウトを指定するかはどうかは仕様によるかと。
|
74
75
|
if not item: # EOF
|
75
|
-
# Windowの終了
|
76
|
+
# ※ Windowの終了
|
76
77
|
print("on_message EOF")
|
77
78
|
root.quit()
|
78
79
|
return
|
79
80
|
var_message.set(item)
|
80
|
-
root.deiconify() # 表示
|
81
|
+
root.deiconify() # ※ 表示
|
81
|
-
# デッドライン間隔、Queueに要素を追加するのが早いのならその点も考慮する事
|
82
|
+
# ※ デッドライン間隔、Queueに要素を追加するのが早いのならその点も考慮する事
|
82
83
|
root.after(1000, on_message, queue)
|
83
84
|
|
84
85
|
|
@@ -95,7 +96,7 @@
|
|
95
96
|
|
96
97
|
|
97
98
|
def main() -> None:
|
98
|
-
# ↓ファイル選択ダイアログでTopLevelウィンドウが表示されるので。
|
99
|
+
# ※ ↓ファイル選択ダイアログでTopLevelウィンドウが表示されるので。
|
99
100
|
root.withdraw()
|
100
101
|
file_path = filedialog.askopenfilename(parent=root)
|
101
102
|
if not file_path: # isEmpty
|
@@ -104,9 +105,9 @@
|
|
104
105
|
queue = Queue()
|
105
106
|
producer = Process(target=produce, args=(queue, file_path))
|
106
107
|
customer = Process(target=consume, args=(queue,))
|
107
|
-
customer.start() # カスタマーから先に起動
|
108
|
+
customer.start() # ※ カスタマーから先に起動
|
108
109
|
producer.start()
|
109
|
-
producer.join() # プロデューサーはjoinで終了待ちを行う。
|
110
|
+
producer.join() # ※ プロデューサーはjoinで終了待ちを行う。
|
110
111
|
|
111
112
|
|
112
113
|
if __name__ == "__main__":
|