[Отслеживание целей] Подробное объяснение ByteTrack и детали кода
[Отслеживание целей] Подробное объяснение ByteTrack и детали кода

1. Предисловие

Адрес статьи: https://arxiv.org/pdf/2110.06864.pdf.

адрес git: https://github.com/ifzhang/ByteTrack

ByteTrack был публично выпущен в октябре 2021 года и получил награду ECCV 2022. Благодаря простой конструкции он победил все трекеры «магической модификации» того времени, впервые преодолев 80 MOTA на данных MOT17 и достигнув скорости вывода до 30 в одном V100. ФПС. Я резюмирую основные идеи ByteTrack следующим образом:

  1. Различают блоки обнаружения с высокой степенью достоверности и блоки обнаружения с низкой степенью достоверности.,Кадры обнаружения с разными уровнями достоверности используют разные методы обработки.
  2. Сохраняйте кадры обнаружения с низкой степенью достоверности, которые могут быть подтверждены позднее. confirm состояние. а не традиционный MOT алгоритмвыбиратьудалить.

ByteTrack может эффективно устранять некоторые препятствия и поддерживать низкий уровень IDSwith. Достоверность обнаружения цели будет снижена, поскольку она закрыта, а когда она появится снова, достоверность увеличится. Вы можете себе представить:

  1. Когда цель постепенно скрывается,Отслеживание цели и совпадение целей обнаружения с низкой достоверностью.
  2. Когда окклюзия цели постепенно появляется снова,Отслеживайте цели и обнаруживайте совпадения целей с высокой уверенностью.

Кроме того, следует тщательно рассматривать и устранять ложные срабатывания при обнаружении и кадры с низкой достоверностью без обнаружения цели.

DeepSort и ByteTrack часто сравнивают в Интернете. Что касается ByteTrack и DeepSort, у них есть свои ограничения. Мы должны выбрать подходящий алгоритм в соответствии с реальной ситуацией.

  • ByteTrack: Эффект отслеживания во многом зависит от эффекта обнаружения. Если детектор хороший, отслеживание также даст хорошие результаты.
  • DeepSort: использует дескрипторы внешнего вида и сложный алгоритм сопоставления.,В некоторых сложных сценариях может потребоваться большой объем вычислений.,Влияет на производительность в реальном времени.

2. Подробное объяснение кода

Чтобы по-настоящему понять и полностью понять, важно прочитать исходный код. Дело не в том, что вам нужно понимать исходный код для запуска проекта, но вы можете похвастаться после того, как поймете его. Дело не в том, что вам нужно хвастаться, по крайней мере, у вас будет чувство выполненного долга.

Без лишних слов, давайте сразу к делу! Этот раздел кода немного сложно объяснить подробно. Если вы не можете понять это в данный момент, вы можете поставить лайк и сначала сохранить его, а затем медленно прочитать позже. . .

Это легко понять. Вместо следования порядку кода анализ основан на порядке от начала до конца дорожки.

2.1. Новая траектория

Только высокие (больше, чем high_thrash) ячейки уверенности могут начать новую траекторию. Порог, который различает кадры обнаружения с высокой и низкой достоверностью, равен track_thresh = 0,5. Но обычно значение, установленное high_thresh, больше, чем track_thresh. Например, high_thresh = 0,6. В новом треке состояние = Отслеживается, только первый кадр нового трека is_activated =True, в противном случае is_activated = false.

Язык кода:javascript
копировать
	this->state = TrackState::Tracked;
	if (frame_id == 1)
	{
		this->is_activated = true;
	}
	//this->is_activated = true;
	this->frame_id = frame_id;
	this->start_frame = frame_id;

Подвести итог:когда Первыйрамкачас,Сам трек - это пространство-время,Только уровень достоверности превышает high_thresh Когда появится новый стартовый трек состояние в это время = Tracked,is_activated = истинный. Впоследствии остаются только несовпадающие и уровень достоверности очень высок (более high_thresh ) — новый стартовый трек, состояние в это время = Tracked,is_activated = false。

2.2. Прогнозирование

Объединить is_activated = true с состоянием = потерянные треки. После слияния выполняется прогнозирование, которое следует за прогнозированием фильтра Калмана.

