このアルゴリズムはハンガリアンアルゴリズムとKalmanTrackerを基盤とした安定追跡システムです。OpenCVライブラリが必要となるため、事前にインストールし適切なヘッダファイルをインポートしてください。実装には./include/SortTracker.hppヘッダと./src/SortTracker.cppソースファイルを使用します。
基本インターフェース
trk名前空間内に実装されたSortTrackerクラスの主要メソッドは次の通りです:
list<TrackingResult> processFrame(vector<Detection>& detections)
入力はvector<Detection>& detectionsで、1フレーム内の検出対象を表します。Detection構造体の構成は以下の通り:
struct Detection {
int frame_id = 0; // フレームID
int detection_id = 0; // 検出対象ID
int category = 0; // カテゴリ(0/1)
float score = 0.0; // 信頼度
Rect_<float> bbox; // 矩形座標(x,y,width,height)
};
出力はlist<TrackingResult>で追跡結果を表し、TrackingResult構造体で構成されます:
struct TrackingResult {
int track_id = 0; // 追跡対象ID
int category = 0; // カテゴリ
int hit_count = 0; // 連続検出フレーム数
int miss_count = 0; // 連続未検出フレーム数
float score = 0.0; // 信頼度
Rect_<float> bbox; // 矩形座標
};
SortTracker初期化時には閾値パラメータを指定可能:
SortTracker(double iou_thresh = 0.3,
int max_miss = 3,
int min_hits = 0,
float min_score = 0.0)
使用例
入力ファイルからフレームデータを読み込み、追跡処理を実行するサンプル:
void runTrackerDemo()
{
ifstream input_stream("./detections.txt");
ofstream output_stream("./results.txt");
vector<Detection> raw_detections;
string record;
while (getline(input_stream, record)) {
istringstream parser(record);
Detection det;
char delimiter;
float x, y, w, h;
parser >> det.frame_id >> delimiter >> det.detection_id >> delimiter;
parser >> x >> delimiter >> y >> delimiter >> w >> delimiter >> h >> delimiter;
parser >> det.score >> delimiter >> det.category;
det.bbox = Rect_<float>(x, y, w, h);
raw_detections.push_back(det);
}
int total_frames = 0;
for (const auto& item : raw_detections) {
if (item.frame_id > total_frames)
total_frames = item.frame_id;
}
vector<vector<Detection>> frame_based_detections;
for (int fid = 1; fid <= total_frames; fid++) {
vector<Detection> current_frame;
for (const auto& det : raw_detections) {
if (det.frame_id == fid)
current_frame.push_back(det);
}
frame_based_detections.push_back(current_frame);
}
SortTracker tracker(0.4, 4, 2, 0.5);
for (int fid = 0; fid < total_frames; fid++) {
auto results = tracker.processFrame(frame_based_detections[fid]);
for (const auto& res : results) {
output_stream << fid + 1 << "," << res.track_id << ","
<< res.bbox.x << "," << res.bbox.y << ","
<< res.bbox.width << "," << res.bbox.height << ","
<< res.score << "," << res.category << endl;
}
}
}