質問編集履歴

2

修正

2020/10/23 02:37

投稿

nonnon615
nonnon615

スコア19

test CHANGED
File without changes
test CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  何個も特徴点を追加できるのですが,すべて同じ色になっていします.
4
4
 
5
- その色を変更できますか?
5
+ その色を変更できますか?←解決しました‼
6
-
7
-
8
-
6
+
7
+
8
+
9
- また,クリックして加えた特徴点を含む動画を保存し,座標を示すことは可能でしょうか?
9
+ また,クリックして加えた特徴点を含む動画を保存し,座標を示すことは可能でしょうか?csvに座標を,mp4に動画の保存をしたいです.
10
10
 
11
11
 
12
12
 

1

コードがうまく示せていなかった

2020/10/23 02:36

投稿

nonnon615
nonnon615

スコア19

test CHANGED
File without changes
test CHANGED
@@ -10,408 +10,412 @@
10
10
 
11
11
 
12
12
 
13
- 作成したコードを示します.```ここに言語を入力
13
+ 作成したコードを示します.
14
+
15
+
16
+
17
+ ```import cv2
18
+
19
+ import numpy as np
20
+
21
+
22
+
23
+ # Esc キー_終了
24
+
25
+ ESC_KEY = 0x1b
26
+
27
+ # s キー_一時停止
28
+
29
+ S_KEY = 0x73
30
+
31
+ # r キー_リスタート
32
+
33
+ R_KEY = 0x72
34
+
35
+ # 特徴点の最大数
36
+
37
+ MAX_FEATURE_NUM = 500
38
+
39
+ # 反復アルゴリズムの終了条件
40
+
41
+ CRITERIA = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)
42
+
43
+ # インターバル (1000 / フレームレート)
44
+
45
+ INTERVAL = 30
46
+
47
+ # ビデオデータ
48
+
49
+ VIDEO_DATA = 'movie.mp4'
50
+
51
+
52
+
53
+ class Motion:
54
+
55
+ # コンストラクタ
56
+
57
+ def __init__(self):
58
+
59
+ # 表示ウィンドウ
60
+
61
+ cv2.namedWindow("motion")
62
+
63
+ # マウスイベントのコールバック登録
64
+
65
+ cv2.setMouseCallback("motion", self.onMouse)
66
+
67
+ # 映像
68
+
69
+ self.video = cv2.VideoCapture(VIDEO_DATA)
70
+
71
+ # インターバル
72
+
73
+ self.interval = INTERVAL
74
+
75
+ # 現在のフレーム(カラー)
76
+
77
+ self.frame = None
78
+
79
+ # 現在のフレーム(グレー)
80
+
81
+ self.gray_next = None
82
+
83
+ # 前回のフレーム(グレー)
84
+
85
+ self.gray_prev = None
86
+
87
+ # 特徴点
88
+
89
+ self.features = None
90
+
91
+ # 特徴点のステータス
92
+
93
+ self.status = None
94
+
95
+
96
+
97
+ # メインループ
98
+
99
+ def run(self):
100
+
101
+
102
+
103
+ # 最初のフレームの処理
104
+
105
+ end_flag, self.frame = self.video.read()
106
+
107
+ self.gray_prev = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)
108
+
109
+
110
+
111
+ while end_flag:
112
+
113
+ # グレースケールに変換
114
+
115
+ self.gray_next = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)
116
+
117
+
118
+
119
+ # 特徴点が登録されている場合にOpticalFlowを計算する
120
+
121
+ if self.features is not None:
122
+
123
+ # オプティカルフローの計算
124
+
125
+ features_prev = self.features
126
+
127
+ self.features, self.status, err = cv2.calcOpticalFlowPyrLK( \
128
+
129
+ self.gray_prev, \
130
+
131
+ self.gray_next, \
132
+
133
+ features_prev, \
134
+
135
+ None, \
136
+
137
+ winSize = (10, 10), \
138
+
139
+ maxLevel = 3, \
140
+
141
+ criteria = CRITERIA, \
142
+
143
+ flags = 0)
144
+
145
+
146
+
147
+ # 有効な特徴点のみ残す
148
+
149
+ self.refreshFeatures()
150
+
151
+
152
+
153
+ # フレームに有効な特徴点を描画
154
+
155
+ if self.features is not None:
156
+
157
+ for feature in self.features:
158
+
159
+ cv2.circle(self.frame, (feature[0][0], feature[0][1]), 4, (15, 241, 255), -1, 8, 0)
160
+
161
+
162
+
163
+ # 表示
164
+
165
+ cv2.imshow("motion", self.frame)
166
+
167
+
168
+
169
+ # 次のループ処理の準備
170
+
171
+ self.gray_prev = self.gray_next
172
+
173
+ end_flag, self.frame = self.video.read()
174
+
175
+ if end_flag:
176
+
177
+ self.gray_next = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)
178
+
179
+
180
+
181
+ # インターバル
182
+
183
+ key = cv2.waitKey(self.interval)
184
+
185
+ # "Esc"キー押下で終了
186
+
187
+ if key == ESC_KEY:
188
+
189
+ break
190
+
191
+ # "s"キー押下で一時停止
192
+
193
+ elif key == S_KEY:
194
+
195
+ self.interval = 0
196
+
197
+ elif key == R_KEY:
198
+
199
+ self.interval = INTERVAL
200
+
201
+
202
+
203
+
204
+
205
+ # 終了処理
206
+
207
+ cv2.destroyAllWindows()
208
+
209
+ self.video.release()
210
+
211
+
212
+
213
+
214
+
215
+ # マウスクリックで特徴点を指定する
216
+
217
+ # クリックされた近傍に既存の特徴点がある場合は既存の特徴点を削除する
218
+
219
+ # クリックされた近傍に既存の特徴点がない場合は新規に特徴点を追加する
220
+
221
+ def onMouse(self, event, x, y, flags, param):
222
+
223
+ # 左クリック以外
224
+
225
+ if event != cv2.EVENT_LBUTTONDOWN:
226
+
227
+ return
228
+
229
+
230
+
231
+ # 最初の特徴点追加
232
+
233
+ if self.features is None:
234
+
235
+ self.addFeature(x, y)
236
+
237
+ return
238
+
239
+
240
+
241
+ # 探索半径(pixel)
242
+
243
+ radius = 5
244
+
245
+ # 既存の特徴点が近傍にあるか探索
246
+
247
+ index = self.getFeatureIndex(x, y, radius)
248
+
249
+
250
+
251
+ # クリックされた近傍に既存の特徴点があるので既存の特徴点を削除する
252
+
253
+ if index >= 0:
254
+
255
+ self.features = np.delete(self.features, index, 0)
256
+
257
+ self.status = np.delete(self.status, index, 0)
258
+
259
+
260
+
261
+ # クリックされた近傍に既存の特徴点がないので新規に特徴点を追加する
262
+
263
+ else:
264
+
265
+ self.addFeature(x, y)
266
+
267
+
268
+
269
+ return
270
+
271
+
272
+
273
+
274
+
275
+ # 指定した半径内にある既存の特徴点のインデックスを1つ取得する
276
+
277
+ # 指定した半径内に特徴点がない場合 index = -1 を応答
278
+
279
+ def getFeatureIndex(self, x, y, radius):
280
+
281
+ index = -1
282
+
283
+
284
+
285
+ # 特徴点が1つも登録されていない
286
+
287
+ if self.features is None:
288
+
289
+ return index
290
+
291
+
292
+
293
+ max_r2 = radius ** 2
294
+
295
+ index = 0
296
+
297
+ for point in self.features:
298
+
299
+ dx = x - point[0][0]
300
+
301
+ dy = y - point[0][1]
302
+
303
+ r2 = dx ** 2 + dy ** 2
304
+
305
+ if r2 <= max_r2:
306
+
307
+ # この特徴点は指定された半径内
308
+
309
+ return index
310
+
311
+ else:
312
+
313
+ # この特徴点は指定された半径外
314
+
315
+ index += 1
316
+
317
+
318
+
319
+ # 全ての特徴点が指定された半径の外側にある
320
+
321
+ return -1
322
+
323
+
324
+
325
+
326
+
327
+ # 特徴点を新規に追加する
328
+
329
+ def addFeature(self, x, y):
330
+
331
+
332
+
333
+ # 特徴点が未登録
334
+
335
+ if self.features is None:
336
+
337
+ # ndarrayの作成し特徴点の座標を登録
338
+
339
+ self.features = np.array([[[x, y]]], np.float32)
340
+
341
+ self.status = np.array([1])
342
+
343
+ # 特徴点を高精度化
344
+
345
+ cv2.cornerSubPix(self.gray_next, self.features, (10, 10), (-1, -1), CRITERIA)
346
+
347
+
348
+
349
+ # 特徴点の最大登録個数をオーバー
350
+
351
+ elif len(self.features) >= MAX_FEATURE_NUM:
352
+
353
+ print("max feature num over: " + str(MAX_FEATURE_NUM))
354
+
355
+
356
+
357
+ # 特徴点を追加登録
358
+
359
+ else:
360
+
361
+ # 既存のndarrayの最後に特徴点の座標を追加
362
+
363
+ self.features = np.append(self.features, [[[x, y]]], axis = 0).astype(np.float32)
364
+
365
+ self.status = np.append(self.status, 1)
366
+
367
+ # 特徴点を高精度化
368
+
369
+ cv2.cornerSubPix(self.gray_next, self.features, (10, 10), (-1, -1), CRITERIA)
370
+
371
+
372
+
373
+
374
+
375
+ # 有効な特徴点のみ残す
376
+
377
+ def refreshFeatures(self):
378
+
379
+ # 特徴点が未登録
380
+
381
+ if self.features is None:
382
+
383
+ return
384
+
385
+
386
+
387
+ # 全statusをチェックする
388
+
389
+ i = 0
390
+
391
+ while i < len(self.features):
392
+
393
+
394
+
395
+ # 特徴点として認識できず
396
+
397
+ if self.status[i] == 0:
398
+
399
+ # 既存のndarrayから削除
400
+
401
+ self.features = np.delete(self.features, i, 0)
402
+
403
+ self.status = np.delete(self.status, i, 0)
404
+
405
+ i -= 1
406
+
407
+
408
+
409
+ i += 1
410
+
411
+
412
+
413
+
414
+
415
+ if __name__ == '__main__':
416
+
417
+ Motion().run()
14
418
 