Каждая новая информация об обнаружении инициализирует STrack Объект, сможет ли этот объект начать новую траекторию, уточнялось ранее. в исходном коде tlbr 顺序Это ловушкаЗаказ неtop,left,bottom,верно. На самом деле осталось,top,right,нижний. я тоже сначала неправильно понял,Я до сих пор не понимаю, почему для назван в таком порядке.

Язык кода:javascript
копировать
	if (objects.boxes.size() > 0)
	{
		for (int i = 0; i < objects.boxes.size(); i++)
		{
			std::vector<float> tlbr_;   // x1,y1,x2,y2
			tlbr_.resize(4);
			tlbr_[0] = objects.boxes[i].x;
			tlbr_[1] = objects.boxes[i].y;
			tlbr_[2] = objects.boxes[i].x + objects.boxes[i].w;
			tlbr_[3] = objects.boxes[i].y + objects.boxes[i].h;
			float score = objects.boxes[i].score;
			STrack strack(STrack::tlbr_to_tlwh(tlbr_), score);
			if (score >= track_thresh)
			{
				detections.push_back(strack);
			}
			else
			{
				detections_low.push_back(strack);
			}
			
		}
	}

tlbr_to_tlwh преобразует x1,y1,x2,y2 в x1,y1,w,h. При запуске нового трека tlwh_to_xyah в функции активации преобразует x1, y1, w, h в xCenter, yCenter, w/h, h. Затем поместите его в инициализацию фильтра Калмана, чтобы инициализировать его состояние и ковариацию.

Язык кода:javascript
копировать
void STrack::activate(byte_kalman::KalmanFilter &kalman_filter, int frame_id)
{
     Опустить код здесь
	auto mc = this->kalman_filter.initiate(xyah_box);
     Опустить код здесь
}

На данный момент _motion_mat представляет собой матрицу 8*8. Соответствующее уравнение состояния движения представляет собой равномерную скорость.

box состояние meanдля:(xCenter,yCenter,w/h,h,Vx,Vy,Vr,Vh)。 предсказывать, предсказывать Получить новое состояние new_mean = _motion_mat * mean.T

Язык кода:javascript
копировать
	void KalmanFilter::predict(KAL_MEAN &mean, KAL_COVA &covariance)
	{
		//revise the data;
		DETECTBOX std_pos;
		std_pos << _std_weight_position * mean(3),
			_std_weight_position * mean(3),
			1e-2,
			_std_weight_position * mean(3);
		DETECTBOX std_vel;
		std_vel << _std_weight_velocity * mean(3),
			_std_weight_velocity * mean(3),
			1e-5,
			_std_weight_velocity * mean(3);
		KAL_MEAN tmp;
		tmp.block<1, 4>(0, 0) = std_pos;
		tmp.block<1, 4>(0, 4) = std_vel;
		tmp = tmp.array().square();
		KAL_COVA motion_cov = tmp.asDiagonal();
		KAL_MEAN mean1 = this->_motion_mat * mean.transpose();
		KAL_COVA covariance1 = this->_motion_mat * covariance *(_motion_mat.transpose());
		covariance1 += motion_cov;

		mean = mean1;
		covariance = covariance1;
	}

Обновить ковариацию covariance = _motion_mat * convariance *_motion_mat.T + motion_cov 。 montion_covдляматрица шума процесса。В целом может оставаться неизменным,Может быть установлен во время инициализации,Исходный кодсерединаSET для w/h связанная диагональная матрица.

2.3. Соответствие

Эта часть является изюминкой всей статьи, а также самой запутанной частью кода.

Блок предсказания первого совпадения и блок обнаружения с высокой степенью достоверности

  • Поле прогнозов: окно прогнозов отслеживания для версии 2.2середина. Они заявляют, что гусеничногоилиLost
  • Кадр обнаружения высокой достоверности: кадр обнаружения с уровнем достоверности выше track_thresh середина, text серединаtrack_thresh Установить значение 0,5.

Расчеты, использованные в этой статье iou Выполняется сопоставление, а также пересечение и сравнение между кадром предсказания и кадром обнаружения. когда совпадает поле предсказания, состояние в это время = Tracked,is_activated = true。 После сопоставления необходимо обновить ковариацию блока.

