ailia_tracker  1.1.0.0
APIの使用方法

ailia TrackerのAPIの概要

基本的な使用方法

ailia Trackerでは、ailiaTrackerCreateでインスタンスを作成、ailiaTrackerAddTargetで物体検知モデルの検知結果を登録し、ailiaTrackerComputeでトラッキングを実行、ailiaTrackerGetObjectでトラッキング結果を取得可能です。

#include <ctime>
#include <cstdlib>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <vector>
#include <map>
#undef UNICODE
#include "ailia.h"
#include "ailia_detector.h"
#include "ailia_tracker.h"
#include "detector_utils.h"
#include "utils.h"
#include "webcamera_utils.h"
// ======================
// Parameters
// ======================
#define WEIGHT_PATH "yolox_s.opt.onnx"
#define MODEL_PATH "yolox_s.opt.onnx.prototxt"
#define MODEL_INPUT_WIDTH 640
#define MODEL_INPUT_HEIGHT 640
#define IMAGE_WIDTH 640 // for video mode
#define IMAGE_HEIGHT 640 // for video mode
#define TARGET_CATEGORY 0 // person
#define THRESHOLD 0.4f
#define IOU 0.45f
#define IS_VERTICAL_THRESHOLD 1.6
#define RECTANGLE_BORDER_SIZE 2
#define TEXT_COLOR cv::Scalar(0, 255, 0)
#define TEXT_SIZE 1.0
#define TEXT_BORDER_SIZE 1
#define TEXT_FONT cv::FONT_HERSHEY_SIMPLEX
static bool useWebCamera(false);
static bool saveOutputVideo(false);
static std::string inputVideoPath;
static std::string outputVideoPath;
static int args_env_id = -1;
void main(void){
std::map<unsigned int, cv::Scalar> id2Color;
// AILIANetworkインスタンスの作成(初期化詳細は省略)
AILIANetwork *ailia;
// AILIADetectorインスタンスの作成(初期化詳細は省略)
AILIADetector *detector;
AILIATracker *ailiaTracker = nullptr;
settings.score_threshold = 0.1f;
settings.nms_threshold = 0.7f;
settings.track_threshold = 0.5f;
settings.track_buffer = 30;
settings.match_threshold = 0.8f;
status = ailiaTrackerCreate(&ailiaTracker,
// cv::VideoCapture作成
cv::VideoCapture capture;
if (useWebCamera) {
capture = cv::VideoCapture(atoi(inputVideoPath.c_str()));
} else {
capture = cv::VideoCapture(inputVideoPath.c_str());
}
// cv::VideoWriter作成
cv::VideoWriter writer;
if(saveOutputVideo){
int fourcc = cv::VideoWriter::fourcc('M','P','4','V');
writer = cv::VideoWriter(
outputVideoPath.c_str(), fourcc, capture.get(cv::CAP_PROP_FPS), cv::Size(IMAGE_WIDTH, IMAGE_HEIGHT)
);
}
while (1) {
// OpenCVでフレーム読み込み
cv::Mat frame, resized_img, img;
capture >> frame;
if ((char)cv::waitKey(1) == 'q' || frame.empty()) {
break;
}
adjust_frame_size(frame, resized_img, IMAGE_WIDTH, IMAGE_HEIGHT);
cv::cvtColor(resized_img, img, cv::COLOR_BGR2BGRA);
// 物体検知を実行
ailiaDetectorCompute(detector, img.data, MODEL_INPUT_WIDTH * 4,
MODEL_INPUT_WIDTH, MODEL_INPUT_HEIGHT,
AILIA_IMAGE_FORMAT_BGRA, THRESHOLD, IOU);
unsigned int objCounts;
ailiaDetectorGetObjectCount(detector, &objCounts);
AILIADetectorObject *ailiaDetectorObject = new AILIADetectorObject[objCounts];
for (int i = 0; i < objCounts; i++) {
ailiaDetectorGetObject(detector, &ailiaDetectorObject[i], i,
AILIA_DETECTOR_OBJECT_VERSION);
}
// 物体検知結果をailiaTrackerに連携
for(int i=0; i<objCounts; i++){
ailiaTrackerAddTarget(ailiaTracker, &ailiaDetectorObject[i], AILIA_DETECTOR_OBJECT_VERSION);
}
delete[] ailiaDetectorObject;
// トラッキングを実行
ailiaTrackerCompute(ailiaTracker);
unsigned int onlineSize;
// トラッキングでオンラインの物体数を取得
ailiaTrackerGetObjectCount(ailiaTracker, &onlineSize);
AILIATrackerObject *ailiaTrackerObject = new AILIATrackerObject[onlineSize];
// トラッキング結果を取得
ailiaTrackerGetObject(ailiaTracker, ailiaTrackerObject, 1);
cv::Point leftUpperPoint, rightBottomPoint;
// トラッキング結果を一つずつ取得しバウンディングボックスを描画
cv::Scalar color;
for (unsigned int i = 0; i < onlineSize; i++) {
AILIATrackerObject obj = ailiaTrackerObject[i];
if(obj.category != TARGET_CATEGORY){
continue;
}
const unsigned int id = obj.id;
if(id2Color.find(id) != id2Color.end()){
color = id2Color[id];
}else{
int b = rand() % 256;
int g = rand() % 256;
int r = rand() % 256;
color = cv::Scalar(b, g, r);
id2Color.insert(std::make_pair(id, color));
}
const unsigned int x = static_cast<unsigned int>(obj.x * IMAGE_WIDTH);
const unsigned int y = static_cast<unsigned int>(obj.y * IMAGE_HEIGHT);
const unsigned int width = static_cast<unsigned int>(obj.w * IMAGE_WIDTH);
const unsigned int height = static_cast<unsigned int>(obj.h * IMAGE_HEIGHT);
leftUpperPoint = cv::Point(x, y);
rightBottomPoint = cv::Point(x+width, y+height);
cv::rectangle(resized_img, leftUpperPoint, rightBottomPoint,
color, RECTANGLE_BORDER_SIZE);
cv::putText(resized_img, std::to_string(obj.id),
leftUpperPoint, TEXT_FONT, TEXT_SIZE, TEXT_COLOR,
TEXT_BORDER_SIZE);
}
delete[] ailiaTrackerObject;
// 結果を描画
cv::imshow("result frame", resized_img);
if(saveOutputVideo){
writer.write(resized_img);
}
}
capture.release();
f(saveOutputVideo){
writer.release();
}
cv::destroyAllWindows();
// AILIATrackerインスタンスの破棄
ailiaTrackerDestroy(ailiaTracker);
ailiaDestroyDetector(detector);
ailiaDestroy(ailia);
}
ailia Tracking 物体追跡 ライブラリ
#define AILIA_TRACKER_ALGORITHM_BYTE_TRACK
ByteTrack
Definition: ailia_tracker.h:43
int AILIA_API ailiaTrackerAddTarget(struct AILIATracker *tracker, const AILIADetectorObject *detector_object, int version)
トラッキングの対象を登録します。
int AILIA_API ailiaTrackerGetObjectCount(struct AILIATracker *tracker, unsigned int *obj_count)
検出結果の数を取得します。
#define AILIA_TRACKER_FLAG_NONE
フラグを設定しません
Definition: ailia_tracker.h:202
int AILIA_API ailiaTrackerDestroy(struct AILIATracker *tracker)
トラッカーオブジェクトを破棄します。
int AILIA_API ailiaTrackerCreate(struct AILIATracker **tracker, int algorithm, const AILIATrackerSettings *settings, int version, int flags)
トラッカーオブジェクトを作成します。
int AILIA_API ailiaTrackerCompute(struct AILIATracker *tracker)
トラッキングを行います。
#define AILIA_TRACKER_SETTINGS_VERSION
Definition: ailia_tracker.h:112
int AILIA_API ailiaTrackerGetObject(struct AILIATracker *tracker, AILIATrackerObject *obj, unsigned int index, unsigned int version)
検出結果を取得します。
Definition: ailia_tracker.h:50
float x
Definition: ailia_tracker.h:82
float h
Definition: ailia_tracker.h:106
unsigned int category
Definition: ailia_tracker.h:66
float w
Definition: ailia_tracker.h:98
float y
Definition: ailia_tracker.h:90
unsigned int id
Definition: ailia_tracker.h:58
Definition: ailia_tracker.h:114
float nms_threshold
Definition: ailia_tracker.h:139
float score_threshold
Definition: ailia_tracker.h:126
float match_threshold
Definition: ailia_tracker.h:186
int track_buffer
Definition: ailia_tracker.h:171
float track_threshold
Definition: ailia_tracker.h:158

ailia Trackerのパラメータ

ailia Trackerが使用するトラッキングアルゴリズムであるByte Trackは、カルマンフィルタを使用して、バウンディングボックスの形状のみからトラッキングを行います。画像特徴は使用しません。

1. 検出結果を取得
2. score_threshold で低スコアを除外
3. nms_threshold で重複除去 (NMS)
4. track_threshold 以上の高信頼検出を「第1段マッチング用」として選別
5. match_threshold を使って
└→ 前フレームのトラックと現在フレームの検出をマッチング
6. (第1段でマッチしなかったトラックに対して)
track_threshold 未満の「低スコア検出」でも IoU が高ければ再マッチング
→ ここでも IoU に match_threshold が利用される
7. track_buffer を用いて見失い管理

設定可能なパラメータを下記に示します。

パラメータ名 説明
score_threshold 検出結果を採用するかどうかを決めるスコア(信頼度)の下限値です。検出スコアがこの値未満の物体は追跡対象から除外されます。値を大きくすると確実な検出のみを扱い、小さくするとノイズを含む検出も保持します。
デフォルト:0.1
nms_threshold 検出結果の重複を除去するための NMS(Non-Maximum Suppression)しきい値です。IoU(物体の重なり)がこの値を超えるような検出は同一物体とみなされ、最もスコアの高いものだけが残ります。値を小さくすると重複検出を厳しく除去し、大きくすると緩やかになります。
デフォルト:0.7
track_threshold 追跡対象として更新に使用する検出スコアのしきい値です。通常はこの値以上のスコアを持つ検出のみでトラックを更新しますが、ByteTrack のアルゴリズムでは、score_threshold 以上かつ track_threshold 未満の低スコア検出であっても、IoU のマッチングが成立した場合には補助的にトラック更新に利用されることがあります。
値を高くすると厳密な追跡となり、低くすると一時的に信頼度が下がった物体も追跡しやすくなります。
デフォルト:0.5
track_buffer 一度見失った物体トラックを保持しておく最大フレーム数です。指定されたフレーム数の間に同じ物体を再び検出できればトラッキングが再開されます。この値を大きくすると見失った物体を長く保持し、小さくすると早めに追跡終了とみなします。
デフォルト:30
match_threshold フレーム間で物体を対応付ける際の IoU(Intersection over Union)しきい値です。IoU がこの値以上の場合、前フレームのトラックと現在フレームの検出が同一物体とみなされます。値を大きくするとマッチングが厳密になり、値を小さくするとゆるやかになります。
デフォルト:0.8

ailia Trackerのフラグ

デフォルトでは、人の検知に最適化されたモードで動作します。Byte Trackの標準アルゴリズムに従い、縦横比が1.6以上の横長画像の場合はトラッキングの対象外になります。

AILIA_TRACKER_FLAG_ALLOW_WIDE_ASPECT_RATIOを指定することで、横長画像に対してもトラッキングの対象とすることができます。車の検知などで有効です。