回答編集履歴

1

コードを追加。

2018/11/13 14:47

投稿

tachikoma
tachikoma

スコア3601

test CHANGED
@@ -1,5 +1,169 @@
1
- 検出処理を別スレッドに飛ばしたりするなどの工夫が必要ですね。
1
+ 検出処理を別スレッドに飛ばしたりするなどの工夫が必要ですね。難しいですが、検出器側の大まかな構造だけを実装してみました(検出ロジックは未実装)。
2
2
 
3
3
 
4
4
 
5
- 検出用のクラスを作って非同期処理(スレッド等)の検出メソッド作っておいて、検出処理が終わっているかをメンルーで確認。もし終わっていれば矩形を描画とか。もちろん検出結果数フーム前ものるので、現在の物体の位置とはズレが発生しますよん
5
+ 非同期処理には`threading`いて、タスクのパイプには`queue`を使っていす。Pythonのqueueッド同期利用できるのでうまく使うと便利です。検出処理自は`run`中に実装しますが、タスクの開始はdetectメソッドを通して行い、getResultで結果を回収することを意図した構造です
6
+
7
+
8
+
9
+ 一番したに試しにこのクラスを使ったコードがあります。動作を追いかけられますかね。
10
+
11
+
12
+
13
+ ```Python
14
+
15
+ import threading
16
+
17
+ import queue
18
+
19
+ import time
20
+
21
+ import numpy
22
+
23
+
24
+
25
+
26
+
27
+ class Detector(threading.Thread):
28
+
29
+ """非同期の物体検出クラス"""
30
+
31
+
32
+
33
+ def __init__(self):
34
+
35
+ threading.Thread.__init__(self)
36
+
37
+ self._lock = threading.Lock()
38
+
39
+
40
+
41
+ # タスク・結果のパイプ用
42
+
43
+ self._task_queue = queue.Queue(maxsize=1)
44
+
45
+ self._result_queue = queue.Queue(maxsize=1)
46
+
47
+
48
+
49
+ # threadを開始させておく
50
+
51
+ self.busy = False
52
+
53
+ self.start()
54
+
55
+
56
+
57
+ def join(self):
58
+
59
+ """終了処理"""
60
+
61
+ self._task_queue.put(None)
62
+
63
+ super(Detector, self).join()
64
+
65
+
66
+
67
+ def run(self):
68
+
69
+ """検出処理をするメイン部分"""
70
+
71
+ while True:
72
+
73
+ with self._lock:
74
+
75
+ task = self._task_queue.get()
76
+
77
+ if task is None:
78
+
79
+ # スレッドの終了条件
80
+
81
+ break
82
+
83
+ self.busy = True # 追加の処理を受け付けないようにする
84
+
85
+ print("get task", task, time.ctime())
86
+
87
+
88
+
89
+ # 重い処理の部分
90
+
91
+ time.sleep(3)
92
+
93
+
94
+
95
+ # 結果をqueueに送り込む
96
+
97
+ with self._lock:
98
+
99
+ if self._result_queue.full():
100
+
101
+ # 回収されていない結果は捨てる
102
+
103
+ self._result_queue.get()
104
+
105
+ self._result_queue.put("done " + task)
106
+
107
+ self.busy = False
108
+
109
+ print("finishd task", task, time.ctime())
110
+
111
+ print("thread finished", time.ctime())
112
+
113
+
114
+
115
+ def detect(self, img: numpy.array) -> bool:
116
+
117
+ """非同期で検出処理を受け付ける"""
118
+
119
+ if not self.busy:
120
+
121
+ self._task_queue.put(img)
122
+
123
+ return True
124
+
125
+ return False
126
+
127
+
128
+
129
+ def getResult(self) -> (bool, list):
130
+
131
+ """結果を回収する"""
132
+
133
+ if not self._result_queue.empty():
134
+
135
+ return True, self._result_queue.get()
136
+
137
+ return False, []
138
+
139
+
140
+
141
+
142
+
143
+ if __name__ == "__main__":
144
+
145
+ det = Detector()
146
+
147
+ print(det.detect("hoge")) # 検出処理を依頼
148
+
149
+ time.sleep(1)
150
+
151
+ print(det.detect("foo")) # 続けざまに処理を依頼すると拒否される
152
+
153
+ time.sleep(3) # 終了するまで待つ
154
+
155
+ done, result = det.getResult() # 結果の回収を試みる
156
+
157
+ if done:
158
+
159
+ # もしタスクが完了していれば
160
+
161
+ print("result ", result)
162
+
163
+ # 前のタスクが完了していれば次の処理を受け付ける
164
+
165
+ print(det.detect("bar"))
166
+
167
+ det.join()
168
+
169
+ ```