15
419
  コード
16
420
 
17
- ```import cv2
18
-
19
- import numpy as np
20
-
21
-
22
-
23
- # Esc キー_終了
24
-
25
- ESC_KEY = 0x1b
26
-
27
- # s キー_一時停止
28
-
29
- S_KEY = 0x73
30
-
31
- # r キー_リスタート
32
-
33
- R_KEY = 0x72
34
-
35
- # 特徴点の最大数
36
-
37
- MAX_FEATURE_NUM = 500
38
-
39
- # 反復アルゴリズムの終了条件
40
-
41
- CRITERIA = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)
42
-
43
- # インターバル (1000 / フレームレート)
44
-
45
- INTERVAL = 30
46
-
47
- # ビデオデータ
48
-
49
- VIDEO_DATA = 'movie.mp4'
50
-
51
-
52
-
53
- class Motion:
54
-
55
- # コンストラクタ
56
-
57
- def __init__(self):
58
-
59
- # 表示ウィンドウ
60
-
61
- cv2.namedWindow("motion")
62
-
63
- # マウスイベントのコールバック登録
64
-
65
- cv2.setMouseCallback("motion", self.onMouse)
66
-
67
- # 映像
421
+ ```
68
-
69
- self.video = cv2.VideoCapture(VIDEO_DATA)
70
-
71
- # インターバル
72
-
73
- self.interval = INTERVAL
74
-
75
- # 現在のフレーム(カラー)
76
-
77
- self.frame = None
78
-
79
- # 現在のフレーム(グレー)
80
-
81
- self.gray_next = None
82
-
83
- # 前回のフレーム(グレー)
84
-
85
- self.gray_prev = None
86
-
87
- # 特徴点
88
-
89
- self.features = None
90
-
91
- # 特徴点のステータス
92
-
93
- self.status = None
94
-
95
-
96
-
97
- # メインループ
98
-
99
- def run(self):
100
-
101
-
102
-
103
- # 最初のフレームの処理
104
-
105
- end_flag, self.frame = self.video.read()
106
-
107
- self.gray_prev = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)
108
-
109
-
110
-
111
- while end_flag:
112
-
113
- # グレースケールに変換
114
-
115
- self.gray_next = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)
116
-
117
-
118
-
119
- # 特徴点が登録されている場合にOpticalFlowを計算する
120
-
121
- if self.features is not None:
122
-
123
- # オプティカルフローの計算
124
-
125
- features_prev = self.features
126
-
127
- self.features, self.status, err = cv2.calcOpticalFlowPyrLK( \
128
-
129
- self.gray_prev, \
130
-
131
- self.gray_next, \
132
-
133
- features_prev, \
134
-
135
- None, \
136
-
137
- winSize = (10, 10), \
138
-
139
- maxLevel = 3, \
140
-
141
- criteria = CRITERIA, \
142
-
143
- flags = 0)
144
-
145
-
146
-
147
- # 有効な特徴点のみ残す
148
-
149
- self.refreshFeatures()
150
-
151
-
152
-
153
- # フレームに有効な特徴点を描画
154
-
155
- if self.features is not None:
156
-
157
- for feature in self.features:
158
-
159
- cv2.circle(self.frame, (feature[0][0], feature[0][1]), 4, (15, 241, 255), -1, 8, 0)
160
-
161
-
162
-
163
- # 表示
164
-
165
- cv2.imshow("motion", self.frame)
166
-
167
-
168
-
169
- # 次のループ処理の準備
170
-
171
- self.gray_prev = self.gray_next
172
-
173
- end_flag, self.frame = self.video.read()
174
-
175
- if end_flag:
176
-
177
- self.gray_next = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)
178
-
179
-
180
-
181
- # インターバル
182
-
183
- key = cv2.waitKey(self.interval)
184
-
185
- # "Esc"キー押下で終了
186
-
187
- if key == ESC_KEY:
188
-
189
- break
190
-
191
- # "s"キー押下で一時停止
192
-
193
- elif key == S_KEY:
194
-
195
- self.interval = 0
196
-
197
- elif key == R_KEY:
198
-
199
- self.interval = INTERVAL
200
-
201
-
202
-
203
-
204
-
205
- # 終了処理
206
-
207
- cv2.destroyAllWindows()
208
-
209
- self.video.release()
210
-
211
-
212
-
213
-
214
-
215
- # マウスクリックで特徴点を指定する
216
-
217
- # クリックされた近傍に既存の特徴点がある場合は既存の特徴点を削除する
218
-
219
- # クリックされた近傍に既存の特徴点がない場合は新規に特徴点を追加する
220
-
221
- def onMouse(self, event, x, y, flags, param):
222
-
223
- # 左クリック以外
224
-
225
- if event != cv2.EVENT_LBUTTONDOWN:
226
-
227
- return
228
-
229
-
230
-
231
- # 最初の特徴点追加
232
-
233
- if self.features is None:
234
-
235
- self.addFeature(x, y)
236
-
237
- return
238
-
239
-
240
-
241
- # 探索半径(pixel)
242
-
243
- radius = 5
244
-
245
- # 既存の特徴点が近傍にあるか探索
246
-
247
- index = self.getFeatureIndex(x, y, radius)
248
-
249
-
250
-
251
- # クリックされた近傍に既存の特徴点があるので既存の特徴点を削除する
252
-
253
- if index >= 0:
254
-
255
- self.features = np.delete(self.features, index, 0)
256
-
257
- self.status = np.delete(self.status, index, 0)
258
-
259
-
260
-
261
- # クリックされた近傍に既存の特徴点がないので新規に特徴点を追加する
262
-
263
- else:
264
-
265
- self.addFeature(x, y)
266
-
267
-
268
-
269
- return
270
-
271
-
272
-
273
-
274
-
275
- # 指定した半径内にある既存の特徴点のインデックスを1つ取得する
276
-
277
- # 指定した半径内に特徴点がない場合 index = -1 を応答
278
-
279
- def getFeatureIndex(self, x, y, radius):
280
-
281
- index = -1
282
-
283
-
284
-
285
- # 特徴点が1つも登録されていない
286
-
287
- if self.features is None:
288
-
289
- return index
290
-
291
-
292
-
293
- max_r2 = radius ** 2
294
-
295
- index = 0
296
-
297
- for point in self.features:
298
-
299
- dx = x - point[0][0]
300
-
301
- dy = y - point[0][1]
302
-
303
- r2 = dx ** 2 + dy ** 2
304
-
305
- if r2 <= max_r2:
306
-
307
- # この特徴点は指定された半径内
308
-
309
- return index
310
-
311
- else:
312
-
313
- # この特徴点は指定された半径外
314
-
315
- index += 1
316
-
317
-
318
-
319
- # 全ての特徴点が指定された半径の外側にある
320
-
321
- return -1
322
-
323
-
324
-
325
-
326
-
327
- # 特徴点を新規に追加する
328
-
329
- def addFeature(self, x, y):
330
-
331
-
332
-
333
- # 特徴点が未登録
334
-
335
- if self.features is None:
336
-
337
- # ndarrayの作成し特徴点の座標を登録
338
-
339
- self.features = np.array([[[x, y]]], np.float32)
340
-
341
- self.status = np.array([1])
342
-
343
- # 特徴点を高精度化
344
-
345
- cv2.cornerSubPix(self.gray_next, self.features, (10, 10), (-1, -1), CRITERIA)
346
-
347
-
348
-
349
- # 特徴点の最大登録個数をオーバー
350
-
351
- elif len(self.features) >= MAX_FEATURE_NUM:
352
-
353
- print("max feature num over: " + str(MAX_FEATURE_NUM))
354
-
355
-
356
-
357
- # 特徴点を追加登録
358
-
359
- else:
360
-
361
- # 既存のndarrayの最後に特徴点の座標を追加
362
-
363
- self.features = np.append(self.features, [[[x, y]]], axis = 0).astype(np.float32)
364
-
365
- self.status = np.append(self.status, 1)
366
-
367
- # 特徴点を高精度化
368
-
369
- cv2.cornerSubPix(self.gray_next, self.features, (10, 10), (-1, -1), CRITERIA)
370
-
371
-
372
-
373
-
374
-
375
- # 有効な特徴点のみ残す
376
-
377
- def refreshFeatures(self):
378
-
379
- # 特徴点が未登録
380
-
381
- if self.features is None:
382
-
383
- return
384
-
385
-
386
-
387
- # 全statusをチェックする
388
-
389
- i = 0
390
-
391
- while i < len(self.features):
392
-
393
-
394
-
395
- # 特徴点として認識できず
396
-
397
- if self.status[i] == 0:
398
-
399
- # 既存のndarrayから削除
400
-
401
- self.features = np.delete(self.features, i, 0)
402
-
403
- self.status = np.delete(self.status, i, 0)
404
-
405
- i -= 1
406
-
407
-
408
-
409
- i += 1
410
-
411
-
412
-
413
-
414
-
415
- if __name__ == '__main__':
416
-
417
- Motion().run()