обновление в калмане:

Язык кода:javascript
копировать
	KAL_DATA
		KalmanFilter::update(
			const KAL_MEAN &mean,
			const KAL_COVA &covariance,
			const DETECTBOX &measurement)
	{
		KAL_HDATA pa = project(mean, covariance);
		KAL_HMEAN projected_mean = pa.first;    // x,y,r,h
		KAL_HCOVA projected_cov = pa.second;    // _update_mat * covariance * (_update_mat.transpose()) + diag

		Eigen::Matrix<float, 4, 8> B = (covariance * (_update_mat.transpose())).transpose();
		Eigen::Matrix<float, 8, 4> kalman_gain = (projected_cov.llt().solve(B)).transpose(); // eg.8x4
		Eigen::Matrix<float, 1, 4> innovation = measurement - projected_mean; //eg.1x4
		auto tmp = innovation * (kalman_gain.transpose());
		KAL_MEAN new_mean = (mean.array() + tmp.array()).matrix();
		KAL_COVA new_covariance = covariance - kalman_gain * projected_cov*(kalman_gain.transpose());
		return std::make_pair(new_mean, new_covariance);
	}

Сначала введите функцию проекта и получите Projected_mean и Projected_con. Давайте сначала посмотрим, какие операции выполнял проект.

Язык кода:javascript
копировать
	KAL_HDATA KalmanFilter::project(const KAL_MEAN &mean, const KAL_COVA &covariance)
	{
		DETECTBOX std;
		std << _std_weight_position * mean(3), _std_weight_position * mean(3),
			1e-1, _std_weight_position * mean(3);
		KAL_HMEAN mean1 = _update_mat * mean.transpose();
		KAL_HCOVA covariance1 = _update_mat * covariance * (_update_mat.transpose());
		Eigen::Matrix<float, 4, 4> diag = std.asDiagonal();
		diag = diag.array().square().matrix();
		covariance1 += diag;
		return std::make_pair(mean1, covariance1);
	}

mean Матрица 1*8 (xCenter, yCenter, w/h, h, Vx, Vy, Vr, Vh) mean1 Эквивалентно извлечению mean первые четыре элемента. covariance1 Это сделано для облегчения последующих обновлений. covariance Промежуточная сумма. diag Для измерения ковариации шума настройки в этой статье аналогичны матрице шума процесса. kalman_gain Для выигрыша Калмана потребовалось бы projected_cov Обратная матрица , а затем B Его получают путем перемножения матриц. Здесь он получается непосредственно путем решения системы линейных уравнений, пропуская некоторые этапы вычислений. new_mean и new_covariance для нового box состояниеи Новая ковариация. После того, как кадр предсказания и кадр обнаружения с высокой степенью достоверности успешно сопоставлены, независимо от это время目标 state для гусеничного все еще Пропало, все надо обновить для гусеничногосостояние,иis_activated обновляются до истинный. И все нужно выполнить kalman середина update действовать. Как только цель будет достигнута:

(1) Состояние цели меняется на «Отслеживается».

(2) Значение is_activated цели становится истинным.

(3) Необходимо обновить среднюю ковариацию цели.

Кадр предсказания и кадр обнаружения, которые не совпадают в первый раз, дополнительно кэшируются. Удобное последующее действие.

второй матч Первый несовпадающий блок прогнозов и блок обнаружения с низкой достоверностью

  • Несовпадающее поле прогноза впервые: Несовпадающее впервые, состояниедля Ящик предсказаний Гусеничного. состояниедля гусеничногоуказать цельдля Верхнийрамкасоответствующая цель
  • Кадр обнаружения с низкой достоверностью: кадр обнаружения с достоверностью меньше, чем track_threshсередина, текст серединаtrack_thresh = 0,5.

Матчи по-прежнему засчитываются в счет ваших матчей. Аналогично обрабатываются совпадения в целевом первом матче. Несовпадающие цели будут отмечены, а состояние может быть изменено позже.

