動画上でクリックした点を追跡するプログラムを書きました.
何個も特徴点を追加できるのですが,すべて同じ色になっていします.
その色を変更できますか?←解決しました‼
また,クリックして加えた特徴点を含む動画を保存し,座標を示すことは可能でしょうか?csvに座標を,mp4に動画の保存をしたいです.
作成したコードを示します.
import
1import numpy as np 2 3# Esc キー_終了 4ESC_KEY = 0x1b 5# s キー_一時停止 6S_KEY = 0x73 7# r キー_リスタート 8R_KEY = 0x72 9# 特徴点の最大数 10MAX_FEATURE_NUM = 500 11# 反復アルゴリズムの終了条件 12CRITERIA = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03) 13# インターバル (1000 / フレームレート) 14INTERVAL = 30 15# ビデオデータ 16VIDEO_DATA = 'movie.mp4' 17 18class Motion: 19 # コンストラクタ 20 def __init__(self): 21 # 表示ウィンドウ 22 cv2.namedWindow("motion") 23 # マウスイベントのコールバック登録 24 cv2.setMouseCallback("motion", self.onMouse) 25 # 映像 26 self.video = cv2.VideoCapture(VIDEO_DATA) 27 # インターバル 28 self.interval = INTERVAL 29 # 現在のフレーム(カラー) 30 self.frame = None 31 # 現在のフレーム(グレー) 32 self.gray_next = None 33 # 前回のフレーム(グレー) 34 self.gray_prev = None 35 # 特徴点 36 self.features = None 37 # 特徴点のステータス 38 self.status = None 39 40 # メインループ 41 def run(self): 42 43 # 最初のフレームの処理 44 end_flag, self.frame = self.video.read() 45 self.gray_prev = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY) 46 47 while end_flag: 48 # グレースケールに変換 49 self.gray_next = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY) 50 51 # 特徴点が登録されている場合にOpticalFlowを計算する 52 if self.features is not None: 53 # オプティカルフローの計算 54 features_prev = self.features 55 self.features, self.status, err = cv2.calcOpticalFlowPyrLK( \ 56 self.gray_prev, \ 57 self.gray_next, \ 58 features_prev, \ 59 None, \ 60 winSize = (10, 10), \ 61 maxLevel = 3, \ 62 criteria = CRITERIA, \ 63 flags = 0) 64 65 # 有効な特徴点のみ残す 66 self.refreshFeatures() 67 68 # フレームに有効な特徴点を描画 69 if self.features is not None: 70 for feature in self.features: 71 cv2.circle(self.frame, (feature[0][0], feature[0][1]), 4, (15, 241, 255), -1, 8, 0) 72 73 # 表示 74 cv2.imshow("motion", self.frame) 75 76 # 次のループ処理の準備 77 self.gray_prev = self.gray_next 78 end_flag, self.frame = self.video.read() 79 if end_flag: 80 self.gray_next = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY) 81 82 # インターバル 83 key = cv2.waitKey(self.interval) 84 # "Esc"キー押下で終了 85 if key == ESC_KEY: 86 break 87 # "s"キー押下で一時停止 88 elif key == S_KEY: 89 self.interval = 0 90 elif key == R_KEY: 91 self.interval = INTERVAL 92 93 94 # 終了処理 95 cv2.destroyAllWindows() 96 self.video.release() 97 98 99 # マウスクリックで特徴点を指定する 100 # クリックされた近傍に既存の特徴点がある場合は既存の特徴点を削除する 101 # クリックされた近傍に既存の特徴点がない場合は新規に特徴点を追加する 102 def onMouse(self, event, x, y, flags, param): 103 # 左クリック以外 104 if event != cv2.EVENT_LBUTTONDOWN: 105 return 106 107 # 最初の特徴点追加 108 if self.features is None: 109 self.addFeature(x, y) 110 return 111 112 # 探索半径(pixel) 113 radius = 5 114 # 既存の特徴点が近傍にあるか探索 115 index = self.getFeatureIndex(x, y, radius) 116 117 # クリックされた近傍に既存の特徴点があるので既存の特徴点を削除する 118 if index >= 0: 119 self.features = np.delete(self.features, index, 0) 120 self.status = np.delete(self.status, index, 0) 121 122 # クリックされた近傍に既存の特徴点がないので新規に特徴点を追加する 123 else: 124 self.addFeature(x, y) 125 126 return 127 128 129 # 指定した半径内にある既存の特徴点のインデックスを1つ取得する 130 # 指定した半径内に特徴点がない場合 index = -1 を応答 131 def getFeatureIndex(self, x, y, radius): 132 index = -1 133 134 # 特徴点が1つも登録されていない 135 if self.features is None: 136 return index 137 138 max_r2 = radius ** 2 139 index = 0 140 for point in self.features: 141 dx = x - point[0][0] 142 dy = y - point[0][1] 143 r2 = dx ** 2 + dy ** 2 144 if r2 <= max_r2: 145 # この特徴点は指定された半径内 146 return index 147 else: 148 # この特徴点は指定された半径外 149 index += 1 150 151 # 全ての特徴点が指定された半径の外側にある 152 return -1 153 154 155 # 特徴点を新規に追加する 156 def addFeature(self, x, y): 157 158 # 特徴点が未登録 159 if self.features is None: 160 # ndarrayの作成し特徴点の座標を登録 161 self.features = np.array([[[x, y]]], np.float32) 162 self.status = np.array([1]) 163 # 特徴点を高精度化 164 cv2.cornerSubPix(self.gray_next, self.features, (10, 10), (-1, -1), CRITERIA) 165 166 # 特徴点の最大登録個数をオーバー 167 elif len(self.features) >= MAX_FEATURE_NUM: 168 print("max feature num over: " + str(MAX_FEATURE_NUM)) 169 170 # 特徴点を追加登録 171 else: 172 # 既存のndarrayの最後に特徴点の座標を追加 173 self.features = np.append(self.features, [[[x, y]]], axis = 0).astype(np.float32) 174 self.status = np.append(self.status, 1) 175 # 特徴点を高精度化 176 cv2.cornerSubPix(self.gray_next, self.features, (10, 10), (-1, -1), CRITERIA) 177 178 179 # 有効な特徴点のみ残す 180 def refreshFeatures(self): 181 # 特徴点が未登録 182 if self.features is None: 183 return 184 185 # 全statusをチェックする 186 i = 0 187 while i < len(self.features): 188 189 # 特徴点として認識できず 190 if self.status[i] == 0: 191 # 既存のndarrayから削除 192 self.features = np.delete(self.features, i, 0) 193 self.status = np.delete(self.status, i, 0) 194 i -= 1 195 196 i += 1 197 198 199if __name__ == '__main__': 200 Motion().run() 201コード
あなたの回答
tips
プレビュー