третий матч is_activated=false Блок отслеживания и первый не имеющий аналогов блок обнаружения с высокой степенью достоверности.

  • Кадр отслеживания с is_activated=false: новая цель из предыдущего кадра. Только новая цель из предыдущего кадра is_activate имеет значение false, и кадр в этот момент не был предсказан, что означает, что используется исходное обнаружение предыдущего кадра. . коробка соответствие
  • Первый непревзойденный кадр обнаружения с высокой степенью достоверности: достоверность превышает track_thresh.,Но в первый раз изостояниедляis_activate отслеживает целевое совпадение.

Если цель совпадает, то (1) укажите = Tracked(2)is_activated = true(3)mean и covariance все update。

Если цель не соответствует,в это времясостояниевстречастановиться При удалении эта цель будет удалена навсегда. Чтобы избежать случайного ложного срабатывания определенного кадра два раза подряд, необходимо обнаружить, по крайней мере, кадр с высокой достоверностью. confirm,有机встреча参и Последующие расчеты。

2.4. Публикация результатов.

Перед публикацией результатов необходимо изменить значение переменной-члена класса BYTETrack.

  1. Когда состояние Lost превышает When max_time_lost, указывает, что Lost становится удаленным, эта цель навсегда забывается. max_time_lost уже установлен при построении функции. Установите значение 10 или 30, отрегулируйте в соответствии с реальной ситуацией.
  2. когдачлен state от Lost становиться Tracked или Remove dчас,this->lost_stracks Те, у кого одинаковый идентификатор, должны быть устранены.
Язык кода:javascript
копировать
this->lost_stracks = sub_stracks(this->lost_stracks, this->tracked_stracks);
this->lost_stracks = sub_stracks(this->lost_stracks, this->removed_stracks);
remove_duplicate_stracks(resa, resb, this->tracked_stracks, this->lost_stracks);    // Удалять Повторить путь

При наличии повторяющихся путей количество кадров выживания одинаково и траектории аналогичны. Этот потерянный след также необходимо устранить. Результаты вывода: цель будет выводиться только в том случае, если is_activated = true, state = Tracked.

2.5. Резюме

  1. Когда цель обнаружения не совпадает, только уровень достоверности когда превышает 0.6 Только тогда можно будет начать новую траекторию, а другие ситуации будут прямо забыты. В это время новая траектория is_activated для false (первый кадр другой, первый кадр начинает новую дорожку is_activated 默认для true), когда достоверность следующего кадра больше, чем 0.5 Цель обнаружения находится в третьем матч совпадает, когда (is_activated=false Цель не имеет права участвовать в первых двух матчах), в это время is_activated становиться true。в это времяотмеченныйдля подтвердите право на вывод.
  2. Трек отслеживания в сопоставлении середина успешно найден, в это времянесмотря ни на что state = отслеживается, is_activated = true. К первым двум матчам середина можно обратиться в следующем кадре. Если первые два матча неудачны, то в это время state = Потерян, может относиться только к следующему кадру. если подряд max_time_lost рамкасуществоватьпервый матч не совпадает, в это время будет забыто Удален, удалить этот трек навсегда.

3. Блок-схема

Если вы все еще не поняли после прочтения, я дам вам еще одну блок-схему, которую я составил.

4. Развертывание

Если вы действительно не можете понять исходный код и не хотите его понимать, вам просто нужно запустить его локально, чтобы увидеть эффект. Тогда смотрите прямо здесь.

Окружающая среда: компиляция Linux cmake

Набор данных: https://motchallenge.net/data/MOT17/

адрес git: https://github.com/ifzhang/ByteTrack

Первый clone Исходный код внизу. Ссылка была дана ранее. С++ Код находится в deploy папка, выбранная блоггером ncnn\cpp код в папке. Есть ниже include и src Это весь код.

В CMakeLists.txt отсутствуют ссылки.

Файл mian.cpp Основная идея состоит в том, чтобы прочитать файл det.txt и сохранить результаты обнаружения каждого кадра. Дайте мне примерный код

Язык кода:javascript
копировать
BYTETracker byteTrack = BYTETracker(10, 30);
for (int fi = 0; fi < maxFrame; fi++) { // maxFrame рамка
    std::vector<ObjectTrack> trackResult;
    byteTrack.update(detFrameData[fi], trackResult);
}

trackResult — это результат, определенный вами

Просто укажите файл BYTETracker.cpp и измените обновление на

Язык кода:javascript
копировать
void BYTETracker::update(const DetectInfo& objects, std::vector<ObjectTrack>& outTracks)
{
    // в конце функции добавить код
	for (auto i = 0; i < output_stracks.size(); i++)
	{
		outTracks.push_back({
							static_cast<uint>(output_stracks[i].track_id), 
							static_cast<uint>(output_stracks[i].tlbr[0]),
							static_cast<uint>(output_stracks[i].tlbr[1]),
							static_cast<uint>(output_stracks[i].tlbr[2]),
							static_cast<uint>(output_stracks[i].tlbr[3]),
							output_stracks[i].score			
						});
	}
}

На данный момент результаты получены. В дальнейшем вам останется только визуализировать соответствующие результаты на соответствующих картинках и все готово [Cheers.jpg]. Вы достаточно умны, чтобы принять меры.

boy illustration
Учебное пособие по Jetpack Compose для начинающих, базовые элементы управления и макет
boy illustration
Код js веб-страницы, фон частицы, код спецэффектов
boy illustration
【новый! Суперподробное】Полное руководство по свойствам компонентов Figma.
boy illustration
🎉Обязательно к прочтению новичкам: полное руководство по написанию мини-программ WeChat с использованием программного обеспечения Cursor.
boy illustration
[Забавный проект Docker] VoceChat — еще одно приложение для мгновенного чата (IM)! Может быть встроен в любую веб-страницу!
boy illustration
Как реализовать переход по странице в HTML (html переходит на указанную страницу)
boy illustration
Как решить проблему зависания и низкой скорости при установке зависимостей с помощью npm. Существуют ли доступные источники npm, которые могут решить эту проблему?
boy illustration
Серия From Zero to Fun: Uni-App WeChat Payment Practice WeChat авторизует вход в систему и украшает страницу заказа, создает интерфейс заказа и инициирует запрос заказа
boy illustration
Серия uni-app: uni.navigateЧтобы передать скачок значения
boy illustration
Апплет WeChat настраивает верхнюю панель навигации и адаптируется к различным моделям.
boy illustration
JS-время конвертации
boy illustration
Обеспечьте бесперебойную работу ChromeDriver 125: советы по решению проблемы chromedriver.exe не найдены
boy illustration
Поле комментария, щелчок мышью, специальные эффекты, js-код
boy illustration
Объект массива перемещения объекта JS
boy illustration
Как открыть разрешение на позиционирование апплета WeChat_Как использовать WeChat для определения местонахождения друзей
boy illustration
Я даю вам два набора из 18 простых в использовании фонов холста Power BI, так что вам больше не придется возиться с цветами!
boy illustration
Получить текущее время в js_Как динамически отображать дату и время в js
boy illustration
Вам необходимо изучить сочетания клавиш vsCode для форматирования и организации кода, чтобы вам больше не приходилось настраивать формат вручную.
boy illustration
У ChatGPT большое обновление. Всего за 45 минут пресс-конференция показывает, что OpenAI сделал еще один шаг вперед.
boy illustration
Copilot облачной разработки — упрощение разработки
boy illustration
Микросборка xChatGPT с низким кодом, создание апплета чат-бота с искусственным интеллектом за пять шагов
boy illustration
CUDA Out of Memory: идеальное решение проблемы нехватки памяти CUDA
boy illustration
Анализ кластеризации отдельных ячеек, который должен освоить каждый&MarkerгенетическийВизуализация
boy illustration
vLLM: мощный инструмент для ускорения вывода ИИ
boy illustration
CodeGeeX: мощный инструмент генерации кода искусственного интеллекта, который можно использовать бесплатно в дополнение к второму пилоту.
boy illustration
Машинное обучение Реальный бой LightGBM + настройка параметров случайного поиска: точность 96,67%
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция без кодирования и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
LM Studio для создания локальных больших моделей
boy illustration
Как определить количество слоев и нейронов скрытых слоев нейронной сети?
boy illustration
[Отслеживание целей] Подробное объяснение ByteTrack и детали кода