Spaces:
Runtime error
Runtime error
AK391
commited on
Commit
·
7734d5b
1
Parent(s):
924319f
all files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- Dockerfile +53 -0
- datasets/data_path/citypersons.train +0 -0
- datasets/data_path/eth.train +2056 -0
- deploy/ONNXRuntime/README.md +19 -0
- deploy/ONNXRuntime/onnx_inference.py +160 -0
- deploy/TensorRT/cpp/CMakeLists.txt +39 -0
- deploy/TensorRT/cpp/README.md +58 -0
- deploy/TensorRT/cpp/include/BYTETracker.h +49 -0
- deploy/TensorRT/cpp/include/STrack.h +50 -0
- deploy/TensorRT/cpp/include/dataType.h +36 -0
- deploy/TensorRT/cpp/include/kalmanFilter.h +31 -0
- deploy/TensorRT/cpp/include/lapjv.h +63 -0
- deploy/TensorRT/cpp/include/logging.h +503 -0
- deploy/TensorRT/cpp/src/BYTETracker.cpp +241 -0
- deploy/TensorRT/cpp/src/STrack.cpp +192 -0
- deploy/TensorRT/cpp/src/bytetrack.cpp +506 -0
- deploy/TensorRT/cpp/src/kalmanFilter.cpp +152 -0
- deploy/TensorRT/cpp/src/lapjv.cpp +343 -0
- deploy/TensorRT/cpp/src/utils.cpp +429 -0
- deploy/TensorRT/python/README.md +22 -0
- deploy/ncnn/cpp/CMakeLists.txt +84 -0
- deploy/ncnn/cpp/README.md +103 -0
- deploy/ncnn/cpp/include/BYTETracker.h +49 -0
- deploy/ncnn/cpp/include/STrack.h +50 -0
- deploy/ncnn/cpp/include/dataType.h +36 -0
- deploy/ncnn/cpp/include/kalmanFilter.h +31 -0
- deploy/ncnn/cpp/include/lapjv.h +63 -0
- deploy/ncnn/cpp/src/BYTETracker.cpp +241 -0
- deploy/ncnn/cpp/src/STrack.cpp +192 -0
- deploy/ncnn/cpp/src/bytetrack.cpp +396 -0
- deploy/ncnn/cpp/src/kalmanFilter.cpp +152 -0
- deploy/ncnn/cpp/src/lapjv.cpp +343 -0
- deploy/ncnn/cpp/src/utils.cpp +429 -0
- exps/default/nano.py +39 -0
- exps/default/yolov3.py +89 -0
- exps/default/yolox_l.py +15 -0
- exps/default/yolox_m.py +15 -0
- exps/default/yolox_s.py +15 -0
- exps/default/yolox_tiny.py +19 -0
- exps/default/yolox_x.py +15 -0
- exps/example/mot/yolox_l_mix_det.py +138 -0
- exps/example/mot/yolox_m_mix_det.py +138 -0
- exps/example/mot/yolox_s_mix_det.py +138 -0
- exps/example/mot/yolox_x_ablation.py +138 -0
- exps/example/mot/yolox_x_ch.py +138 -0
- exps/example/mot/yolox_x_mix_det.py +138 -0
- exps/example/mot/yolox_x_mix_mot20_ch.py +139 -0
- exps/example/mot/yolox_x_mot17_half.py +138 -0
- requirements.txt +22 -0
- setup.cfg +18 -0
Dockerfile
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM nvcr.io/nvidia/tensorrt:21.09-py3
|
| 2 |
+
|
| 3 |
+
ENV DEBIAN_FRONTEND=noninteractive
|
| 4 |
+
ARG USERNAME=user
|
| 5 |
+
ARG WORKDIR=/workspace/ByteTrack
|
| 6 |
+
|
| 7 |
+
RUN apt-get update && apt-get install -y \
|
| 8 |
+
automake autoconf libpng-dev nano python3-pip \
|
| 9 |
+
curl zip unzip libtool swig zlib1g-dev pkg-config \
|
| 10 |
+
python3-mock libpython3-dev libpython3-all-dev \
|
| 11 |
+
g++ gcc cmake make pciutils cpio gosu wget \
|
| 12 |
+
libgtk-3-dev libxtst-dev sudo apt-transport-https \
|
| 13 |
+
build-essential gnupg git xz-utils vim \
|
| 14 |
+
libva-drm2 libva-x11-2 vainfo libva-wayland2 libva-glx2 \
|
| 15 |
+
libva-dev libdrm-dev xorg xorg-dev protobuf-compiler \
|
| 16 |
+
openbox libx11-dev libgl1-mesa-glx libgl1-mesa-dev \
|
| 17 |
+
libtbb2 libtbb-dev libopenblas-dev libopenmpi-dev \
|
| 18 |
+
&& sed -i 's/# set linenumbers/set linenumbers/g' /etc/nanorc \
|
| 19 |
+
&& apt clean \
|
| 20 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 21 |
+
|
| 22 |
+
RUN git clone https://github.com/ifzhang/ByteTrack \
|
| 23 |
+
&& cd ByteTrack \
|
| 24 |
+
&& git checkout 3434c5e8bc6a5ae8ad530528ba8d9a431967f237 \
|
| 25 |
+
&& mkdir -p YOLOX_outputs/yolox_x_mix_det/track_vis \
|
| 26 |
+
&& sed -i 's/torch>=1.7/torch==1.9.1+cu111/g' requirements.txt \
|
| 27 |
+
&& sed -i 's/torchvision==0.10.0/torchvision==0.10.1+cu111/g' requirements.txt \
|
| 28 |
+
&& sed -i "s/'cuda'/0/g" tools/demo_track.py \
|
| 29 |
+
&& pip3 install pip --upgrade \
|
| 30 |
+
&& pip3 install -r requirements.txt -f https://download.pytorch.org/whl/torch_stable.html \
|
| 31 |
+
&& python3 setup.py develop \
|
| 32 |
+
&& pip3 install cython \
|
| 33 |
+
&& pip3 install 'git+https://github.com/cocodataset/cocoapi.git#subdirectory=PythonAPI' \
|
| 34 |
+
&& pip3 install cython_bbox gdown \
|
| 35 |
+
&& ldconfig \
|
| 36 |
+
&& pip cache purge
|
| 37 |
+
|
| 38 |
+
RUN git clone https://github.com/NVIDIA-AI-IOT/torch2trt \
|
| 39 |
+
&& cd torch2trt \
|
| 40 |
+
&& git checkout 0400b38123d01cc845364870bdf0a0044ea2b3b2 \
|
| 41 |
+
# https://github.com/NVIDIA-AI-IOT/torch2trt/issues/619
|
| 42 |
+
&& wget https://github.com/NVIDIA-AI-IOT/torch2trt/commit/8b9fb46ddbe99c2ddf3f1ed148c97435cbeb8fd3.patch \
|
| 43 |
+
&& git apply 8b9fb46ddbe99c2ddf3f1ed148c97435cbeb8fd3.patch \
|
| 44 |
+
&& python3 setup.py install
|
| 45 |
+
|
| 46 |
+
RUN echo "root:root" | chpasswd \
|
| 47 |
+
&& adduser --disabled-password --gecos "" "${USERNAME}" \
|
| 48 |
+
&& echo "${USERNAME}:${USERNAME}" | chpasswd \
|
| 49 |
+
&& echo "%${USERNAME} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/${USERNAME} \
|
| 50 |
+
&& chmod 0440 /etc/sudoers.d/${USERNAME}
|
| 51 |
+
USER ${USERNAME}
|
| 52 |
+
RUN sudo chown -R ${USERNAME}:${USERNAME} ${WORKDIR}
|
| 53 |
+
WORKDIR ${WORKDIR}
|
datasets/data_path/citypersons.train
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
datasets/data_path/eth.train
ADDED
|
@@ -0,0 +1,2056 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
ETHZ/eth01/images/image_00000001_0.png
|
| 2 |
+
ETHZ/eth01/images/image_00000002_0.png
|
| 3 |
+
ETHZ/eth01/images/image_00000003_0.png
|
| 4 |
+
ETHZ/eth01/images/image_00000004_0.png
|
| 5 |
+
ETHZ/eth01/images/image_00000005_0.png
|
| 6 |
+
ETHZ/eth01/images/image_00000006_0.png
|
| 7 |
+
ETHZ/eth01/images/image_00000007_0.png
|
| 8 |
+
ETHZ/eth01/images/image_00000008_0.png
|
| 9 |
+
ETHZ/eth01/images/image_00000009_0.png
|
| 10 |
+
ETHZ/eth01/images/image_00000010_0.png
|
| 11 |
+
ETHZ/eth01/images/image_00000011_0.png
|
| 12 |
+
ETHZ/eth01/images/image_00000012_0.png
|
| 13 |
+
ETHZ/eth01/images/image_00000013_0.png
|
| 14 |
+
ETHZ/eth01/images/image_00000014_0.png
|
| 15 |
+
ETHZ/eth01/images/image_00000015_0.png
|
| 16 |
+
ETHZ/eth01/images/image_00000016_0.png
|
| 17 |
+
ETHZ/eth01/images/image_00000017_0.png
|
| 18 |
+
ETHZ/eth01/images/image_00000018_0.png
|
| 19 |
+
ETHZ/eth01/images/image_00000019_0.png
|
| 20 |
+
ETHZ/eth01/images/image_00000020_0.png
|
| 21 |
+
ETHZ/eth01/images/image_00000021_0.png
|
| 22 |
+
ETHZ/eth01/images/image_00000022_0.png
|
| 23 |
+
ETHZ/eth01/images/image_00000023_0.png
|
| 24 |
+
ETHZ/eth01/images/image_00000024_0.png
|
| 25 |
+
ETHZ/eth01/images/image_00000025_0.png
|
| 26 |
+
ETHZ/eth01/images/image_00000026_0.png
|
| 27 |
+
ETHZ/eth01/images/image_00000027_0.png
|
| 28 |
+
ETHZ/eth01/images/image_00000028_0.png
|
| 29 |
+
ETHZ/eth01/images/image_00000029_0.png
|
| 30 |
+
ETHZ/eth01/images/image_00000030_0.png
|
| 31 |
+
ETHZ/eth01/images/image_00000031_0.png
|
| 32 |
+
ETHZ/eth01/images/image_00000032_0.png
|
| 33 |
+
ETHZ/eth01/images/image_00000033_0.png
|
| 34 |
+
ETHZ/eth01/images/image_00000034_0.png
|
| 35 |
+
ETHZ/eth01/images/image_00000035_0.png
|
| 36 |
+
ETHZ/eth01/images/image_00000036_0.png
|
| 37 |
+
ETHZ/eth01/images/image_00000037_0.png
|
| 38 |
+
ETHZ/eth01/images/image_00000038_0.png
|
| 39 |
+
ETHZ/eth01/images/image_00000039_0.png
|
| 40 |
+
ETHZ/eth01/images/image_00000040_0.png
|
| 41 |
+
ETHZ/eth01/images/image_00000041_0.png
|
| 42 |
+
ETHZ/eth01/images/image_00000042_0.png
|
| 43 |
+
ETHZ/eth01/images/image_00000043_0.png
|
| 44 |
+
ETHZ/eth01/images/image_00000044_0.png
|
| 45 |
+
ETHZ/eth01/images/image_00000045_0.png
|
| 46 |
+
ETHZ/eth01/images/image_00000046_0.png
|
| 47 |
+
ETHZ/eth01/images/image_00000047_0.png
|
| 48 |
+
ETHZ/eth01/images/image_00000048_0.png
|
| 49 |
+
ETHZ/eth01/images/image_00000049_0.png
|
| 50 |
+
ETHZ/eth01/images/image_00000050_0.png
|
| 51 |
+
ETHZ/eth01/images/image_00000051_0.png
|
| 52 |
+
ETHZ/eth01/images/image_00000052_0.png
|
| 53 |
+
ETHZ/eth01/images/image_00000053_0.png
|
| 54 |
+
ETHZ/eth01/images/image_00000054_0.png
|
| 55 |
+
ETHZ/eth01/images/image_00000055_0.png
|
| 56 |
+
ETHZ/eth01/images/image_00000056_0.png
|
| 57 |
+
ETHZ/eth01/images/image_00000057_0.png
|
| 58 |
+
ETHZ/eth01/images/image_00000058_0.png
|
| 59 |
+
ETHZ/eth01/images/image_00000059_0.png
|
| 60 |
+
ETHZ/eth01/images/image_00000060_0.png
|
| 61 |
+
ETHZ/eth01/images/image_00000061_0.png
|
| 62 |
+
ETHZ/eth01/images/image_00000062_0.png
|
| 63 |
+
ETHZ/eth01/images/image_00000063_0.png
|
| 64 |
+
ETHZ/eth01/images/image_00000064_0.png
|
| 65 |
+
ETHZ/eth01/images/image_00000065_0.png
|
| 66 |
+
ETHZ/eth01/images/image_00000066_0.png
|
| 67 |
+
ETHZ/eth01/images/image_00000067_0.png
|
| 68 |
+
ETHZ/eth01/images/image_00000068_0.png
|
| 69 |
+
ETHZ/eth01/images/image_00000069_0.png
|
| 70 |
+
ETHZ/eth01/images/image_00000070_0.png
|
| 71 |
+
ETHZ/eth01/images/image_00000071_0.png
|
| 72 |
+
ETHZ/eth01/images/image_00000072_0.png
|
| 73 |
+
ETHZ/eth01/images/image_00000073_0.png
|
| 74 |
+
ETHZ/eth01/images/image_00000074_0.png
|
| 75 |
+
ETHZ/eth01/images/image_00000075_0.png
|
| 76 |
+
ETHZ/eth01/images/image_00000076_0.png
|
| 77 |
+
ETHZ/eth01/images/image_00000077_0.png
|
| 78 |
+
ETHZ/eth01/images/image_00000078_0.png
|
| 79 |
+
ETHZ/eth01/images/image_00000079_0.png
|
| 80 |
+
ETHZ/eth01/images/image_00000080_0.png
|
| 81 |
+
ETHZ/eth01/images/image_00000081_0.png
|
| 82 |
+
ETHZ/eth01/images/image_00000082_0.png
|
| 83 |
+
ETHZ/eth01/images/image_00000083_0.png
|
| 84 |
+
ETHZ/eth01/images/image_00000084_0.png
|
| 85 |
+
ETHZ/eth01/images/image_00000085_0.png
|
| 86 |
+
ETHZ/eth01/images/image_00000086_0.png
|
| 87 |
+
ETHZ/eth01/images/image_00000087_0.png
|
| 88 |
+
ETHZ/eth01/images/image_00000088_0.png
|
| 89 |
+
ETHZ/eth01/images/image_00000089_0.png
|
| 90 |
+
ETHZ/eth01/images/image_00000090_0.png
|
| 91 |
+
ETHZ/eth01/images/image_00000091_0.png
|
| 92 |
+
ETHZ/eth01/images/image_00000092_0.png
|
| 93 |
+
ETHZ/eth01/images/image_00000093_0.png
|
| 94 |
+
ETHZ/eth01/images/image_00000094_0.png
|
| 95 |
+
ETHZ/eth01/images/image_00000095_0.png
|
| 96 |
+
ETHZ/eth01/images/image_00000096_0.png
|
| 97 |
+
ETHZ/eth01/images/image_00000097_0.png
|
| 98 |
+
ETHZ/eth01/images/image_00000098_0.png
|
| 99 |
+
ETHZ/eth01/images/image_00000099_0.png
|
| 100 |
+
ETHZ/eth01/images/image_00000100_0.png
|
| 101 |
+
ETHZ/eth01/images/image_00000101_0.png
|
| 102 |
+
ETHZ/eth01/images/image_00000102_0.png
|
| 103 |
+
ETHZ/eth01/images/image_00000103_0.png
|
| 104 |
+
ETHZ/eth01/images/image_00000104_0.png
|
| 105 |
+
ETHZ/eth01/images/image_00000105_0.png
|
| 106 |
+
ETHZ/eth01/images/image_00000106_0.png
|
| 107 |
+
ETHZ/eth01/images/image_00000107_0.png
|
| 108 |
+
ETHZ/eth01/images/image_00000108_0.png
|
| 109 |
+
ETHZ/eth01/images/image_00000109_0.png
|
| 110 |
+
ETHZ/eth01/images/image_00000110_0.png
|
| 111 |
+
ETHZ/eth01/images/image_00000111_0.png
|
| 112 |
+
ETHZ/eth01/images/image_00000112_0.png
|
| 113 |
+
ETHZ/eth01/images/image_00000113_0.png
|
| 114 |
+
ETHZ/eth01/images/image_00000114_0.png
|
| 115 |
+
ETHZ/eth01/images/image_00000115_0.png
|
| 116 |
+
ETHZ/eth01/images/image_00000116_0.png
|
| 117 |
+
ETHZ/eth01/images/image_00000117_0.png
|
| 118 |
+
ETHZ/eth01/images/image_00000118_0.png
|
| 119 |
+
ETHZ/eth01/images/image_00000119_0.png
|
| 120 |
+
ETHZ/eth01/images/image_00000120_0.png
|
| 121 |
+
ETHZ/eth01/images/image_00000121_0.png
|
| 122 |
+
ETHZ/eth01/images/image_00000122_0.png
|
| 123 |
+
ETHZ/eth01/images/image_00000123_0.png
|
| 124 |
+
ETHZ/eth01/images/image_00000124_0.png
|
| 125 |
+
ETHZ/eth01/images/image_00000125_0.png
|
| 126 |
+
ETHZ/eth01/images/image_00000126_0.png
|
| 127 |
+
ETHZ/eth01/images/image_00000127_0.png
|
| 128 |
+
ETHZ/eth01/images/image_00000128_0.png
|
| 129 |
+
ETHZ/eth01/images/image_00000129_0.png
|
| 130 |
+
ETHZ/eth01/images/image_00000130_0.png
|
| 131 |
+
ETHZ/eth01/images/image_00000131_0.png
|
| 132 |
+
ETHZ/eth01/images/image_00000132_0.png
|
| 133 |
+
ETHZ/eth01/images/image_00000133_0.png
|
| 134 |
+
ETHZ/eth01/images/image_00000134_0.png
|
| 135 |
+
ETHZ/eth01/images/image_00000135_0.png
|
| 136 |
+
ETHZ/eth01/images/image_00000136_0.png
|
| 137 |
+
ETHZ/eth01/images/image_00000137_0.png
|
| 138 |
+
ETHZ/eth01/images/image_00000138_0.png
|
| 139 |
+
ETHZ/eth01/images/image_00000139_0.png
|
| 140 |
+
ETHZ/eth01/images/image_00000140_0.png
|
| 141 |
+
ETHZ/eth01/images/image_00000141_0.png
|
| 142 |
+
ETHZ/eth01/images/image_00000142_0.png
|
| 143 |
+
ETHZ/eth01/images/image_00000143_0.png
|
| 144 |
+
ETHZ/eth01/images/image_00000144_0.png
|
| 145 |
+
ETHZ/eth01/images/image_00000145_0.png
|
| 146 |
+
ETHZ/eth01/images/image_00000146_0.png
|
| 147 |
+
ETHZ/eth01/images/image_00000147_0.png
|
| 148 |
+
ETHZ/eth01/images/image_00000148_0.png
|
| 149 |
+
ETHZ/eth01/images/image_00000149_0.png
|
| 150 |
+
ETHZ/eth01/images/image_00000150_0.png
|
| 151 |
+
ETHZ/eth01/images/image_00000151_0.png
|
| 152 |
+
ETHZ/eth01/images/image_00000152_0.png
|
| 153 |
+
ETHZ/eth01/images/image_00000153_0.png
|
| 154 |
+
ETHZ/eth01/images/image_00000154_0.png
|
| 155 |
+
ETHZ/eth01/images/image_00000155_0.png
|
| 156 |
+
ETHZ/eth01/images/image_00000156_0.png
|
| 157 |
+
ETHZ/eth01/images/image_00000157_0.png
|
| 158 |
+
ETHZ/eth01/images/image_00000158_0.png
|
| 159 |
+
ETHZ/eth01/images/image_00000159_0.png
|
| 160 |
+
ETHZ/eth01/images/image_00000160_0.png
|
| 161 |
+
ETHZ/eth01/images/image_00000161_0.png
|
| 162 |
+
ETHZ/eth01/images/image_00000162_0.png
|
| 163 |
+
ETHZ/eth01/images/image_00000163_0.png
|
| 164 |
+
ETHZ/eth01/images/image_00000164_0.png
|
| 165 |
+
ETHZ/eth01/images/image_00000165_0.png
|
| 166 |
+
ETHZ/eth01/images/image_00000166_0.png
|
| 167 |
+
ETHZ/eth01/images/image_00000167_0.png
|
| 168 |
+
ETHZ/eth01/images/image_00000168_0.png
|
| 169 |
+
ETHZ/eth01/images/image_00000169_0.png
|
| 170 |
+
ETHZ/eth01/images/image_00000170_0.png
|
| 171 |
+
ETHZ/eth01/images/image_00000171_0.png
|
| 172 |
+
ETHZ/eth01/images/image_00000172_0.png
|
| 173 |
+
ETHZ/eth01/images/image_00000173_0.png
|
| 174 |
+
ETHZ/eth01/images/image_00000174_0.png
|
| 175 |
+
ETHZ/eth01/images/image_00000175_0.png
|
| 176 |
+
ETHZ/eth01/images/image_00000176_0.png
|
| 177 |
+
ETHZ/eth01/images/image_00000177_0.png
|
| 178 |
+
ETHZ/eth01/images/image_00000178_0.png
|
| 179 |
+
ETHZ/eth01/images/image_00000179_0.png
|
| 180 |
+
ETHZ/eth01/images/image_00000180_0.png
|
| 181 |
+
ETHZ/eth01/images/image_00000181_0.png
|
| 182 |
+
ETHZ/eth01/images/image_00000182_0.png
|
| 183 |
+
ETHZ/eth01/images/image_00000183_0.png
|
| 184 |
+
ETHZ/eth01/images/image_00000184_0.png
|
| 185 |
+
ETHZ/eth01/images/image_00000185_0.png
|
| 186 |
+
ETHZ/eth01/images/image_00000186_0.png
|
| 187 |
+
ETHZ/eth01/images/image_00000187_0.png
|
| 188 |
+
ETHZ/eth01/images/image_00000188_0.png
|
| 189 |
+
ETHZ/eth01/images/image_00000189_0.png
|
| 190 |
+
ETHZ/eth01/images/image_00000190_0.png
|
| 191 |
+
ETHZ/eth01/images/image_00000191_0.png
|
| 192 |
+
ETHZ/eth01/images/image_00000192_0.png
|
| 193 |
+
ETHZ/eth01/images/image_00000193_0.png
|
| 194 |
+
ETHZ/eth01/images/image_00000194_0.png
|
| 195 |
+
ETHZ/eth01/images/image_00000195_0.png
|
| 196 |
+
ETHZ/eth01/images/image_00000196_0.png
|
| 197 |
+
ETHZ/eth01/images/image_00000197_0.png
|
| 198 |
+
ETHZ/eth01/images/image_00000198_0.png
|
| 199 |
+
ETHZ/eth01/images/image_00000199_0.png
|
| 200 |
+
ETHZ/eth01/images/image_00000200_0.png
|
| 201 |
+
ETHZ/eth01/images/image_00000201_0.png
|
| 202 |
+
ETHZ/eth01/images/image_00000202_0.png
|
| 203 |
+
ETHZ/eth01/images/image_00000203_0.png
|
| 204 |
+
ETHZ/eth01/images/image_00000204_0.png
|
| 205 |
+
ETHZ/eth01/images/image_00000205_0.png
|
| 206 |
+
ETHZ/eth01/images/image_00000206_0.png
|
| 207 |
+
ETHZ/eth01/images/image_00000207_0.png
|
| 208 |
+
ETHZ/eth01/images/image_00000208_0.png
|
| 209 |
+
ETHZ/eth01/images/image_00000209_0.png
|
| 210 |
+
ETHZ/eth01/images/image_00000210_0.png
|
| 211 |
+
ETHZ/eth01/images/image_00000211_0.png
|
| 212 |
+
ETHZ/eth01/images/image_00000212_0.png
|
| 213 |
+
ETHZ/eth01/images/image_00000213_0.png
|
| 214 |
+
ETHZ/eth01/images/image_00000214_0.png
|
| 215 |
+
ETHZ/eth01/images/image_00000215_0.png
|
| 216 |
+
ETHZ/eth01/images/image_00000216_0.png
|
| 217 |
+
ETHZ/eth01/images/image_00000217_0.png
|
| 218 |
+
ETHZ/eth01/images/image_00000218_0.png
|
| 219 |
+
ETHZ/eth01/images/image_00000219_0.png
|
| 220 |
+
ETHZ/eth01/images/image_00000220_0.png
|
| 221 |
+
ETHZ/eth01/images/image_00000221_0.png
|
| 222 |
+
ETHZ/eth01/images/image_00000222_0.png
|
| 223 |
+
ETHZ/eth01/images/image_00000223_0.png
|
| 224 |
+
ETHZ/eth01/images/image_00000224_0.png
|
| 225 |
+
ETHZ/eth01/images/image_00000225_0.png
|
| 226 |
+
ETHZ/eth01/images/image_00000226_0.png
|
| 227 |
+
ETHZ/eth01/images/image_00000227_0.png
|
| 228 |
+
ETHZ/eth01/images/image_00000228_0.png
|
| 229 |
+
ETHZ/eth01/images/image_00000229_0.png
|
| 230 |
+
ETHZ/eth01/images/image_00000230_0.png
|
| 231 |
+
ETHZ/eth01/images/image_00000231_0.png
|
| 232 |
+
ETHZ/eth01/images/image_00000232_0.png
|
| 233 |
+
ETHZ/eth01/images/image_00000233_0.png
|
| 234 |
+
ETHZ/eth01/images/image_00000234_0.png
|
| 235 |
+
ETHZ/eth01/images/image_00000235_0.png
|
| 236 |
+
ETHZ/eth01/images/image_00000236_0.png
|
| 237 |
+
ETHZ/eth01/images/image_00000237_0.png
|
| 238 |
+
ETHZ/eth01/images/image_00000238_0.png
|
| 239 |
+
ETHZ/eth01/images/image_00000239_0.png
|
| 240 |
+
ETHZ/eth01/images/image_00000240_0.png
|
| 241 |
+
ETHZ/eth01/images/image_00000241_0.png
|
| 242 |
+
ETHZ/eth01/images/image_00000242_0.png
|
| 243 |
+
ETHZ/eth01/images/image_00000243_0.png
|
| 244 |
+
ETHZ/eth01/images/image_00000244_0.png
|
| 245 |
+
ETHZ/eth01/images/image_00000245_0.png
|
| 246 |
+
ETHZ/eth01/images/image_00000246_0.png
|
| 247 |
+
ETHZ/eth01/images/image_00000247_0.png
|
| 248 |
+
ETHZ/eth01/images/image_00000248_0.png
|
| 249 |
+
ETHZ/eth01/images/image_00000249_0.png
|
| 250 |
+
ETHZ/eth01/images/image_00000250_0.png
|
| 251 |
+
ETHZ/eth01/images/image_00000251_0.png
|
| 252 |
+
ETHZ/eth01/images/image_00000252_0.png
|
| 253 |
+
ETHZ/eth01/images/image_00000253_0.png
|
| 254 |
+
ETHZ/eth01/images/image_00000254_0.png
|
| 255 |
+
ETHZ/eth01/images/image_00000255_0.png
|
| 256 |
+
ETHZ/eth01/images/image_00000256_0.png
|
| 257 |
+
ETHZ/eth01/images/image_00000257_0.png
|
| 258 |
+
ETHZ/eth01/images/image_00000258_0.png
|
| 259 |
+
ETHZ/eth01/images/image_00000259_0.png
|
| 260 |
+
ETHZ/eth01/images/image_00000260_0.png
|
| 261 |
+
ETHZ/eth01/images/image_00000261_0.png
|
| 262 |
+
ETHZ/eth01/images/image_00000262_0.png
|
| 263 |
+
ETHZ/eth01/images/image_00000263_0.png
|
| 264 |
+
ETHZ/eth01/images/image_00000264_0.png
|
| 265 |
+
ETHZ/eth01/images/image_00000265_0.png
|
| 266 |
+
ETHZ/eth01/images/image_00000266_0.png
|
| 267 |
+
ETHZ/eth01/images/image_00000267_0.png
|
| 268 |
+
ETHZ/eth01/images/image_00000268_0.png
|
| 269 |
+
ETHZ/eth01/images/image_00000269_0.png
|
| 270 |
+
ETHZ/eth01/images/image_00000270_0.png
|
| 271 |
+
ETHZ/eth01/images/image_00000271_0.png
|
| 272 |
+
ETHZ/eth01/images/image_00000272_0.png
|
| 273 |
+
ETHZ/eth01/images/image_00000273_0.png
|
| 274 |
+
ETHZ/eth01/images/image_00000274_0.png
|
| 275 |
+
ETHZ/eth01/images/image_00000275_0.png
|
| 276 |
+
ETHZ/eth01/images/image_00000276_0.png
|
| 277 |
+
ETHZ/eth01/images/image_00000277_0.png
|
| 278 |
+
ETHZ/eth01/images/image_00000278_0.png
|
| 279 |
+
ETHZ/eth01/images/image_00000279_0.png
|
| 280 |
+
ETHZ/eth01/images/image_00000280_0.png
|
| 281 |
+
ETHZ/eth01/images/image_00000281_0.png
|
| 282 |
+
ETHZ/eth01/images/image_00000282_0.png
|
| 283 |
+
ETHZ/eth01/images/image_00000283_0.png
|
| 284 |
+
ETHZ/eth01/images/image_00000284_0.png
|
| 285 |
+
ETHZ/eth01/images/image_00000285_0.png
|
| 286 |
+
ETHZ/eth01/images/image_00000286_0.png
|
| 287 |
+
ETHZ/eth01/images/image_00000287_0.png
|
| 288 |
+
ETHZ/eth01/images/image_00000288_0.png
|
| 289 |
+
ETHZ/eth01/images/image_00000289_0.png
|
| 290 |
+
ETHZ/eth01/images/image_00000290_0.png
|
| 291 |
+
ETHZ/eth01/images/image_00000291_0.png
|
| 292 |
+
ETHZ/eth01/images/image_00000292_0.png
|
| 293 |
+
ETHZ/eth01/images/image_00000293_0.png
|
| 294 |
+
ETHZ/eth01/images/image_00000294_0.png
|
| 295 |
+
ETHZ/eth01/images/image_00000295_0.png
|
| 296 |
+
ETHZ/eth01/images/image_00000296_0.png
|
| 297 |
+
ETHZ/eth01/images/image_00000297_0.png
|
| 298 |
+
ETHZ/eth01/images/image_00000298_0.png
|
| 299 |
+
ETHZ/eth01/images/image_00000299_0.png
|
| 300 |
+
ETHZ/eth01/images/image_00000300_0.png
|
| 301 |
+
ETHZ/eth01/images/image_00000301_0.png
|
| 302 |
+
ETHZ/eth01/images/image_00000302_0.png
|
| 303 |
+
ETHZ/eth01/images/image_00000303_0.png
|
| 304 |
+
ETHZ/eth01/images/image_00000304_0.png
|
| 305 |
+
ETHZ/eth01/images/image_00000305_0.png
|
| 306 |
+
ETHZ/eth01/images/image_00000306_0.png
|
| 307 |
+
ETHZ/eth01/images/image_00000307_0.png
|
| 308 |
+
ETHZ/eth01/images/image_00000308_0.png
|
| 309 |
+
ETHZ/eth01/images/image_00000309_0.png
|
| 310 |
+
ETHZ/eth01/images/image_00000310_0.png
|
| 311 |
+
ETHZ/eth01/images/image_00000311_0.png
|
| 312 |
+
ETHZ/eth01/images/image_00000312_0.png
|
| 313 |
+
ETHZ/eth01/images/image_00000313_0.png
|
| 314 |
+
ETHZ/eth01/images/image_00000314_0.png
|
| 315 |
+
ETHZ/eth01/images/image_00000315_0.png
|
| 316 |
+
ETHZ/eth01/images/image_00000316_0.png
|
| 317 |
+
ETHZ/eth01/images/image_00000317_0.png
|
| 318 |
+
ETHZ/eth01/images/image_00000318_0.png
|
| 319 |
+
ETHZ/eth01/images/image_00000319_0.png
|
| 320 |
+
ETHZ/eth01/images/image_00000320_0.png
|
| 321 |
+
ETHZ/eth01/images/image_00000321_0.png
|
| 322 |
+
ETHZ/eth01/images/image_00000322_0.png
|
| 323 |
+
ETHZ/eth01/images/image_00000323_0.png
|
| 324 |
+
ETHZ/eth01/images/image_00000324_0.png
|
| 325 |
+
ETHZ/eth01/images/image_00000325_0.png
|
| 326 |
+
ETHZ/eth01/images/image_00000326_0.png
|
| 327 |
+
ETHZ/eth01/images/image_00000327_0.png
|
| 328 |
+
ETHZ/eth01/images/image_00000328_0.png
|
| 329 |
+
ETHZ/eth01/images/image_00000329_0.png
|
| 330 |
+
ETHZ/eth01/images/image_00000330_0.png
|
| 331 |
+
ETHZ/eth01/images/image_00000331_0.png
|
| 332 |
+
ETHZ/eth01/images/image_00000332_0.png
|
| 333 |
+
ETHZ/eth01/images/image_00000333_0.png
|
| 334 |
+
ETHZ/eth01/images/image_00000334_0.png
|
| 335 |
+
ETHZ/eth01/images/image_00000335_0.png
|
| 336 |
+
ETHZ/eth01/images/image_00000336_0.png
|
| 337 |
+
ETHZ/eth01/images/image_00000337_0.png
|
| 338 |
+
ETHZ/eth01/images/image_00000338_0.png
|
| 339 |
+
ETHZ/eth01/images/image_00000339_0.png
|
| 340 |
+
ETHZ/eth01/images/image_00000340_0.png
|
| 341 |
+
ETHZ/eth01/images/image_00000341_0.png
|
| 342 |
+
ETHZ/eth01/images/image_00000342_0.png
|
| 343 |
+
ETHZ/eth01/images/image_00000343_0.png
|
| 344 |
+
ETHZ/eth01/images/image_00000344_0.png
|
| 345 |
+
ETHZ/eth01/images/image_00000345_0.png
|
| 346 |
+
ETHZ/eth01/images/image_00000346_0.png
|
| 347 |
+
ETHZ/eth01/images/image_00000347_0.png
|
| 348 |
+
ETHZ/eth01/images/image_00000348_0.png
|
| 349 |
+
ETHZ/eth01/images/image_00000349_0.png
|
| 350 |
+
ETHZ/eth01/images/image_00000350_0.png
|
| 351 |
+
ETHZ/eth01/images/image_00000351_0.png
|
| 352 |
+
ETHZ/eth01/images/image_00000352_0.png
|
| 353 |
+
ETHZ/eth01/images/image_00000353_0.png
|
| 354 |
+
ETHZ/eth01/images/image_00000354_0.png
|
| 355 |
+
ETHZ/eth01/images/image_00000355_0.png
|
| 356 |
+
ETHZ/eth01/images/image_00000356_0.png
|
| 357 |
+
ETHZ/eth01/images/image_00000357_0.png
|
| 358 |
+
ETHZ/eth01/images/image_00000358_0.png
|
| 359 |
+
ETHZ/eth01/images/image_00000359_0.png
|
| 360 |
+
ETHZ/eth01/images/image_00000360_0.png
|
| 361 |
+
ETHZ/eth01/images/image_00000361_0.png
|
| 362 |
+
ETHZ/eth01/images/image_00000362_0.png
|
| 363 |
+
ETHZ/eth01/images/image_00000363_0.png
|
| 364 |
+
ETHZ/eth01/images/image_00000364_0.png
|
| 365 |
+
ETHZ/eth01/images/image_00000365_0.png
|
| 366 |
+
ETHZ/eth01/images/image_00000366_0.png
|
| 367 |
+
ETHZ/eth01/images/image_00000367_0.png
|
| 368 |
+
ETHZ/eth01/images/image_00000368_0.png
|
| 369 |
+
ETHZ/eth01/images/image_00000369_0.png
|
| 370 |
+
ETHZ/eth01/images/image_00000370_0.png
|
| 371 |
+
ETHZ/eth01/images/image_00000371_0.png
|
| 372 |
+
ETHZ/eth01/images/image_00000372_0.png
|
| 373 |
+
ETHZ/eth01/images/image_00000373_0.png
|
| 374 |
+
ETHZ/eth01/images/image_00000374_0.png
|
| 375 |
+
ETHZ/eth01/images/image_00000375_0.png
|
| 376 |
+
ETHZ/eth01/images/image_00000376_0.png
|
| 377 |
+
ETHZ/eth01/images/image_00000377_0.png
|
| 378 |
+
ETHZ/eth01/images/image_00000378_0.png
|
| 379 |
+
ETHZ/eth01/images/image_00000379_0.png
|
| 380 |
+
ETHZ/eth01/images/image_00000380_0.png
|
| 381 |
+
ETHZ/eth01/images/image_00000381_0.png
|
| 382 |
+
ETHZ/eth01/images/image_00000382_0.png
|
| 383 |
+
ETHZ/eth01/images/image_00000383_0.png
|
| 384 |
+
ETHZ/eth01/images/image_00000384_0.png
|
| 385 |
+
ETHZ/eth01/images/image_00000385_0.png
|
| 386 |
+
ETHZ/eth01/images/image_00000386_0.png
|
| 387 |
+
ETHZ/eth01/images/image_00000387_0.png
|
| 388 |
+
ETHZ/eth01/images/image_00000388_0.png
|
| 389 |
+
ETHZ/eth01/images/image_00000389_0.png
|
| 390 |
+
ETHZ/eth01/images/image_00000390_0.png
|
| 391 |
+
ETHZ/eth01/images/image_00000391_0.png
|
| 392 |
+
ETHZ/eth01/images/image_00000392_0.png
|
| 393 |
+
ETHZ/eth01/images/image_00000393_0.png
|
| 394 |
+
ETHZ/eth01/images/image_00000394_0.png
|
| 395 |
+
ETHZ/eth01/images/image_00000395_0.png
|
| 396 |
+
ETHZ/eth01/images/image_00000396_0.png
|
| 397 |
+
ETHZ/eth01/images/image_00000397_0.png
|
| 398 |
+
ETHZ/eth01/images/image_00000398_0.png
|
| 399 |
+
ETHZ/eth01/images/image_00000399_0.png
|
| 400 |
+
ETHZ/eth01/images/image_00000400_0.png
|
| 401 |
+
ETHZ/eth01/images/image_00000401_0.png
|
| 402 |
+
ETHZ/eth01/images/image_00000402_0.png
|
| 403 |
+
ETHZ/eth01/images/image_00000403_0.png
|
| 404 |
+
ETHZ/eth01/images/image_00000404_0.png
|
| 405 |
+
ETHZ/eth01/images/image_00000405_0.png
|
| 406 |
+
ETHZ/eth01/images/image_00000406_0.png
|
| 407 |
+
ETHZ/eth01/images/image_00000407_0.png
|
| 408 |
+
ETHZ/eth01/images/image_00000408_0.png
|
| 409 |
+
ETHZ/eth01/images/image_00000409_0.png
|
| 410 |
+
ETHZ/eth01/images/image_00000410_0.png
|
| 411 |
+
ETHZ/eth01/images/image_00000411_0.png
|
| 412 |
+
ETHZ/eth01/images/image_00000412_0.png
|
| 413 |
+
ETHZ/eth01/images/image_00000413_0.png
|
| 414 |
+
ETHZ/eth01/images/image_00000414_0.png
|
| 415 |
+
ETHZ/eth01/images/image_00000415_0.png
|
| 416 |
+
ETHZ/eth01/images/image_00000416_0.png
|
| 417 |
+
ETHZ/eth01/images/image_00000417_0.png
|
| 418 |
+
ETHZ/eth01/images/image_00000418_0.png
|
| 419 |
+
ETHZ/eth01/images/image_00000419_0.png
|
| 420 |
+
ETHZ/eth01/images/image_00000420_0.png
|
| 421 |
+
ETHZ/eth01/images/image_00000421_0.png
|
| 422 |
+
ETHZ/eth01/images/image_00000422_0.png
|
| 423 |
+
ETHZ/eth01/images/image_00000423_0.png
|
| 424 |
+
ETHZ/eth01/images/image_00000424_0.png
|
| 425 |
+
ETHZ/eth01/images/image_00000425_0.png
|
| 426 |
+
ETHZ/eth01/images/image_00000426_0.png
|
| 427 |
+
ETHZ/eth01/images/image_00000427_0.png
|
| 428 |
+
ETHZ/eth01/images/image_00000428_0.png
|
| 429 |
+
ETHZ/eth01/images/image_00000429_0.png
|
| 430 |
+
ETHZ/eth01/images/image_00000430_0.png
|
| 431 |
+
ETHZ/eth01/images/image_00000431_0.png
|
| 432 |
+
ETHZ/eth01/images/image_00000432_0.png
|
| 433 |
+
ETHZ/eth01/images/image_00000433_0.png
|
| 434 |
+
ETHZ/eth01/images/image_00000434_0.png
|
| 435 |
+
ETHZ/eth01/images/image_00000435_0.png
|
| 436 |
+
ETHZ/eth01/images/image_00000436_0.png
|
| 437 |
+
ETHZ/eth01/images/image_00000437_0.png
|
| 438 |
+
ETHZ/eth01/images/image_00000438_0.png
|
| 439 |
+
ETHZ/eth01/images/image_00000439_0.png
|
| 440 |
+
ETHZ/eth01/images/image_00000440_0.png
|
| 441 |
+
ETHZ/eth01/images/image_00000441_0.png
|
| 442 |
+
ETHZ/eth01/images/image_00000442_0.png
|
| 443 |
+
ETHZ/eth01/images/image_00000443_0.png
|
| 444 |
+
ETHZ/eth01/images/image_00000444_0.png
|
| 445 |
+
ETHZ/eth01/images/image_00000445_0.png
|
| 446 |
+
ETHZ/eth01/images/image_00000446_0.png
|
| 447 |
+
ETHZ/eth01/images/image_00000447_0.png
|
| 448 |
+
ETHZ/eth01/images/image_00000448_0.png
|
| 449 |
+
ETHZ/eth01/images/image_00000449_0.png
|
| 450 |
+
ETHZ/eth01/images/image_00000450_0.png
|
| 451 |
+
ETHZ/eth01/images/image_00000451_0.png
|
| 452 |
+
ETHZ/eth01/images/image_00000452_0.png
|
| 453 |
+
ETHZ/eth01/images/image_00000453_0.png
|
| 454 |
+
ETHZ/eth01/images/image_00000454_0.png
|
| 455 |
+
ETHZ/eth01/images/image_00000455_0.png
|
| 456 |
+
ETHZ/eth01/images/image_00000456_0.png
|
| 457 |
+
ETHZ/eth01/images/image_00000457_0.png
|
| 458 |
+
ETHZ/eth01/images/image_00000458_0.png
|
| 459 |
+
ETHZ/eth01/images/image_00000459_0.png
|
| 460 |
+
ETHZ/eth01/images/image_00000460_0.png
|
| 461 |
+
ETHZ/eth01/images/image_00000461_0.png
|
| 462 |
+
ETHZ/eth01/images/image_00000462_0.png
|
| 463 |
+
ETHZ/eth01/images/image_00000463_0.png
|
| 464 |
+
ETHZ/eth01/images/image_00000464_0.png
|
| 465 |
+
ETHZ/eth01/images/image_00000465_0.png
|
| 466 |
+
ETHZ/eth01/images/image_00000466_0.png
|
| 467 |
+
ETHZ/eth01/images/image_00000467_0.png
|
| 468 |
+
ETHZ/eth01/images/image_00000468_0.png
|
| 469 |
+
ETHZ/eth01/images/image_00000469_0.png
|
| 470 |
+
ETHZ/eth01/images/image_00000470_0.png
|
| 471 |
+
ETHZ/eth01/images/image_00000471_0.png
|
| 472 |
+
ETHZ/eth01/images/image_00000472_0.png
|
| 473 |
+
ETHZ/eth01/images/image_00000473_0.png
|
| 474 |
+
ETHZ/eth01/images/image_00000474_0.png
|
| 475 |
+
ETHZ/eth01/images/image_00000475_0.png
|
| 476 |
+
ETHZ/eth01/images/image_00000476_0.png
|
| 477 |
+
ETHZ/eth01/images/image_00000477_0.png
|
| 478 |
+
ETHZ/eth01/images/image_00000478_0.png
|
| 479 |
+
ETHZ/eth01/images/image_00000479_0.png
|
| 480 |
+
ETHZ/eth01/images/image_00000480_0.png
|
| 481 |
+
ETHZ/eth01/images/image_00000481_0.png
|
| 482 |
+
ETHZ/eth01/images/image_00000482_0.png
|
| 483 |
+
ETHZ/eth01/images/image_00000483_0.png
|
| 484 |
+
ETHZ/eth01/images/image_00000484_0.png
|
| 485 |
+
ETHZ/eth01/images/image_00000485_0.png
|
| 486 |
+
ETHZ/eth01/images/image_00000486_0.png
|
| 487 |
+
ETHZ/eth01/images/image_00000487_0.png
|
| 488 |
+
ETHZ/eth01/images/image_00000488_0.png
|
| 489 |
+
ETHZ/eth01/images/image_00000489_0.png
|
| 490 |
+
ETHZ/eth01/images/image_00000490_0.png
|
| 491 |
+
ETHZ/eth01/images/image_00000491_0.png
|
| 492 |
+
ETHZ/eth01/images/image_00000492_0.png
|
| 493 |
+
ETHZ/eth01/images/image_00000493_0.png
|
| 494 |
+
ETHZ/eth01/images/image_00000494_0.png
|
| 495 |
+
ETHZ/eth01/images/image_00000495_0.png
|
| 496 |
+
ETHZ/eth01/images/image_00000496_0.png
|
| 497 |
+
ETHZ/eth01/images/image_00000497_0.png
|
| 498 |
+
ETHZ/eth01/images/image_00000498_0.png
|
| 499 |
+
ETHZ/eth01/images/image_00000499_0.png
|
| 500 |
+
ETHZ/eth01/images/image_00000500_0.png
|
| 501 |
+
ETHZ/eth01/images/image_00000501_0.png
|
| 502 |
+
ETHZ/eth01/images/image_00000502_0.png
|
| 503 |
+
ETHZ/eth01/images/image_00000503_0.png
|
| 504 |
+
ETHZ/eth01/images/image_00000504_0.png
|
| 505 |
+
ETHZ/eth01/images/image_00000505_0.png
|
| 506 |
+
ETHZ/eth01/images/image_00000506_0.png
|
| 507 |
+
ETHZ/eth01/images/image_00000507_0.png
|
| 508 |
+
ETHZ/eth01/images/image_00000508_0.png
|
| 509 |
+
ETHZ/eth01/images/image_00000509_0.png
|
| 510 |
+
ETHZ/eth01/images/image_00000510_0.png
|
| 511 |
+
ETHZ/eth01/images/image_00000511_0.png
|
| 512 |
+
ETHZ/eth01/images/image_00000512_0.png
|
| 513 |
+
ETHZ/eth01/images/image_00000513_0.png
|
| 514 |
+
ETHZ/eth01/images/image_00000514_0.png
|
| 515 |
+
ETHZ/eth01/images/image_00000515_0.png
|
| 516 |
+
ETHZ/eth01/images/image_00000516_0.png
|
| 517 |
+
ETHZ/eth01/images/image_00000517_0.png
|
| 518 |
+
ETHZ/eth01/images/image_00000518_0.png
|
| 519 |
+
ETHZ/eth01/images/image_00000519_0.png
|
| 520 |
+
ETHZ/eth01/images/image_00000520_0.png
|
| 521 |
+
ETHZ/eth01/images/image_00000521_0.png
|
| 522 |
+
ETHZ/eth01/images/image_00000522_0.png
|
| 523 |
+
ETHZ/eth01/images/image_00000523_0.png
|
| 524 |
+
ETHZ/eth01/images/image_00000524_0.png
|
| 525 |
+
ETHZ/eth01/images/image_00000525_0.png
|
| 526 |
+
ETHZ/eth01/images/image_00000526_0.png
|
| 527 |
+
ETHZ/eth01/images/image_00000527_0.png
|
| 528 |
+
ETHZ/eth01/images/image_00000528_0.png
|
| 529 |
+
ETHZ/eth01/images/image_00000529_0.png
|
| 530 |
+
ETHZ/eth01/images/image_00000530_0.png
|
| 531 |
+
ETHZ/eth01/images/image_00000531_0.png
|
| 532 |
+
ETHZ/eth01/images/image_00000532_0.png
|
| 533 |
+
ETHZ/eth01/images/image_00000533_0.png
|
| 534 |
+
ETHZ/eth01/images/image_00000534_0.png
|
| 535 |
+
ETHZ/eth01/images/image_00000535_0.png
|
| 536 |
+
ETHZ/eth01/images/image_00000536_0.png
|
| 537 |
+
ETHZ/eth01/images/image_00000537_0.png
|
| 538 |
+
ETHZ/eth01/images/image_00000538_0.png
|
| 539 |
+
ETHZ/eth01/images/image_00000539_0.png
|
| 540 |
+
ETHZ/eth01/images/image_00000540_0.png
|
| 541 |
+
ETHZ/eth01/images/image_00000541_0.png
|
| 542 |
+
ETHZ/eth01/images/image_00000542_0.png
|
| 543 |
+
ETHZ/eth01/images/image_00000543_0.png
|
| 544 |
+
ETHZ/eth01/images/image_00000544_0.png
|
| 545 |
+
ETHZ/eth01/images/image_00000545_0.png
|
| 546 |
+
ETHZ/eth01/images/image_00000546_0.png
|
| 547 |
+
ETHZ/eth01/images/image_00000547_0.png
|
| 548 |
+
ETHZ/eth01/images/image_00000548_0.png
|
| 549 |
+
ETHZ/eth01/images/image_00000549_0.png
|
| 550 |
+
ETHZ/eth01/images/image_00000550_0.png
|
| 551 |
+
ETHZ/eth01/images/image_00000551_0.png
|
| 552 |
+
ETHZ/eth01/images/image_00000552_0.png
|
| 553 |
+
ETHZ/eth01/images/image_00000553_0.png
|
| 554 |
+
ETHZ/eth01/images/image_00000554_0.png
|
| 555 |
+
ETHZ/eth01/images/image_00000555_0.png
|
| 556 |
+
ETHZ/eth01/images/image_00000556_0.png
|
| 557 |
+
ETHZ/eth01/images/image_00000557_0.png
|
| 558 |
+
ETHZ/eth01/images/image_00000558_0.png
|
| 559 |
+
ETHZ/eth01/images/image_00000559_0.png
|
| 560 |
+
ETHZ/eth01/images/image_00000560_0.png
|
| 561 |
+
ETHZ/eth01/images/image_00000561_0.png
|
| 562 |
+
ETHZ/eth01/images/image_00000562_0.png
|
| 563 |
+
ETHZ/eth01/images/image_00000563_0.png
|
| 564 |
+
ETHZ/eth01/images/image_00000564_0.png
|
| 565 |
+
ETHZ/eth01/images/image_00000565_0.png
|
| 566 |
+
ETHZ/eth01/images/image_00000566_0.png
|
| 567 |
+
ETHZ/eth01/images/image_00000567_0.png
|
| 568 |
+
ETHZ/eth01/images/image_00000568_0.png
|
| 569 |
+
ETHZ/eth01/images/image_00000569_0.png
|
| 570 |
+
ETHZ/eth01/images/image_00000570_0.png
|
| 571 |
+
ETHZ/eth01/images/image_00000571_0.png
|
| 572 |
+
ETHZ/eth01/images/image_00000572_0.png
|
| 573 |
+
ETHZ/eth01/images/image_00000573_0.png
|
| 574 |
+
ETHZ/eth01/images/image_00000574_0.png
|
| 575 |
+
ETHZ/eth01/images/image_00000575_0.png
|
| 576 |
+
ETHZ/eth01/images/image_00000576_0.png
|
| 577 |
+
ETHZ/eth01/images/image_00000577_0.png
|
| 578 |
+
ETHZ/eth01/images/image_00000578_0.png
|
| 579 |
+
ETHZ/eth01/images/image_00000579_0.png
|
| 580 |
+
ETHZ/eth01/images/image_00000580_0.png
|
| 581 |
+
ETHZ/eth01/images/image_00000581_0.png
|
| 582 |
+
ETHZ/eth01/images/image_00000582_0.png
|
| 583 |
+
ETHZ/eth01/images/image_00000583_0.png
|
| 584 |
+
ETHZ/eth01/images/image_00000584_0.png
|
| 585 |
+
ETHZ/eth01/images/image_00000585_0.png
|
| 586 |
+
ETHZ/eth01/images/image_00000586_0.png
|
| 587 |
+
ETHZ/eth01/images/image_00000587_0.png
|
| 588 |
+
ETHZ/eth01/images/image_00000588_0.png
|
| 589 |
+
ETHZ/eth01/images/image_00000589_0.png
|
| 590 |
+
ETHZ/eth01/images/image_00000590_0.png
|
| 591 |
+
ETHZ/eth01/images/image_00000591_0.png
|
| 592 |
+
ETHZ/eth01/images/image_00000592_0.png
|
| 593 |
+
ETHZ/eth01/images/image_00000593_0.png
|
| 594 |
+
ETHZ/eth01/images/image_00000594_0.png
|
| 595 |
+
ETHZ/eth01/images/image_00000595_0.png
|
| 596 |
+
ETHZ/eth01/images/image_00000596_0.png
|
| 597 |
+
ETHZ/eth01/images/image_00000597_0.png
|
| 598 |
+
ETHZ/eth01/images/image_00000598_0.png
|
| 599 |
+
ETHZ/eth01/images/image_00000599_0.png
|
| 600 |
+
ETHZ/eth01/images/image_00000600_0.png
|
| 601 |
+
ETHZ/eth01/images/image_00000601_0.png
|
| 602 |
+
ETHZ/eth01/images/image_00000602_0.png
|
| 603 |
+
ETHZ/eth01/images/image_00000603_0.png
|
| 604 |
+
ETHZ/eth01/images/image_00000604_0.png
|
| 605 |
+
ETHZ/eth01/images/image_00000605_0.png
|
| 606 |
+
ETHZ/eth01/images/image_00000606_0.png
|
| 607 |
+
ETHZ/eth01/images/image_00000607_0.png
|
| 608 |
+
ETHZ/eth01/images/image_00000608_0.png
|
| 609 |
+
ETHZ/eth01/images/image_00000609_0.png
|
| 610 |
+
ETHZ/eth01/images/image_00000610_0.png
|
| 611 |
+
ETHZ/eth01/images/image_00000611_0.png
|
| 612 |
+
ETHZ/eth01/images/image_00000612_0.png
|
| 613 |
+
ETHZ/eth01/images/image_00000613_0.png
|
| 614 |
+
ETHZ/eth01/images/image_00000614_0.png
|
| 615 |
+
ETHZ/eth01/images/image_00000615_0.png
|
| 616 |
+
ETHZ/eth01/images/image_00000616_0.png
|
| 617 |
+
ETHZ/eth01/images/image_00000617_0.png
|
| 618 |
+
ETHZ/eth01/images/image_00000618_0.png
|
| 619 |
+
ETHZ/eth01/images/image_00000619_0.png
|
| 620 |
+
ETHZ/eth01/images/image_00000620_0.png
|
| 621 |
+
ETHZ/eth01/images/image_00000621_0.png
|
| 622 |
+
ETHZ/eth01/images/image_00000622_0.png
|
| 623 |
+
ETHZ/eth01/images/image_00000623_0.png
|
| 624 |
+
ETHZ/eth01/images/image_00000624_0.png
|
| 625 |
+
ETHZ/eth01/images/image_00000625_0.png
|
| 626 |
+
ETHZ/eth01/images/image_00000626_0.png
|
| 627 |
+
ETHZ/eth01/images/image_00000627_0.png
|
| 628 |
+
ETHZ/eth01/images/image_00000628_0.png
|
| 629 |
+
ETHZ/eth01/images/image_00000629_0.png
|
| 630 |
+
ETHZ/eth01/images/image_00000630_0.png
|
| 631 |
+
ETHZ/eth01/images/image_00000631_0.png
|
| 632 |
+
ETHZ/eth01/images/image_00000632_0.png
|
| 633 |
+
ETHZ/eth01/images/image_00000633_0.png
|
| 634 |
+
ETHZ/eth01/images/image_00000634_0.png
|
| 635 |
+
ETHZ/eth01/images/image_00000635_0.png
|
| 636 |
+
ETHZ/eth01/images/image_00000636_0.png
|
| 637 |
+
ETHZ/eth01/images/image_00000637_0.png
|
| 638 |
+
ETHZ/eth01/images/image_00000638_0.png
|
| 639 |
+
ETHZ/eth01/images/image_00000639_0.png
|
| 640 |
+
ETHZ/eth01/images/image_00000640_0.png
|
| 641 |
+
ETHZ/eth01/images/image_00000641_0.png
|
| 642 |
+
ETHZ/eth01/images/image_00000642_0.png
|
| 643 |
+
ETHZ/eth01/images/image_00000643_0.png
|
| 644 |
+
ETHZ/eth01/images/image_00000644_0.png
|
| 645 |
+
ETHZ/eth01/images/image_00000645_0.png
|
| 646 |
+
ETHZ/eth01/images/image_00000646_0.png
|
| 647 |
+
ETHZ/eth01/images/image_00000647_0.png
|
| 648 |
+
ETHZ/eth01/images/image_00000648_0.png
|
| 649 |
+
ETHZ/eth01/images/image_00000649_0.png
|
| 650 |
+
ETHZ/eth01/images/image_00000650_0.png
|
| 651 |
+
ETHZ/eth01/images/image_00000651_0.png
|
| 652 |
+
ETHZ/eth01/images/image_00000652_0.png
|
| 653 |
+
ETHZ/eth01/images/image_00000653_0.png
|
| 654 |
+
ETHZ/eth01/images/image_00000654_0.png
|
| 655 |
+
ETHZ/eth01/images/image_00000655_0.png
|
| 656 |
+
ETHZ/eth01/images/image_00000656_0.png
|
| 657 |
+
ETHZ/eth01/images/image_00000657_0.png
|
| 658 |
+
ETHZ/eth01/images/image_00000658_0.png
|
| 659 |
+
ETHZ/eth01/images/image_00000659_0.png
|
| 660 |
+
ETHZ/eth01/images/image_00000660_0.png
|
| 661 |
+
ETHZ/eth01/images/image_00000661_0.png
|
| 662 |
+
ETHZ/eth01/images/image_00000662_0.png
|
| 663 |
+
ETHZ/eth01/images/image_00000663_0.png
|
| 664 |
+
ETHZ/eth01/images/image_00000664_0.png
|
| 665 |
+
ETHZ/eth01/images/image_00000665_0.png
|
| 666 |
+
ETHZ/eth01/images/image_00000666_0.png
|
| 667 |
+
ETHZ/eth01/images/image_00000667_0.png
|
| 668 |
+
ETHZ/eth01/images/image_00000668_0.png
|
| 669 |
+
ETHZ/eth01/images/image_00000669_0.png
|
| 670 |
+
ETHZ/eth01/images/image_00000670_0.png
|
| 671 |
+
ETHZ/eth01/images/image_00000671_0.png
|
| 672 |
+
ETHZ/eth01/images/image_00000672_0.png
|
| 673 |
+
ETHZ/eth01/images/image_00000673_0.png
|
| 674 |
+
ETHZ/eth01/images/image_00000674_0.png
|
| 675 |
+
ETHZ/eth01/images/image_00000675_0.png
|
| 676 |
+
ETHZ/eth01/images/image_00000676_0.png
|
| 677 |
+
ETHZ/eth01/images/image_00000677_0.png
|
| 678 |
+
ETHZ/eth01/images/image_00000678_0.png
|
| 679 |
+
ETHZ/eth01/images/image_00000679_0.png
|
| 680 |
+
ETHZ/eth01/images/image_00000680_0.png
|
| 681 |
+
ETHZ/eth01/images/image_00000681_0.png
|
| 682 |
+
ETHZ/eth01/images/image_00000682_0.png
|
| 683 |
+
ETHZ/eth01/images/image_00000683_0.png
|
| 684 |
+
ETHZ/eth01/images/image_00000684_0.png
|
| 685 |
+
ETHZ/eth01/images/image_00000685_0.png
|
| 686 |
+
ETHZ/eth01/images/image_00000686_0.png
|
| 687 |
+
ETHZ/eth01/images/image_00000687_0.png
|
| 688 |
+
ETHZ/eth01/images/image_00000688_0.png
|
| 689 |
+
ETHZ/eth01/images/image_00000689_0.png
|
| 690 |
+
ETHZ/eth01/images/image_00000690_0.png
|
| 691 |
+
ETHZ/eth01/images/image_00000691_0.png
|
| 692 |
+
ETHZ/eth01/images/image_00000692_0.png
|
| 693 |
+
ETHZ/eth01/images/image_00000693_0.png
|
| 694 |
+
ETHZ/eth01/images/image_00000694_0.png
|
| 695 |
+
ETHZ/eth01/images/image_00000695_0.png
|
| 696 |
+
ETHZ/eth01/images/image_00000696_0.png
|
| 697 |
+
ETHZ/eth01/images/image_00000697_0.png
|
| 698 |
+
ETHZ/eth01/images/image_00000698_0.png
|
| 699 |
+
ETHZ/eth01/images/image_00000699_0.png
|
| 700 |
+
ETHZ/eth01/images/image_00000700_0.png
|
| 701 |
+
ETHZ/eth01/images/image_00000701_0.png
|
| 702 |
+
ETHZ/eth01/images/image_00000702_0.png
|
| 703 |
+
ETHZ/eth01/images/image_00000703_0.png
|
| 704 |
+
ETHZ/eth01/images/image_00000704_0.png
|
| 705 |
+
ETHZ/eth01/images/image_00000705_0.png
|
| 706 |
+
ETHZ/eth01/images/image_00000706_0.png
|
| 707 |
+
ETHZ/eth01/images/image_00000707_0.png
|
| 708 |
+
ETHZ/eth01/images/image_00000708_0.png
|
| 709 |
+
ETHZ/eth01/images/image_00000709_0.png
|
| 710 |
+
ETHZ/eth01/images/image_00000710_0.png
|
| 711 |
+
ETHZ/eth01/images/image_00000711_0.png
|
| 712 |
+
ETHZ/eth01/images/image_00000712_0.png
|
| 713 |
+
ETHZ/eth01/images/image_00000713_0.png
|
| 714 |
+
ETHZ/eth01/images/image_00000714_0.png
|
| 715 |
+
ETHZ/eth01/images/image_00000715_0.png
|
| 716 |
+
ETHZ/eth01/images/image_00000716_0.png
|
| 717 |
+
ETHZ/eth01/images/image_00000717_0.png
|
| 718 |
+
ETHZ/eth01/images/image_00000718_0.png
|
| 719 |
+
ETHZ/eth01/images/image_00000719_0.png
|
| 720 |
+
ETHZ/eth01/images/image_00000720_0.png
|
| 721 |
+
ETHZ/eth01/images/image_00000721_0.png
|
| 722 |
+
ETHZ/eth01/images/image_00000722_0.png
|
| 723 |
+
ETHZ/eth01/images/image_00000723_0.png
|
| 724 |
+
ETHZ/eth01/images/image_00000724_0.png
|
| 725 |
+
ETHZ/eth01/images/image_00000725_0.png
|
| 726 |
+
ETHZ/eth01/images/image_00000726_0.png
|
| 727 |
+
ETHZ/eth01/images/image_00000727_0.png
|
| 728 |
+
ETHZ/eth01/images/image_00000728_0.png
|
| 729 |
+
ETHZ/eth01/images/image_00000729_0.png
|
| 730 |
+
ETHZ/eth01/images/image_00000730_0.png
|
| 731 |
+
ETHZ/eth01/images/image_00000731_0.png
|
| 732 |
+
ETHZ/eth01/images/image_00000732_0.png
|
| 733 |
+
ETHZ/eth01/images/image_00000733_0.png
|
| 734 |
+
ETHZ/eth01/images/image_00000734_0.png
|
| 735 |
+
ETHZ/eth01/images/image_00000735_0.png
|
| 736 |
+
ETHZ/eth01/images/image_00000736_0.png
|
| 737 |
+
ETHZ/eth01/images/image_00000737_0.png
|
| 738 |
+
ETHZ/eth01/images/image_00000738_0.png
|
| 739 |
+
ETHZ/eth01/images/image_00000739_0.png
|
| 740 |
+
ETHZ/eth01/images/image_00000740_0.png
|
| 741 |
+
ETHZ/eth01/images/image_00000741_0.png
|
| 742 |
+
ETHZ/eth01/images/image_00000742_0.png
|
| 743 |
+
ETHZ/eth01/images/image_00000743_0.png
|
| 744 |
+
ETHZ/eth01/images/image_00000744_0.png
|
| 745 |
+
ETHZ/eth01/images/image_00000745_0.png
|
| 746 |
+
ETHZ/eth01/images/image_00000746_0.png
|
| 747 |
+
ETHZ/eth01/images/image_00000747_0.png
|
| 748 |
+
ETHZ/eth01/images/image_00000748_0.png
|
| 749 |
+
ETHZ/eth01/images/image_00000749_0.png
|
| 750 |
+
ETHZ/eth01/images/image_00000750_0.png
|
| 751 |
+
ETHZ/eth01/images/image_00000751_0.png
|
| 752 |
+
ETHZ/eth01/images/image_00000752_0.png
|
| 753 |
+
ETHZ/eth01/images/image_00000753_0.png
|
| 754 |
+
ETHZ/eth01/images/image_00000754_0.png
|
| 755 |
+
ETHZ/eth01/images/image_00000755_0.png
|
| 756 |
+
ETHZ/eth01/images/image_00000756_0.png
|
| 757 |
+
ETHZ/eth01/images/image_00000757_0.png
|
| 758 |
+
ETHZ/eth01/images/image_00000758_0.png
|
| 759 |
+
ETHZ/eth01/images/image_00000759_0.png
|
| 760 |
+
ETHZ/eth01/images/image_00000760_0.png
|
| 761 |
+
ETHZ/eth01/images/image_00000761_0.png
|
| 762 |
+
ETHZ/eth01/images/image_00000762_0.png
|
| 763 |
+
ETHZ/eth01/images/image_00000763_0.png
|
| 764 |
+
ETHZ/eth01/images/image_00000764_0.png
|
| 765 |
+
ETHZ/eth01/images/image_00000765_0.png
|
| 766 |
+
ETHZ/eth01/images/image_00000766_0.png
|
| 767 |
+
ETHZ/eth01/images/image_00000767_0.png
|
| 768 |
+
ETHZ/eth01/images/image_00000768_0.png
|
| 769 |
+
ETHZ/eth01/images/image_00000769_0.png
|
| 770 |
+
ETHZ/eth01/images/image_00000770_0.png
|
| 771 |
+
ETHZ/eth01/images/image_00000771_0.png
|
| 772 |
+
ETHZ/eth01/images/image_00000772_0.png
|
| 773 |
+
ETHZ/eth01/images/image_00000773_0.png
|
| 774 |
+
ETHZ/eth01/images/image_00000774_0.png
|
| 775 |
+
ETHZ/eth01/images/image_00000775_0.png
|
| 776 |
+
ETHZ/eth01/images/image_00000776_0.png
|
| 777 |
+
ETHZ/eth01/images/image_00000777_0.png
|
| 778 |
+
ETHZ/eth01/images/image_00000778_0.png
|
| 779 |
+
ETHZ/eth01/images/image_00000779_0.png
|
| 780 |
+
ETHZ/eth01/images/image_00000780_0.png
|
| 781 |
+
ETHZ/eth01/images/image_00000781_0.png
|
| 782 |
+
ETHZ/eth01/images/image_00000782_0.png
|
| 783 |
+
ETHZ/eth01/images/image_00000783_0.png
|
| 784 |
+
ETHZ/eth01/images/image_00000784_0.png
|
| 785 |
+
ETHZ/eth01/images/image_00000785_0.png
|
| 786 |
+
ETHZ/eth01/images/image_00000786_0.png
|
| 787 |
+
ETHZ/eth01/images/image_00000787_0.png
|
| 788 |
+
ETHZ/eth01/images/image_00000788_0.png
|
| 789 |
+
ETHZ/eth01/images/image_00000789_0.png
|
| 790 |
+
ETHZ/eth01/images/image_00000790_0.png
|
| 791 |
+
ETHZ/eth01/images/image_00000791_0.png
|
| 792 |
+
ETHZ/eth01/images/image_00000792_0.png
|
| 793 |
+
ETHZ/eth01/images/image_00000793_0.png
|
| 794 |
+
ETHZ/eth01/images/image_00000794_0.png
|
| 795 |
+
ETHZ/eth01/images/image_00000795_0.png
|
| 796 |
+
ETHZ/eth01/images/image_00000796_0.png
|
| 797 |
+
ETHZ/eth01/images/image_00000797_0.png
|
| 798 |
+
ETHZ/eth01/images/image_00000798_0.png
|
| 799 |
+
ETHZ/eth01/images/image_00000799_0.png
|
| 800 |
+
ETHZ/eth01/images/image_00000800_0.png
|
| 801 |
+
ETHZ/eth01/images/image_00000801_0.png
|
| 802 |
+
ETHZ/eth01/images/image_00000802_0.png
|
| 803 |
+
ETHZ/eth01/images/image_00000803_0.png
|
| 804 |
+
ETHZ/eth01/images/image_00000804_0.png
|
| 805 |
+
ETHZ/eth01/images/image_00000805_0.png
|
| 806 |
+
ETHZ/eth01/images/image_00000806_0.png
|
| 807 |
+
ETHZ/eth01/images/image_00000807_0.png
|
| 808 |
+
ETHZ/eth01/images/image_00000808_0.png
|
| 809 |
+
ETHZ/eth01/images/image_00000809_0.png
|
| 810 |
+
ETHZ/eth01/images/image_00000810_0.png
|
| 811 |
+
ETHZ/eth01/images/image_00000811_0.png
|
| 812 |
+
ETHZ/eth01/images/image_00000812_0.png
|
| 813 |
+
ETHZ/eth01/images/image_00000813_0.png
|
| 814 |
+
ETHZ/eth01/images/image_00000814_0.png
|
| 815 |
+
ETHZ/eth01/images/image_00000815_0.png
|
| 816 |
+
ETHZ/eth01/images/image_00000816_0.png
|
| 817 |
+
ETHZ/eth01/images/image_00000817_0.png
|
| 818 |
+
ETHZ/eth01/images/image_00000818_0.png
|
| 819 |
+
ETHZ/eth01/images/image_00000819_0.png
|
| 820 |
+
ETHZ/eth01/images/image_00000820_0.png
|
| 821 |
+
ETHZ/eth01/images/image_00000821_0.png
|
| 822 |
+
ETHZ/eth01/images/image_00000822_0.png
|
| 823 |
+
ETHZ/eth01/images/image_00000823_0.png
|
| 824 |
+
ETHZ/eth01/images/image_00000824_0.png
|
| 825 |
+
ETHZ/eth01/images/image_00000825_0.png
|
| 826 |
+
ETHZ/eth01/images/image_00000826_0.png
|
| 827 |
+
ETHZ/eth01/images/image_00000827_0.png
|
| 828 |
+
ETHZ/eth01/images/image_00000828_0.png
|
| 829 |
+
ETHZ/eth01/images/image_00000829_0.png
|
| 830 |
+
ETHZ/eth01/images/image_00000830_0.png
|
| 831 |
+
ETHZ/eth01/images/image_00000831_0.png
|
| 832 |
+
ETHZ/eth01/images/image_00000832_0.png
|
| 833 |
+
ETHZ/eth01/images/image_00000833_0.png
|
| 834 |
+
ETHZ/eth01/images/image_00000834_0.png
|
| 835 |
+
ETHZ/eth01/images/image_00000835_0.png
|
| 836 |
+
ETHZ/eth01/images/image_00000836_0.png
|
| 837 |
+
ETHZ/eth01/images/image_00000837_0.png
|
| 838 |
+
ETHZ/eth01/images/image_00000838_0.png
|
| 839 |
+
ETHZ/eth01/images/image_00000839_0.png
|
| 840 |
+
ETHZ/eth01/images/image_00000840_0.png
|
| 841 |
+
ETHZ/eth01/images/image_00000841_0.png
|
| 842 |
+
ETHZ/eth01/images/image_00000842_0.png
|
| 843 |
+
ETHZ/eth01/images/image_00000843_0.png
|
| 844 |
+
ETHZ/eth01/images/image_00000844_0.png
|
| 845 |
+
ETHZ/eth01/images/image_00000845_0.png
|
| 846 |
+
ETHZ/eth01/images/image_00000846_0.png
|
| 847 |
+
ETHZ/eth01/images/image_00000847_0.png
|
| 848 |
+
ETHZ/eth01/images/image_00000848_0.png
|
| 849 |
+
ETHZ/eth01/images/image_00000849_0.png
|
| 850 |
+
ETHZ/eth01/images/image_00000850_0.png
|
| 851 |
+
ETHZ/eth01/images/image_00000851_0.png
|
| 852 |
+
ETHZ/eth01/images/image_00000852_0.png
|
| 853 |
+
ETHZ/eth01/images/image_00000853_0.png
|
| 854 |
+
ETHZ/eth01/images/image_00000854_0.png
|
| 855 |
+
ETHZ/eth01/images/image_00000855_0.png
|
| 856 |
+
ETHZ/eth01/images/image_00000856_0.png
|
| 857 |
+
ETHZ/eth01/images/image_00000857_0.png
|
| 858 |
+
ETHZ/eth01/images/image_00000858_0.png
|
| 859 |
+
ETHZ/eth01/images/image_00000859_0.png
|
| 860 |
+
ETHZ/eth01/images/image_00000860_0.png
|
| 861 |
+
ETHZ/eth01/images/image_00000861_0.png
|
| 862 |
+
ETHZ/eth01/images/image_00000862_0.png
|
| 863 |
+
ETHZ/eth01/images/image_00000863_0.png
|
| 864 |
+
ETHZ/eth01/images/image_00000864_0.png
|
| 865 |
+
ETHZ/eth01/images/image_00000865_0.png
|
| 866 |
+
ETHZ/eth01/images/image_00000866_0.png
|
| 867 |
+
ETHZ/eth01/images/image_00000867_0.png
|
| 868 |
+
ETHZ/eth01/images/image_00000868_0.png
|
| 869 |
+
ETHZ/eth01/images/image_00000869_0.png
|
| 870 |
+
ETHZ/eth01/images/image_00000870_0.png
|
| 871 |
+
ETHZ/eth01/images/image_00000871_0.png
|
| 872 |
+
ETHZ/eth01/images/image_00000872_0.png
|
| 873 |
+
ETHZ/eth01/images/image_00000873_0.png
|
| 874 |
+
ETHZ/eth01/images/image_00000874_0.png
|
| 875 |
+
ETHZ/eth01/images/image_00000875_0.png
|
| 876 |
+
ETHZ/eth01/images/image_00000876_0.png
|
| 877 |
+
ETHZ/eth01/images/image_00000877_0.png
|
| 878 |
+
ETHZ/eth01/images/image_00000878_0.png
|
| 879 |
+
ETHZ/eth01/images/image_00000879_0.png
|
| 880 |
+
ETHZ/eth01/images/image_00000880_0.png
|
| 881 |
+
ETHZ/eth01/images/image_00000881_0.png
|
| 882 |
+
ETHZ/eth01/images/image_00000882_0.png
|
| 883 |
+
ETHZ/eth01/images/image_00000883_0.png
|
| 884 |
+
ETHZ/eth01/images/image_00000884_0.png
|
| 885 |
+
ETHZ/eth01/images/image_00000885_0.png
|
| 886 |
+
ETHZ/eth01/images/image_00000886_0.png
|
| 887 |
+
ETHZ/eth01/images/image_00000887_0.png
|
| 888 |
+
ETHZ/eth01/images/image_00000888_0.png
|
| 889 |
+
ETHZ/eth01/images/image_00000889_0.png
|
| 890 |
+
ETHZ/eth01/images/image_00000890_0.png
|
| 891 |
+
ETHZ/eth01/images/image_00000891_0.png
|
| 892 |
+
ETHZ/eth01/images/image_00000892_0.png
|
| 893 |
+
ETHZ/eth01/images/image_00000893_0.png
|
| 894 |
+
ETHZ/eth01/images/image_00000894_0.png
|
| 895 |
+
ETHZ/eth01/images/image_00000895_0.png
|
| 896 |
+
ETHZ/eth01/images/image_00000896_0.png
|
| 897 |
+
ETHZ/eth01/images/image_00000897_0.png
|
| 898 |
+
ETHZ/eth01/images/image_00000898_0.png
|
| 899 |
+
ETHZ/eth01/images/image_00000899_0.png
|
| 900 |
+
ETHZ/eth01/images/image_00000900_0.png
|
| 901 |
+
ETHZ/eth01/images/image_00000901_0.png
|
| 902 |
+
ETHZ/eth01/images/image_00000902_0.png
|
| 903 |
+
ETHZ/eth01/images/image_00000903_0.png
|
| 904 |
+
ETHZ/eth01/images/image_00000904_0.png
|
| 905 |
+
ETHZ/eth01/images/image_00000905_0.png
|
| 906 |
+
ETHZ/eth01/images/image_00000906_0.png
|
| 907 |
+
ETHZ/eth01/images/image_00000907_0.png
|
| 908 |
+
ETHZ/eth01/images/image_00000908_0.png
|
| 909 |
+
ETHZ/eth01/images/image_00000909_0.png
|
| 910 |
+
ETHZ/eth01/images/image_00000910_0.png
|
| 911 |
+
ETHZ/eth01/images/image_00000911_0.png
|
| 912 |
+
ETHZ/eth01/images/image_00000912_0.png
|
| 913 |
+
ETHZ/eth01/images/image_00000913_0.png
|
| 914 |
+
ETHZ/eth01/images/image_00000914_0.png
|
| 915 |
+
ETHZ/eth01/images/image_00000915_0.png
|
| 916 |
+
ETHZ/eth01/images/image_00000916_0.png
|
| 917 |
+
ETHZ/eth01/images/image_00000917_0.png
|
| 918 |
+
ETHZ/eth01/images/image_00000918_0.png
|
| 919 |
+
ETHZ/eth01/images/image_00000919_0.png
|
| 920 |
+
ETHZ/eth01/images/image_00000920_0.png
|
| 921 |
+
ETHZ/eth01/images/image_00000921_0.png
|
| 922 |
+
ETHZ/eth01/images/image_00000922_0.png
|
| 923 |
+
ETHZ/eth01/images/image_00000923_0.png
|
| 924 |
+
ETHZ/eth01/images/image_00000924_0.png
|
| 925 |
+
ETHZ/eth01/images/image_00000925_0.png
|
| 926 |
+
ETHZ/eth01/images/image_00000926_0.png
|
| 927 |
+
ETHZ/eth01/images/image_00000927_0.png
|
| 928 |
+
ETHZ/eth01/images/image_00000928_0.png
|
| 929 |
+
ETHZ/eth01/images/image_00000929_0.png
|
| 930 |
+
ETHZ/eth01/images/image_00000930_0.png
|
| 931 |
+
ETHZ/eth01/images/image_00000931_0.png
|
| 932 |
+
ETHZ/eth01/images/image_00000932_0.png
|
| 933 |
+
ETHZ/eth01/images/image_00000933_0.png
|
| 934 |
+
ETHZ/eth01/images/image_00000934_0.png
|
| 935 |
+
ETHZ/eth01/images/image_00000935_0.png
|
| 936 |
+
ETHZ/eth01/images/image_00000936_0.png
|
| 937 |
+
ETHZ/eth01/images/image_00000937_0.png
|
| 938 |
+
ETHZ/eth01/images/image_00000938_0.png
|
| 939 |
+
ETHZ/eth01/images/image_00000939_0.png
|
| 940 |
+
ETHZ/eth01/images/image_00000940_0.png
|
| 941 |
+
ETHZ/eth01/images/image_00000941_0.png
|
| 942 |
+
ETHZ/eth01/images/image_00000942_0.png
|
| 943 |
+
ETHZ/eth01/images/image_00000943_0.png
|
| 944 |
+
ETHZ/eth01/images/image_00000944_0.png
|
| 945 |
+
ETHZ/eth01/images/image_00000945_0.png
|
| 946 |
+
ETHZ/eth01/images/image_00000946_0.png
|
| 947 |
+
ETHZ/eth01/images/image_00000947_0.png
|
| 948 |
+
ETHZ/eth01/images/image_00000948_0.png
|
| 949 |
+
ETHZ/eth01/images/image_00000949_0.png
|
| 950 |
+
ETHZ/eth01/images/image_00000950_0.png
|
| 951 |
+
ETHZ/eth01/images/image_00000951_0.png
|
| 952 |
+
ETHZ/eth01/images/image_00000952_0.png
|
| 953 |
+
ETHZ/eth01/images/image_00000953_0.png
|
| 954 |
+
ETHZ/eth01/images/image_00000954_0.png
|
| 955 |
+
ETHZ/eth01/images/image_00000955_0.png
|
| 956 |
+
ETHZ/eth01/images/image_00000956_0.png
|
| 957 |
+
ETHZ/eth01/images/image_00000957_0.png
|
| 958 |
+
ETHZ/eth01/images/image_00000958_0.png
|
| 959 |
+
ETHZ/eth01/images/image_00000959_0.png
|
| 960 |
+
ETHZ/eth01/images/image_00000960_0.png
|
| 961 |
+
ETHZ/eth01/images/image_00000961_0.png
|
| 962 |
+
ETHZ/eth01/images/image_00000962_0.png
|
| 963 |
+
ETHZ/eth01/images/image_00000963_0.png
|
| 964 |
+
ETHZ/eth01/images/image_00000964_0.png
|
| 965 |
+
ETHZ/eth01/images/image_00000965_0.png
|
| 966 |
+
ETHZ/eth01/images/image_00000966_0.png
|
| 967 |
+
ETHZ/eth01/images/image_00000967_0.png
|
| 968 |
+
ETHZ/eth01/images/image_00000968_0.png
|
| 969 |
+
ETHZ/eth01/images/image_00000969_0.png
|
| 970 |
+
ETHZ/eth01/images/image_00000970_0.png
|
| 971 |
+
ETHZ/eth01/images/image_00000971_0.png
|
| 972 |
+
ETHZ/eth01/images/image_00000972_0.png
|
| 973 |
+
ETHZ/eth01/images/image_00000973_0.png
|
| 974 |
+
ETHZ/eth01/images/image_00000974_0.png
|
| 975 |
+
ETHZ/eth01/images/image_00000975_0.png
|
| 976 |
+
ETHZ/eth01/images/image_00000976_0.png
|
| 977 |
+
ETHZ/eth01/images/image_00000977_0.png
|
| 978 |
+
ETHZ/eth01/images/image_00000978_0.png
|
| 979 |
+
ETHZ/eth01/images/image_00000979_0.png
|
| 980 |
+
ETHZ/eth01/images/image_00000980_0.png
|
| 981 |
+
ETHZ/eth01/images/image_00000981_0.png
|
| 982 |
+
ETHZ/eth01/images/image_00000982_0.png
|
| 983 |
+
ETHZ/eth01/images/image_00000983_0.png
|
| 984 |
+
ETHZ/eth01/images/image_00000984_0.png
|
| 985 |
+
ETHZ/eth01/images/image_00000985_0.png
|
| 986 |
+
ETHZ/eth01/images/image_00000986_0.png
|
| 987 |
+
ETHZ/eth01/images/image_00000987_0.png
|
| 988 |
+
ETHZ/eth01/images/image_00000988_0.png
|
| 989 |
+
ETHZ/eth01/images/image_00000989_0.png
|
| 990 |
+
ETHZ/eth01/images/image_00000990_0.png
|
| 991 |
+
ETHZ/eth01/images/image_00000991_0.png
|
| 992 |
+
ETHZ/eth01/images/image_00000992_0.png
|
| 993 |
+
ETHZ/eth01/images/image_00000993_0.png
|
| 994 |
+
ETHZ/eth01/images/image_00000994_0.png
|
| 995 |
+
ETHZ/eth01/images/image_00000995_0.png
|
| 996 |
+
ETHZ/eth01/images/image_00000996_0.png
|
| 997 |
+
ETHZ/eth01/images/image_00000997_0.png
|
| 998 |
+
ETHZ/eth01/images/image_00000998_0.png
|
| 999 |
+
ETHZ/eth01/images/image_00000999_0.png
|
| 1000 |
+
ETHZ/eth02/images/image_00000000_0.png
|
| 1001 |
+
ETHZ/eth02/images/image_00000001_0.png
|
| 1002 |
+
ETHZ/eth02/images/image_00000002_0.png
|
| 1003 |
+
ETHZ/eth02/images/image_00000003_0.png
|
| 1004 |
+
ETHZ/eth02/images/image_00000004_0.png
|
| 1005 |
+
ETHZ/eth02/images/image_00000005_0.png
|
| 1006 |
+
ETHZ/eth02/images/image_00000006_0.png
|
| 1007 |
+
ETHZ/eth02/images/image_00000007_0.png
|
| 1008 |
+
ETHZ/eth02/images/image_00000008_0.png
|
| 1009 |
+
ETHZ/eth02/images/image_00000009_0.png
|
| 1010 |
+
ETHZ/eth02/images/image_00000010_0.png
|
| 1011 |
+
ETHZ/eth02/images/image_00000011_0.png
|
| 1012 |
+
ETHZ/eth02/images/image_00000012_0.png
|
| 1013 |
+
ETHZ/eth02/images/image_00000013_0.png
|
| 1014 |
+
ETHZ/eth02/images/image_00000014_0.png
|
| 1015 |
+
ETHZ/eth02/images/image_00000015_0.png
|
| 1016 |
+
ETHZ/eth02/images/image_00000016_0.png
|
| 1017 |
+
ETHZ/eth02/images/image_00000017_0.png
|
| 1018 |
+
ETHZ/eth02/images/image_00000018_0.png
|
| 1019 |
+
ETHZ/eth02/images/image_00000019_0.png
|
| 1020 |
+
ETHZ/eth02/images/image_00000020_0.png
|
| 1021 |
+
ETHZ/eth02/images/image_00000021_0.png
|
| 1022 |
+
ETHZ/eth02/images/image_00000022_0.png
|
| 1023 |
+
ETHZ/eth02/images/image_00000023_0.png
|
| 1024 |
+
ETHZ/eth02/images/image_00000024_0.png
|
| 1025 |
+
ETHZ/eth02/images/image_00000025_0.png
|
| 1026 |
+
ETHZ/eth02/images/image_00000026_0.png
|
| 1027 |
+
ETHZ/eth02/images/image_00000027_0.png
|
| 1028 |
+
ETHZ/eth02/images/image_00000028_0.png
|
| 1029 |
+
ETHZ/eth02/images/image_00000029_0.png
|
| 1030 |
+
ETHZ/eth02/images/image_00000030_0.png
|
| 1031 |
+
ETHZ/eth02/images/image_00000031_0.png
|
| 1032 |
+
ETHZ/eth02/images/image_00000032_0.png
|
| 1033 |
+
ETHZ/eth02/images/image_00000033_0.png
|
| 1034 |
+
ETHZ/eth02/images/image_00000034_0.png
|
| 1035 |
+
ETHZ/eth02/images/image_00000035_0.png
|
| 1036 |
+
ETHZ/eth02/images/image_00000036_0.png
|
| 1037 |
+
ETHZ/eth02/images/image_00000037_0.png
|
| 1038 |
+
ETHZ/eth02/images/image_00000038_0.png
|
| 1039 |
+
ETHZ/eth02/images/image_00000039_0.png
|
| 1040 |
+
ETHZ/eth02/images/image_00000040_0.png
|
| 1041 |
+
ETHZ/eth02/images/image_00000041_0.png
|
| 1042 |
+
ETHZ/eth02/images/image_00000042_0.png
|
| 1043 |
+
ETHZ/eth02/images/image_00000043_0.png
|
| 1044 |
+
ETHZ/eth02/images/image_00000044_0.png
|
| 1045 |
+
ETHZ/eth02/images/image_00000045_0.png
|
| 1046 |
+
ETHZ/eth02/images/image_00000046_0.png
|
| 1047 |
+
ETHZ/eth02/images/image_00000047_0.png
|
| 1048 |
+
ETHZ/eth02/images/image_00000048_0.png
|
| 1049 |
+
ETHZ/eth02/images/image_00000049_0.png
|
| 1050 |
+
ETHZ/eth02/images/image_00000050_0.png
|
| 1051 |
+
ETHZ/eth02/images/image_00000051_0.png
|
| 1052 |
+
ETHZ/eth02/images/image_00000052_0.png
|
| 1053 |
+
ETHZ/eth02/images/image_00000053_0.png
|
| 1054 |
+
ETHZ/eth02/images/image_00000054_0.png
|
| 1055 |
+
ETHZ/eth02/images/image_00000055_0.png
|
| 1056 |
+
ETHZ/eth02/images/image_00000056_0.png
|
| 1057 |
+
ETHZ/eth02/images/image_00000057_0.png
|
| 1058 |
+
ETHZ/eth02/images/image_00000058_0.png
|
| 1059 |
+
ETHZ/eth02/images/image_00000059_0.png
|
| 1060 |
+
ETHZ/eth02/images/image_00000060_0.png
|
| 1061 |
+
ETHZ/eth02/images/image_00000061_0.png
|
| 1062 |
+
ETHZ/eth02/images/image_00000062_0.png
|
| 1063 |
+
ETHZ/eth02/images/image_00000063_0.png
|
| 1064 |
+
ETHZ/eth02/images/image_00000064_0.png
|
| 1065 |
+
ETHZ/eth02/images/image_00000065_0.png
|
| 1066 |
+
ETHZ/eth02/images/image_00000066_0.png
|
| 1067 |
+
ETHZ/eth02/images/image_00000067_0.png
|
| 1068 |
+
ETHZ/eth02/images/image_00000068_0.png
|
| 1069 |
+
ETHZ/eth02/images/image_00000069_0.png
|
| 1070 |
+
ETHZ/eth02/images/image_00000070_0.png
|
| 1071 |
+
ETHZ/eth02/images/image_00000071_0.png
|
| 1072 |
+
ETHZ/eth02/images/image_00000072_0.png
|
| 1073 |
+
ETHZ/eth02/images/image_00000073_0.png
|
| 1074 |
+
ETHZ/eth02/images/image_00000074_0.png
|
| 1075 |
+
ETHZ/eth02/images/image_00000075_0.png
|
| 1076 |
+
ETHZ/eth02/images/image_00000076_0.png
|
| 1077 |
+
ETHZ/eth02/images/image_00000077_0.png
|
| 1078 |
+
ETHZ/eth02/images/image_00000078_0.png
|
| 1079 |
+
ETHZ/eth02/images/image_00000079_0.png
|
| 1080 |
+
ETHZ/eth02/images/image_00000080_0.png
|
| 1081 |
+
ETHZ/eth02/images/image_00000081_0.png
|
| 1082 |
+
ETHZ/eth02/images/image_00000082_0.png
|
| 1083 |
+
ETHZ/eth02/images/image_00000083_0.png
|
| 1084 |
+
ETHZ/eth02/images/image_00000084_0.png
|
| 1085 |
+
ETHZ/eth02/images/image_00000085_0.png
|
| 1086 |
+
ETHZ/eth02/images/image_00000086_0.png
|
| 1087 |
+
ETHZ/eth02/images/image_00000087_0.png
|
| 1088 |
+
ETHZ/eth02/images/image_00000088_0.png
|
| 1089 |
+
ETHZ/eth02/images/image_00000089_0.png
|
| 1090 |
+
ETHZ/eth02/images/image_00000090_0.png
|
| 1091 |
+
ETHZ/eth02/images/image_00000091_0.png
|
| 1092 |
+
ETHZ/eth02/images/image_00000092_0.png
|
| 1093 |
+
ETHZ/eth02/images/image_00000093_0.png
|
| 1094 |
+
ETHZ/eth02/images/image_00000094_0.png
|
| 1095 |
+
ETHZ/eth02/images/image_00000095_0.png
|
| 1096 |
+
ETHZ/eth02/images/image_00000096_0.png
|
| 1097 |
+
ETHZ/eth02/images/image_00000097_0.png
|
| 1098 |
+
ETHZ/eth02/images/image_00000098_0.png
|
| 1099 |
+
ETHZ/eth02/images/image_00000099_0.png
|
| 1100 |
+
ETHZ/eth02/images/image_00000100_0.png
|
| 1101 |
+
ETHZ/eth02/images/image_00000101_0.png
|
| 1102 |
+
ETHZ/eth02/images/image_00000102_0.png
|
| 1103 |
+
ETHZ/eth02/images/image_00000103_0.png
|
| 1104 |
+
ETHZ/eth02/images/image_00000104_0.png
|
| 1105 |
+
ETHZ/eth02/images/image_00000105_0.png
|
| 1106 |
+
ETHZ/eth02/images/image_00000106_0.png
|
| 1107 |
+
ETHZ/eth02/images/image_00000107_0.png
|
| 1108 |
+
ETHZ/eth02/images/image_00000108_0.png
|
| 1109 |
+
ETHZ/eth02/images/image_00000109_0.png
|
| 1110 |
+
ETHZ/eth02/images/image_00000110_0.png
|
| 1111 |
+
ETHZ/eth02/images/image_00000111_0.png
|
| 1112 |
+
ETHZ/eth02/images/image_00000112_0.png
|
| 1113 |
+
ETHZ/eth02/images/image_00000113_0.png
|
| 1114 |
+
ETHZ/eth02/images/image_00000114_0.png
|
| 1115 |
+
ETHZ/eth02/images/image_00000115_0.png
|
| 1116 |
+
ETHZ/eth02/images/image_00000116_0.png
|
| 1117 |
+
ETHZ/eth02/images/image_00000117_0.png
|
| 1118 |
+
ETHZ/eth02/images/image_00000118_0.png
|
| 1119 |
+
ETHZ/eth02/images/image_00000119_0.png
|
| 1120 |
+
ETHZ/eth02/images/image_00000120_0.png
|
| 1121 |
+
ETHZ/eth02/images/image_00000121_0.png
|
| 1122 |
+
ETHZ/eth02/images/image_00000122_0.png
|
| 1123 |
+
ETHZ/eth02/images/image_00000123_0.png
|
| 1124 |
+
ETHZ/eth02/images/image_00000124_0.png
|
| 1125 |
+
ETHZ/eth02/images/image_00000125_0.png
|
| 1126 |
+
ETHZ/eth02/images/image_00000126_0.png
|
| 1127 |
+
ETHZ/eth02/images/image_00000127_0.png
|
| 1128 |
+
ETHZ/eth02/images/image_00000128_0.png
|
| 1129 |
+
ETHZ/eth02/images/image_00000129_0.png
|
| 1130 |
+
ETHZ/eth02/images/image_00000130_0.png
|
| 1131 |
+
ETHZ/eth02/images/image_00000131_0.png
|
| 1132 |
+
ETHZ/eth02/images/image_00000132_0.png
|
| 1133 |
+
ETHZ/eth02/images/image_00000133_0.png
|
| 1134 |
+
ETHZ/eth02/images/image_00000134_0.png
|
| 1135 |
+
ETHZ/eth02/images/image_00000135_0.png
|
| 1136 |
+
ETHZ/eth02/images/image_00000136_0.png
|
| 1137 |
+
ETHZ/eth02/images/image_00000137_0.png
|
| 1138 |
+
ETHZ/eth02/images/image_00000138_0.png
|
| 1139 |
+
ETHZ/eth02/images/image_00000139_0.png
|
| 1140 |
+
ETHZ/eth02/images/image_00000140_0.png
|
| 1141 |
+
ETHZ/eth02/images/image_00000141_0.png
|
| 1142 |
+
ETHZ/eth02/images/image_00000142_0.png
|
| 1143 |
+
ETHZ/eth02/images/image_00000143_0.png
|
| 1144 |
+
ETHZ/eth02/images/image_00000144_0.png
|
| 1145 |
+
ETHZ/eth02/images/image_00000145_0.png
|
| 1146 |
+
ETHZ/eth02/images/image_00000146_0.png
|
| 1147 |
+
ETHZ/eth02/images/image_00000147_0.png
|
| 1148 |
+
ETHZ/eth02/images/image_00000148_0.png
|
| 1149 |
+
ETHZ/eth02/images/image_00000149_0.png
|
| 1150 |
+
ETHZ/eth02/images/image_00000150_0.png
|
| 1151 |
+
ETHZ/eth02/images/image_00000151_0.png
|
| 1152 |
+
ETHZ/eth02/images/image_00000152_0.png
|
| 1153 |
+
ETHZ/eth02/images/image_00000153_0.png
|
| 1154 |
+
ETHZ/eth02/images/image_00000154_0.png
|
| 1155 |
+
ETHZ/eth02/images/image_00000155_0.png
|
| 1156 |
+
ETHZ/eth02/images/image_00000156_0.png
|
| 1157 |
+
ETHZ/eth02/images/image_00000157_0.png
|
| 1158 |
+
ETHZ/eth02/images/image_00000158_0.png
|
| 1159 |
+
ETHZ/eth02/images/image_00000159_0.png
|
| 1160 |
+
ETHZ/eth02/images/image_00000160_0.png
|
| 1161 |
+
ETHZ/eth02/images/image_00000161_0.png
|
| 1162 |
+
ETHZ/eth02/images/image_00000162_0.png
|
| 1163 |
+
ETHZ/eth02/images/image_00000163_0.png
|
| 1164 |
+
ETHZ/eth02/images/image_00000164_0.png
|
| 1165 |
+
ETHZ/eth02/images/image_00000165_0.png
|
| 1166 |
+
ETHZ/eth02/images/image_00000166_0.png
|
| 1167 |
+
ETHZ/eth02/images/image_00000167_0.png
|
| 1168 |
+
ETHZ/eth02/images/image_00000168_0.png
|
| 1169 |
+
ETHZ/eth02/images/image_00000169_0.png
|
| 1170 |
+
ETHZ/eth02/images/image_00000170_0.png
|
| 1171 |
+
ETHZ/eth02/images/image_00000171_0.png
|
| 1172 |
+
ETHZ/eth02/images/image_00000172_0.png
|
| 1173 |
+
ETHZ/eth02/images/image_00000173_0.png
|
| 1174 |
+
ETHZ/eth02/images/image_00000174_0.png
|
| 1175 |
+
ETHZ/eth02/images/image_00000175_0.png
|
| 1176 |
+
ETHZ/eth02/images/image_00000176_0.png
|
| 1177 |
+
ETHZ/eth02/images/image_00000177_0.png
|
| 1178 |
+
ETHZ/eth02/images/image_00000178_0.png
|
| 1179 |
+
ETHZ/eth02/images/image_00000179_0.png
|
| 1180 |
+
ETHZ/eth02/images/image_00000180_0.png
|
| 1181 |
+
ETHZ/eth02/images/image_00000181_0.png
|
| 1182 |
+
ETHZ/eth02/images/image_00000182_0.png
|
| 1183 |
+
ETHZ/eth02/images/image_00000183_0.png
|
| 1184 |
+
ETHZ/eth02/images/image_00000184_0.png
|
| 1185 |
+
ETHZ/eth02/images/image_00000185_0.png
|
| 1186 |
+
ETHZ/eth02/images/image_00000186_0.png
|
| 1187 |
+
ETHZ/eth02/images/image_00000187_0.png
|
| 1188 |
+
ETHZ/eth02/images/image_00000188_0.png
|
| 1189 |
+
ETHZ/eth02/images/image_00000189_0.png
|
| 1190 |
+
ETHZ/eth02/images/image_00000190_0.png
|
| 1191 |
+
ETHZ/eth02/images/image_00000191_0.png
|
| 1192 |
+
ETHZ/eth02/images/image_00000192_0.png
|
| 1193 |
+
ETHZ/eth02/images/image_00000193_0.png
|
| 1194 |
+
ETHZ/eth02/images/image_00000194_0.png
|
| 1195 |
+
ETHZ/eth02/images/image_00000195_0.png
|
| 1196 |
+
ETHZ/eth02/images/image_00000196_0.png
|
| 1197 |
+
ETHZ/eth02/images/image_00000197_0.png
|
| 1198 |
+
ETHZ/eth02/images/image_00000198_0.png
|
| 1199 |
+
ETHZ/eth02/images/image_00000199_0.png
|
| 1200 |
+
ETHZ/eth02/images/image_00000200_0.png
|
| 1201 |
+
ETHZ/eth02/images/image_00000201_0.png
|
| 1202 |
+
ETHZ/eth02/images/image_00000202_0.png
|
| 1203 |
+
ETHZ/eth02/images/image_00000203_0.png
|
| 1204 |
+
ETHZ/eth02/images/image_00000204_0.png
|
| 1205 |
+
ETHZ/eth02/images/image_00000205_0.png
|
| 1206 |
+
ETHZ/eth02/images/image_00000206_0.png
|
| 1207 |
+
ETHZ/eth02/images/image_00000207_0.png
|
| 1208 |
+
ETHZ/eth02/images/image_00000208_0.png
|
| 1209 |
+
ETHZ/eth02/images/image_00000209_0.png
|
| 1210 |
+
ETHZ/eth02/images/image_00000210_0.png
|
| 1211 |
+
ETHZ/eth02/images/image_00000211_0.png
|
| 1212 |
+
ETHZ/eth02/images/image_00000212_0.png
|
| 1213 |
+
ETHZ/eth02/images/image_00000213_0.png
|
| 1214 |
+
ETHZ/eth02/images/image_00000214_0.png
|
| 1215 |
+
ETHZ/eth02/images/image_00000215_0.png
|
| 1216 |
+
ETHZ/eth02/images/image_00000216_0.png
|
| 1217 |
+
ETHZ/eth02/images/image_00000217_0.png
|
| 1218 |
+
ETHZ/eth02/images/image_00000218_0.png
|
| 1219 |
+
ETHZ/eth02/images/image_00000219_0.png
|
| 1220 |
+
ETHZ/eth02/images/image_00000220_0.png
|
| 1221 |
+
ETHZ/eth02/images/image_00000221_0.png
|
| 1222 |
+
ETHZ/eth02/images/image_00000222_0.png
|
| 1223 |
+
ETHZ/eth02/images/image_00000223_0.png
|
| 1224 |
+
ETHZ/eth02/images/image_00000224_0.png
|
| 1225 |
+
ETHZ/eth02/images/image_00000225_0.png
|
| 1226 |
+
ETHZ/eth02/images/image_00000226_0.png
|
| 1227 |
+
ETHZ/eth02/images/image_00000227_0.png
|
| 1228 |
+
ETHZ/eth02/images/image_00000228_0.png
|
| 1229 |
+
ETHZ/eth02/images/image_00000229_0.png
|
| 1230 |
+
ETHZ/eth02/images/image_00000230_0.png
|
| 1231 |
+
ETHZ/eth02/images/image_00000231_0.png
|
| 1232 |
+
ETHZ/eth02/images/image_00000232_0.png
|
| 1233 |
+
ETHZ/eth02/images/image_00000233_0.png
|
| 1234 |
+
ETHZ/eth02/images/image_00000234_0.png
|
| 1235 |
+
ETHZ/eth02/images/image_00000235_0.png
|
| 1236 |
+
ETHZ/eth02/images/image_00000236_0.png
|
| 1237 |
+
ETHZ/eth02/images/image_00000237_0.png
|
| 1238 |
+
ETHZ/eth02/images/image_00000238_0.png
|
| 1239 |
+
ETHZ/eth02/images/image_00000239_0.png
|
| 1240 |
+
ETHZ/eth02/images/image_00000240_0.png
|
| 1241 |
+
ETHZ/eth02/images/image_00000241_0.png
|
| 1242 |
+
ETHZ/eth02/images/image_00000242_0.png
|
| 1243 |
+
ETHZ/eth02/images/image_00000243_0.png
|
| 1244 |
+
ETHZ/eth02/images/image_00000244_0.png
|
| 1245 |
+
ETHZ/eth02/images/image_00000245_0.png
|
| 1246 |
+
ETHZ/eth02/images/image_00000246_0.png
|
| 1247 |
+
ETHZ/eth02/images/image_00000247_0.png
|
| 1248 |
+
ETHZ/eth02/images/image_00000248_0.png
|
| 1249 |
+
ETHZ/eth02/images/image_00000249_0.png
|
| 1250 |
+
ETHZ/eth02/images/image_00000250_0.png
|
| 1251 |
+
ETHZ/eth02/images/image_00000251_0.png
|
| 1252 |
+
ETHZ/eth02/images/image_00000252_0.png
|
| 1253 |
+
ETHZ/eth02/images/image_00000253_0.png
|
| 1254 |
+
ETHZ/eth02/images/image_00000254_0.png
|
| 1255 |
+
ETHZ/eth02/images/image_00000255_0.png
|
| 1256 |
+
ETHZ/eth02/images/image_00000256_0.png
|
| 1257 |
+
ETHZ/eth02/images/image_00000257_0.png
|
| 1258 |
+
ETHZ/eth02/images/image_00000258_0.png
|
| 1259 |
+
ETHZ/eth02/images/image_00000259_0.png
|
| 1260 |
+
ETHZ/eth02/images/image_00000260_0.png
|
| 1261 |
+
ETHZ/eth02/images/image_00000261_0.png
|
| 1262 |
+
ETHZ/eth02/images/image_00000262_0.png
|
| 1263 |
+
ETHZ/eth02/images/image_00000263_0.png
|
| 1264 |
+
ETHZ/eth02/images/image_00000264_0.png
|
| 1265 |
+
ETHZ/eth02/images/image_00000265_0.png
|
| 1266 |
+
ETHZ/eth02/images/image_00000266_0.png
|
| 1267 |
+
ETHZ/eth02/images/image_00000267_0.png
|
| 1268 |
+
ETHZ/eth02/images/image_00000268_0.png
|
| 1269 |
+
ETHZ/eth02/images/image_00000269_0.png
|
| 1270 |
+
ETHZ/eth02/images/image_00000270_0.png
|
| 1271 |
+
ETHZ/eth02/images/image_00000271_0.png
|
| 1272 |
+
ETHZ/eth02/images/image_00000272_0.png
|
| 1273 |
+
ETHZ/eth02/images/image_00000273_0.png
|
| 1274 |
+
ETHZ/eth02/images/image_00000274_0.png
|
| 1275 |
+
ETHZ/eth02/images/image_00000275_0.png
|
| 1276 |
+
ETHZ/eth02/images/image_00000276_0.png
|
| 1277 |
+
ETHZ/eth02/images/image_00000277_0.png
|
| 1278 |
+
ETHZ/eth02/images/image_00000278_0.png
|
| 1279 |
+
ETHZ/eth02/images/image_00000279_0.png
|
| 1280 |
+
ETHZ/eth02/images/image_00000280_0.png
|
| 1281 |
+
ETHZ/eth02/images/image_00000281_0.png
|
| 1282 |
+
ETHZ/eth02/images/image_00000282_0.png
|
| 1283 |
+
ETHZ/eth02/images/image_00000283_0.png
|
| 1284 |
+
ETHZ/eth02/images/image_00000284_0.png
|
| 1285 |
+
ETHZ/eth02/images/image_00000285_0.png
|
| 1286 |
+
ETHZ/eth02/images/image_00000286_0.png
|
| 1287 |
+
ETHZ/eth02/images/image_00000287_0.png
|
| 1288 |
+
ETHZ/eth02/images/image_00000288_0.png
|
| 1289 |
+
ETHZ/eth02/images/image_00000289_0.png
|
| 1290 |
+
ETHZ/eth02/images/image_00000290_0.png
|
| 1291 |
+
ETHZ/eth02/images/image_00000291_0.png
|
| 1292 |
+
ETHZ/eth02/images/image_00000292_0.png
|
| 1293 |
+
ETHZ/eth02/images/image_00000293_0.png
|
| 1294 |
+
ETHZ/eth02/images/image_00000294_0.png
|
| 1295 |
+
ETHZ/eth02/images/image_00000295_0.png
|
| 1296 |
+
ETHZ/eth02/images/image_00000296_0.png
|
| 1297 |
+
ETHZ/eth02/images/image_00000297_0.png
|
| 1298 |
+
ETHZ/eth02/images/image_00000298_0.png
|
| 1299 |
+
ETHZ/eth02/images/image_00000299_0.png
|
| 1300 |
+
ETHZ/eth02/images/image_00000300_0.png
|
| 1301 |
+
ETHZ/eth02/images/image_00000301_0.png
|
| 1302 |
+
ETHZ/eth02/images/image_00000302_0.png
|
| 1303 |
+
ETHZ/eth02/images/image_00000303_0.png
|
| 1304 |
+
ETHZ/eth02/images/image_00000304_0.png
|
| 1305 |
+
ETHZ/eth02/images/image_00000305_0.png
|
| 1306 |
+
ETHZ/eth02/images/image_00000306_0.png
|
| 1307 |
+
ETHZ/eth02/images/image_00000307_0.png
|
| 1308 |
+
ETHZ/eth02/images/image_00000308_0.png
|
| 1309 |
+
ETHZ/eth02/images/image_00000309_0.png
|
| 1310 |
+
ETHZ/eth02/images/image_00000310_0.png
|
| 1311 |
+
ETHZ/eth02/images/image_00000311_0.png
|
| 1312 |
+
ETHZ/eth02/images/image_00000312_0.png
|
| 1313 |
+
ETHZ/eth02/images/image_00000313_0.png
|
| 1314 |
+
ETHZ/eth02/images/image_00000314_0.png
|
| 1315 |
+
ETHZ/eth02/images/image_00000315_0.png
|
| 1316 |
+
ETHZ/eth02/images/image_00000316_0.png
|
| 1317 |
+
ETHZ/eth02/images/image_00000317_0.png
|
| 1318 |
+
ETHZ/eth02/images/image_00000318_0.png
|
| 1319 |
+
ETHZ/eth02/images/image_00000319_0.png
|
| 1320 |
+
ETHZ/eth02/images/image_00000320_0.png
|
| 1321 |
+
ETHZ/eth02/images/image_00000321_0.png
|
| 1322 |
+
ETHZ/eth02/images/image_00000322_0.png
|
| 1323 |
+
ETHZ/eth02/images/image_00000323_0.png
|
| 1324 |
+
ETHZ/eth02/images/image_00000324_0.png
|
| 1325 |
+
ETHZ/eth02/images/image_00000325_0.png
|
| 1326 |
+
ETHZ/eth02/images/image_00000326_0.png
|
| 1327 |
+
ETHZ/eth02/images/image_00000327_0.png
|
| 1328 |
+
ETHZ/eth02/images/image_00000328_0.png
|
| 1329 |
+
ETHZ/eth02/images/image_00000329_0.png
|
| 1330 |
+
ETHZ/eth02/images/image_00000330_0.png
|
| 1331 |
+
ETHZ/eth02/images/image_00000331_0.png
|
| 1332 |
+
ETHZ/eth02/images/image_00000332_0.png
|
| 1333 |
+
ETHZ/eth02/images/image_00000333_0.png
|
| 1334 |
+
ETHZ/eth02/images/image_00000334_0.png
|
| 1335 |
+
ETHZ/eth02/images/image_00000335_0.png
|
| 1336 |
+
ETHZ/eth02/images/image_00000336_0.png
|
| 1337 |
+
ETHZ/eth02/images/image_00000337_0.png
|
| 1338 |
+
ETHZ/eth02/images/image_00000338_0.png
|
| 1339 |
+
ETHZ/eth02/images/image_00000339_0.png
|
| 1340 |
+
ETHZ/eth02/images/image_00000340_0.png
|
| 1341 |
+
ETHZ/eth02/images/image_00000341_0.png
|
| 1342 |
+
ETHZ/eth02/images/image_00000342_0.png
|
| 1343 |
+
ETHZ/eth02/images/image_00000343_0.png
|
| 1344 |
+
ETHZ/eth02/images/image_00000344_0.png
|
| 1345 |
+
ETHZ/eth02/images/image_00000345_0.png
|
| 1346 |
+
ETHZ/eth02/images/image_00000346_0.png
|
| 1347 |
+
ETHZ/eth02/images/image_00000347_0.png
|
| 1348 |
+
ETHZ/eth02/images/image_00000348_0.png
|
| 1349 |
+
ETHZ/eth02/images/image_00000349_0.png
|
| 1350 |
+
ETHZ/eth02/images/image_00000350_0.png
|
| 1351 |
+
ETHZ/eth02/images/image_00000351_0.png
|
| 1352 |
+
ETHZ/eth02/images/image_00000352_0.png
|
| 1353 |
+
ETHZ/eth02/images/image_00000353_0.png
|
| 1354 |
+
ETHZ/eth02/images/image_00000354_0.png
|
| 1355 |
+
ETHZ/eth02/images/image_00000355_0.png
|
| 1356 |
+
ETHZ/eth02/images/image_00000356_0.png
|
| 1357 |
+
ETHZ/eth02/images/image_00000357_0.png
|
| 1358 |
+
ETHZ/eth02/images/image_00000358_0.png
|
| 1359 |
+
ETHZ/eth02/images/image_00000359_0.png
|
| 1360 |
+
ETHZ/eth02/images/image_00000360_0.png
|
| 1361 |
+
ETHZ/eth02/images/image_00000361_0.png
|
| 1362 |
+
ETHZ/eth02/images/image_00000362_0.png
|
| 1363 |
+
ETHZ/eth02/images/image_00000363_0.png
|
| 1364 |
+
ETHZ/eth02/images/image_00000364_0.png
|
| 1365 |
+
ETHZ/eth02/images/image_00000365_0.png
|
| 1366 |
+
ETHZ/eth02/images/image_00000366_0.png
|
| 1367 |
+
ETHZ/eth02/images/image_00000367_0.png
|
| 1368 |
+
ETHZ/eth02/images/image_00000368_0.png
|
| 1369 |
+
ETHZ/eth02/images/image_00000369_0.png
|
| 1370 |
+
ETHZ/eth02/images/image_00000370_0.png
|
| 1371 |
+
ETHZ/eth02/images/image_00000371_0.png
|
| 1372 |
+
ETHZ/eth02/images/image_00000372_0.png
|
| 1373 |
+
ETHZ/eth02/images/image_00000373_0.png
|
| 1374 |
+
ETHZ/eth02/images/image_00000374_0.png
|
| 1375 |
+
ETHZ/eth02/images/image_00000375_0.png
|
| 1376 |
+
ETHZ/eth02/images/image_00000376_0.png
|
| 1377 |
+
ETHZ/eth02/images/image_00000377_0.png
|
| 1378 |
+
ETHZ/eth02/images/image_00000378_0.png
|
| 1379 |
+
ETHZ/eth02/images/image_00000379_0.png
|
| 1380 |
+
ETHZ/eth02/images/image_00000380_0.png
|
| 1381 |
+
ETHZ/eth02/images/image_00000381_0.png
|
| 1382 |
+
ETHZ/eth02/images/image_00000382_0.png
|
| 1383 |
+
ETHZ/eth02/images/image_00000383_0.png
|
| 1384 |
+
ETHZ/eth02/images/image_00000384_0.png
|
| 1385 |
+
ETHZ/eth02/images/image_00000385_0.png
|
| 1386 |
+
ETHZ/eth02/images/image_00000386_0.png
|
| 1387 |
+
ETHZ/eth02/images/image_00000387_0.png
|
| 1388 |
+
ETHZ/eth02/images/image_00000388_0.png
|
| 1389 |
+
ETHZ/eth02/images/image_00000389_0.png
|
| 1390 |
+
ETHZ/eth02/images/image_00000390_0.png
|
| 1391 |
+
ETHZ/eth02/images/image_00000391_0.png
|
| 1392 |
+
ETHZ/eth02/images/image_00000392_0.png
|
| 1393 |
+
ETHZ/eth02/images/image_00000393_0.png
|
| 1394 |
+
ETHZ/eth02/images/image_00000394_0.png
|
| 1395 |
+
ETHZ/eth02/images/image_00000395_0.png
|
| 1396 |
+
ETHZ/eth02/images/image_00000396_0.png
|
| 1397 |
+
ETHZ/eth02/images/image_00000397_0.png
|
| 1398 |
+
ETHZ/eth02/images/image_00000398_0.png
|
| 1399 |
+
ETHZ/eth02/images/image_00000399_0.png
|
| 1400 |
+
ETHZ/eth02/images/image_00000400_0.png
|
| 1401 |
+
ETHZ/eth02/images/image_00000401_0.png
|
| 1402 |
+
ETHZ/eth02/images/image_00000402_0.png
|
| 1403 |
+
ETHZ/eth02/images/image_00000403_0.png
|
| 1404 |
+
ETHZ/eth02/images/image_00000404_0.png
|
| 1405 |
+
ETHZ/eth02/images/image_00000405_0.png
|
| 1406 |
+
ETHZ/eth02/images/image_00000406_0.png
|
| 1407 |
+
ETHZ/eth02/images/image_00000407_0.png
|
| 1408 |
+
ETHZ/eth02/images/image_00000408_0.png
|
| 1409 |
+
ETHZ/eth02/images/image_00000409_0.png
|
| 1410 |
+
ETHZ/eth02/images/image_00000410_0.png
|
| 1411 |
+
ETHZ/eth02/images/image_00000411_0.png
|
| 1412 |
+
ETHZ/eth02/images/image_00000412_0.png
|
| 1413 |
+
ETHZ/eth02/images/image_00000413_0.png
|
| 1414 |
+
ETHZ/eth02/images/image_00000414_0.png
|
| 1415 |
+
ETHZ/eth02/images/image_00000415_0.png
|
| 1416 |
+
ETHZ/eth02/images/image_00000416_0.png
|
| 1417 |
+
ETHZ/eth02/images/image_00000417_0.png
|
| 1418 |
+
ETHZ/eth02/images/image_00000418_0.png
|
| 1419 |
+
ETHZ/eth02/images/image_00000419_0.png
|
| 1420 |
+
ETHZ/eth02/images/image_00000420_0.png
|
| 1421 |
+
ETHZ/eth02/images/image_00000421_0.png
|
| 1422 |
+
ETHZ/eth02/images/image_00000422_0.png
|
| 1423 |
+
ETHZ/eth02/images/image_00000423_0.png
|
| 1424 |
+
ETHZ/eth02/images/image_00000424_0.png
|
| 1425 |
+
ETHZ/eth02/images/image_00000425_0.png
|
| 1426 |
+
ETHZ/eth02/images/image_00000426_0.png
|
| 1427 |
+
ETHZ/eth02/images/image_00000427_0.png
|
| 1428 |
+
ETHZ/eth02/images/image_00000428_0.png
|
| 1429 |
+
ETHZ/eth02/images/image_00000429_0.png
|
| 1430 |
+
ETHZ/eth02/images/image_00000430_0.png
|
| 1431 |
+
ETHZ/eth02/images/image_00000431_0.png
|
| 1432 |
+
ETHZ/eth02/images/image_00000432_0.png
|
| 1433 |
+
ETHZ/eth02/images/image_00000433_0.png
|
| 1434 |
+
ETHZ/eth02/images/image_00000434_0.png
|
| 1435 |
+
ETHZ/eth02/images/image_00000435_0.png
|
| 1436 |
+
ETHZ/eth02/images/image_00000436_0.png
|
| 1437 |
+
ETHZ/eth02/images/image_00000437_0.png
|
| 1438 |
+
ETHZ/eth02/images/image_00000438_0.png
|
| 1439 |
+
ETHZ/eth02/images/image_00000439_0.png
|
| 1440 |
+
ETHZ/eth02/images/image_00000440_0.png
|
| 1441 |
+
ETHZ/eth02/images/image_00000441_0.png
|
| 1442 |
+
ETHZ/eth02/images/image_00000442_0.png
|
| 1443 |
+
ETHZ/eth02/images/image_00000443_0.png
|
| 1444 |
+
ETHZ/eth02/images/image_00000444_0.png
|
| 1445 |
+
ETHZ/eth02/images/image_00000445_0.png
|
| 1446 |
+
ETHZ/eth03/images/image_00000100_0.png
|
| 1447 |
+
ETHZ/eth03/images/image_00000101_0.png
|
| 1448 |
+
ETHZ/eth03/images/image_00000102_0.png
|
| 1449 |
+
ETHZ/eth03/images/image_00000103_0.png
|
| 1450 |
+
ETHZ/eth03/images/image_00000104_0.png
|
| 1451 |
+
ETHZ/eth03/images/image_00000105_0.png
|
| 1452 |
+
ETHZ/eth03/images/image_00000106_0.png
|
| 1453 |
+
ETHZ/eth03/images/image_00000107_0.png
|
| 1454 |
+
ETHZ/eth03/images/image_00000108_0.png
|
| 1455 |
+
ETHZ/eth03/images/image_00000109_0.png
|
| 1456 |
+
ETHZ/eth03/images/image_00000110_0.png
|
| 1457 |
+
ETHZ/eth03/images/image_00000111_0.png
|
| 1458 |
+
ETHZ/eth03/images/image_00000112_0.png
|
| 1459 |
+
ETHZ/eth03/images/image_00000113_0.png
|
| 1460 |
+
ETHZ/eth03/images/image_00000114_0.png
|
| 1461 |
+
ETHZ/eth03/images/image_00000115_0.png
|
| 1462 |
+
ETHZ/eth03/images/image_00000116_0.png
|
| 1463 |
+
ETHZ/eth03/images/image_00000117_0.png
|
| 1464 |
+
ETHZ/eth03/images/image_00000118_0.png
|
| 1465 |
+
ETHZ/eth03/images/image_00000119_0.png
|
| 1466 |
+
ETHZ/eth03/images/image_00000120_0.png
|
| 1467 |
+
ETHZ/eth03/images/image_00000121_0.png
|
| 1468 |
+
ETHZ/eth03/images/image_00000122_0.png
|
| 1469 |
+
ETHZ/eth03/images/image_00000123_0.png
|
| 1470 |
+
ETHZ/eth03/images/image_00000124_0.png
|
| 1471 |
+
ETHZ/eth03/images/image_00000125_0.png
|
| 1472 |
+
ETHZ/eth03/images/image_00000126_0.png
|
| 1473 |
+
ETHZ/eth03/images/image_00000127_0.png
|
| 1474 |
+
ETHZ/eth03/images/image_00000128_0.png
|
| 1475 |
+
ETHZ/eth03/images/image_00000129_0.png
|
| 1476 |
+
ETHZ/eth03/images/image_00000130_0.png
|
| 1477 |
+
ETHZ/eth03/images/image_00000131_0.png
|
| 1478 |
+
ETHZ/eth03/images/image_00000132_0.png
|
| 1479 |
+
ETHZ/eth03/images/image_00000133_0.png
|
| 1480 |
+
ETHZ/eth03/images/image_00000134_0.png
|
| 1481 |
+
ETHZ/eth03/images/image_00000135_0.png
|
| 1482 |
+
ETHZ/eth03/images/image_00000136_0.png
|
| 1483 |
+
ETHZ/eth03/images/image_00000137_0.png
|
| 1484 |
+
ETHZ/eth03/images/image_00000138_0.png
|
| 1485 |
+
ETHZ/eth03/images/image_00000139_0.png
|
| 1486 |
+
ETHZ/eth03/images/image_00000140_0.png
|
| 1487 |
+
ETHZ/eth03/images/image_00000141_0.png
|
| 1488 |
+
ETHZ/eth03/images/image_00000142_0.png
|
| 1489 |
+
ETHZ/eth03/images/image_00000143_0.png
|
| 1490 |
+
ETHZ/eth03/images/image_00000144_0.png
|
| 1491 |
+
ETHZ/eth03/images/image_00000145_0.png
|
| 1492 |
+
ETHZ/eth03/images/image_00000146_0.png
|
| 1493 |
+
ETHZ/eth03/images/image_00000147_0.png
|
| 1494 |
+
ETHZ/eth03/images/image_00000148_0.png
|
| 1495 |
+
ETHZ/eth03/images/image_00000149_0.png
|
| 1496 |
+
ETHZ/eth03/images/image_00000150_0.png
|
| 1497 |
+
ETHZ/eth03/images/image_00000151_0.png
|
| 1498 |
+
ETHZ/eth03/images/image_00000152_0.png
|
| 1499 |
+
ETHZ/eth03/images/image_00000153_0.png
|
| 1500 |
+
ETHZ/eth03/images/image_00000154_0.png
|
| 1501 |
+
ETHZ/eth03/images/image_00000155_0.png
|
| 1502 |
+
ETHZ/eth03/images/image_00000156_0.png
|
| 1503 |
+
ETHZ/eth03/images/image_00000157_0.png
|
| 1504 |
+
ETHZ/eth03/images/image_00000158_0.png
|
| 1505 |
+
ETHZ/eth03/images/image_00000159_0.png
|
| 1506 |
+
ETHZ/eth03/images/image_00000160_0.png
|
| 1507 |
+
ETHZ/eth03/images/image_00000161_0.png
|
| 1508 |
+
ETHZ/eth03/images/image_00000162_0.png
|
| 1509 |
+
ETHZ/eth03/images/image_00000163_0.png
|
| 1510 |
+
ETHZ/eth03/images/image_00000164_0.png
|
| 1511 |
+
ETHZ/eth03/images/image_00000165_0.png
|
| 1512 |
+
ETHZ/eth03/images/image_00000166_0.png
|
| 1513 |
+
ETHZ/eth03/images/image_00000167_0.png
|
| 1514 |
+
ETHZ/eth03/images/image_00000168_0.png
|
| 1515 |
+
ETHZ/eth03/images/image_00000169_0.png
|
| 1516 |
+
ETHZ/eth03/images/image_00000170_0.png
|
| 1517 |
+
ETHZ/eth03/images/image_00000171_0.png
|
| 1518 |
+
ETHZ/eth03/images/image_00000172_0.png
|
| 1519 |
+
ETHZ/eth03/images/image_00000173_0.png
|
| 1520 |
+
ETHZ/eth03/images/image_00000174_0.png
|
| 1521 |
+
ETHZ/eth03/images/image_00000175_0.png
|
| 1522 |
+
ETHZ/eth03/images/image_00000176_0.png
|
| 1523 |
+
ETHZ/eth03/images/image_00000177_0.png
|
| 1524 |
+
ETHZ/eth03/images/image_00000178_0.png
|
| 1525 |
+
ETHZ/eth03/images/image_00000179_0.png
|
| 1526 |
+
ETHZ/eth03/images/image_00000180_0.png
|
| 1527 |
+
ETHZ/eth03/images/image_00000181_0.png
|
| 1528 |
+
ETHZ/eth03/images/image_00000182_0.png
|
| 1529 |
+
ETHZ/eth03/images/image_00000183_0.png
|
| 1530 |
+
ETHZ/eth03/images/image_00000184_0.png
|
| 1531 |
+
ETHZ/eth03/images/image_00000185_0.png
|
| 1532 |
+
ETHZ/eth03/images/image_00000186_0.png
|
| 1533 |
+
ETHZ/eth03/images/image_00000187_0.png
|
| 1534 |
+
ETHZ/eth03/images/image_00000188_0.png
|
| 1535 |
+
ETHZ/eth03/images/image_00000189_0.png
|
| 1536 |
+
ETHZ/eth03/images/image_00000190_0.png
|
| 1537 |
+
ETHZ/eth03/images/image_00000191_0.png
|
| 1538 |
+
ETHZ/eth03/images/image_00000192_0.png
|
| 1539 |
+
ETHZ/eth03/images/image_00000193_0.png
|
| 1540 |
+
ETHZ/eth03/images/image_00000194_0.png
|
| 1541 |
+
ETHZ/eth03/images/image_00000195_0.png
|
| 1542 |
+
ETHZ/eth03/images/image_00000196_0.png
|
| 1543 |
+
ETHZ/eth03/images/image_00000197_0.png
|
| 1544 |
+
ETHZ/eth03/images/image_00000198_0.png
|
| 1545 |
+
ETHZ/eth03/images/image_00000199_0.png
|
| 1546 |
+
ETHZ/eth03/images/image_00000200_0.png
|
| 1547 |
+
ETHZ/eth03/images/image_00000201_0.png
|
| 1548 |
+
ETHZ/eth03/images/image_00000202_0.png
|
| 1549 |
+
ETHZ/eth03/images/image_00000203_0.png
|
| 1550 |
+
ETHZ/eth03/images/image_00000204_0.png
|
| 1551 |
+
ETHZ/eth03/images/image_00000205_0.png
|
| 1552 |
+
ETHZ/eth03/images/image_00000206_0.png
|
| 1553 |
+
ETHZ/eth03/images/image_00000207_0.png
|
| 1554 |
+
ETHZ/eth03/images/image_00000208_0.png
|
| 1555 |
+
ETHZ/eth03/images/image_00000209_0.png
|
| 1556 |
+
ETHZ/eth03/images/image_00000210_0.png
|
| 1557 |
+
ETHZ/eth03/images/image_00000211_0.png
|
| 1558 |
+
ETHZ/eth03/images/image_00000212_0.png
|
| 1559 |
+
ETHZ/eth03/images/image_00000213_0.png
|
| 1560 |
+
ETHZ/eth03/images/image_00000214_0.png
|
| 1561 |
+
ETHZ/eth03/images/image_00000215_0.png
|
| 1562 |
+
ETHZ/eth03/images/image_00000216_0.png
|
| 1563 |
+
ETHZ/eth03/images/image_00000217_0.png
|
| 1564 |
+
ETHZ/eth03/images/image_00000218_0.png
|
| 1565 |
+
ETHZ/eth03/images/image_00000219_0.png
|
| 1566 |
+
ETHZ/eth03/images/image_00000220_0.png
|
| 1567 |
+
ETHZ/eth03/images/image_00000221_0.png
|
| 1568 |
+
ETHZ/eth03/images/image_00000222_0.png
|
| 1569 |
+
ETHZ/eth03/images/image_00000223_0.png
|
| 1570 |
+
ETHZ/eth03/images/image_00000224_0.png
|
| 1571 |
+
ETHZ/eth03/images/image_00000225_0.png
|
| 1572 |
+
ETHZ/eth03/images/image_00000226_0.png
|
| 1573 |
+
ETHZ/eth03/images/image_00000227_0.png
|
| 1574 |
+
ETHZ/eth03/images/image_00000228_0.png
|
| 1575 |
+
ETHZ/eth03/images/image_00000229_0.png
|
| 1576 |
+
ETHZ/eth03/images/image_00000230_0.png
|
| 1577 |
+
ETHZ/eth03/images/image_00000231_0.png
|
| 1578 |
+
ETHZ/eth03/images/image_00000232_0.png
|
| 1579 |
+
ETHZ/eth03/images/image_00000233_0.png
|
| 1580 |
+
ETHZ/eth03/images/image_00000234_0.png
|
| 1581 |
+
ETHZ/eth03/images/image_00000235_0.png
|
| 1582 |
+
ETHZ/eth03/images/image_00000236_0.png
|
| 1583 |
+
ETHZ/eth03/images/image_00000237_0.png
|
| 1584 |
+
ETHZ/eth03/images/image_00000238_0.png
|
| 1585 |
+
ETHZ/eth03/images/image_00000239_0.png
|
| 1586 |
+
ETHZ/eth03/images/image_00000240_0.png
|
| 1587 |
+
ETHZ/eth03/images/image_00000241_0.png
|
| 1588 |
+
ETHZ/eth03/images/image_00000242_0.png
|
| 1589 |
+
ETHZ/eth03/images/image_00000243_0.png
|
| 1590 |
+
ETHZ/eth03/images/image_00000244_0.png
|
| 1591 |
+
ETHZ/eth03/images/image_00000245_0.png
|
| 1592 |
+
ETHZ/eth03/images/image_00000246_0.png
|
| 1593 |
+
ETHZ/eth03/images/image_00000247_0.png
|
| 1594 |
+
ETHZ/eth03/images/image_00000248_0.png
|
| 1595 |
+
ETHZ/eth03/images/image_00000249_0.png
|
| 1596 |
+
ETHZ/eth03/images/image_00000250_0.png
|
| 1597 |
+
ETHZ/eth03/images/image_00000251_0.png
|
| 1598 |
+
ETHZ/eth03/images/image_00000252_0.png
|
| 1599 |
+
ETHZ/eth03/images/image_00000253_0.png
|
| 1600 |
+
ETHZ/eth03/images/image_00000254_0.png
|
| 1601 |
+
ETHZ/eth03/images/image_00000255_0.png
|
| 1602 |
+
ETHZ/eth03/images/image_00000256_0.png
|
| 1603 |
+
ETHZ/eth03/images/image_00000257_0.png
|
| 1604 |
+
ETHZ/eth03/images/image_00000258_0.png
|
| 1605 |
+
ETHZ/eth03/images/image_00000259_0.png
|
| 1606 |
+
ETHZ/eth03/images/image_00000260_0.png
|
| 1607 |
+
ETHZ/eth03/images/image_00000261_0.png
|
| 1608 |
+
ETHZ/eth03/images/image_00000262_0.png
|
| 1609 |
+
ETHZ/eth03/images/image_00000263_0.png
|
| 1610 |
+
ETHZ/eth03/images/image_00000264_0.png
|
| 1611 |
+
ETHZ/eth03/images/image_00000265_0.png
|
| 1612 |
+
ETHZ/eth03/images/image_00000266_0.png
|
| 1613 |
+
ETHZ/eth03/images/image_00000267_0.png
|
| 1614 |
+
ETHZ/eth03/images/image_00000268_0.png
|
| 1615 |
+
ETHZ/eth03/images/image_00000269_0.png
|
| 1616 |
+
ETHZ/eth03/images/image_00000270_0.png
|
| 1617 |
+
ETHZ/eth03/images/image_00000271_0.png
|
| 1618 |
+
ETHZ/eth03/images/image_00000272_0.png
|
| 1619 |
+
ETHZ/eth03/images/image_00000273_0.png
|
| 1620 |
+
ETHZ/eth03/images/image_00000274_0.png
|
| 1621 |
+
ETHZ/eth03/images/image_00000275_0.png
|
| 1622 |
+
ETHZ/eth03/images/image_00000276_0.png
|
| 1623 |
+
ETHZ/eth03/images/image_00000277_0.png
|
| 1624 |
+
ETHZ/eth03/images/image_00000278_0.png
|
| 1625 |
+
ETHZ/eth03/images/image_00000279_0.png
|
| 1626 |
+
ETHZ/eth03/images/image_00000280_0.png
|
| 1627 |
+
ETHZ/eth03/images/image_00000281_0.png
|
| 1628 |
+
ETHZ/eth03/images/image_00000282_0.png
|
| 1629 |
+
ETHZ/eth03/images/image_00000283_0.png
|
| 1630 |
+
ETHZ/eth03/images/image_00000284_0.png
|
| 1631 |
+
ETHZ/eth03/images/image_00000285_0.png
|
| 1632 |
+
ETHZ/eth03/images/image_00000286_0.png
|
| 1633 |
+
ETHZ/eth03/images/image_00000287_0.png
|
| 1634 |
+
ETHZ/eth03/images/image_00000288_0.png
|
| 1635 |
+
ETHZ/eth03/images/image_00000289_0.png
|
| 1636 |
+
ETHZ/eth03/images/image_00000290_0.png
|
| 1637 |
+
ETHZ/eth03/images/image_00000291_0.png
|
| 1638 |
+
ETHZ/eth03/images/image_00000292_0.png
|
| 1639 |
+
ETHZ/eth03/images/image_00000293_0.png
|
| 1640 |
+
ETHZ/eth03/images/image_00000294_0.png
|
| 1641 |
+
ETHZ/eth03/images/image_00000295_0.png
|
| 1642 |
+
ETHZ/eth03/images/image_00000296_0.png
|
| 1643 |
+
ETHZ/eth03/images/image_00000297_0.png
|
| 1644 |
+
ETHZ/eth03/images/image_00000298_0.png
|
| 1645 |
+
ETHZ/eth03/images/image_00000299_0.png
|
| 1646 |
+
ETHZ/eth03/images/image_00000300_0.png
|
| 1647 |
+
ETHZ/eth03/images/image_00000301_0.png
|
| 1648 |
+
ETHZ/eth03/images/image_00000302_0.png
|
| 1649 |
+
ETHZ/eth03/images/image_00000303_0.png
|
| 1650 |
+
ETHZ/eth03/images/image_00000304_0.png
|
| 1651 |
+
ETHZ/eth03/images/image_00000305_0.png
|
| 1652 |
+
ETHZ/eth03/images/image_00000306_0.png
|
| 1653 |
+
ETHZ/eth03/images/image_00000307_0.png
|
| 1654 |
+
ETHZ/eth03/images/image_00000308_0.png
|
| 1655 |
+
ETHZ/eth03/images/image_00000309_0.png
|
| 1656 |
+
ETHZ/eth03/images/image_00000310_0.png
|
| 1657 |
+
ETHZ/eth03/images/image_00000311_0.png
|
| 1658 |
+
ETHZ/eth03/images/image_00000312_0.png
|
| 1659 |
+
ETHZ/eth03/images/image_00000313_0.png
|
| 1660 |
+
ETHZ/eth03/images/image_00000314_0.png
|
| 1661 |
+
ETHZ/eth03/images/image_00000315_0.png
|
| 1662 |
+
ETHZ/eth03/images/image_00000316_0.png
|
| 1663 |
+
ETHZ/eth03/images/image_00000317_0.png
|
| 1664 |
+
ETHZ/eth03/images/image_00000318_0.png
|
| 1665 |
+
ETHZ/eth03/images/image_00000319_0.png
|
| 1666 |
+
ETHZ/eth03/images/image_00000320_0.png
|
| 1667 |
+
ETHZ/eth03/images/image_00000321_0.png
|
| 1668 |
+
ETHZ/eth03/images/image_00000322_0.png
|
| 1669 |
+
ETHZ/eth03/images/image_00000323_0.png
|
| 1670 |
+
ETHZ/eth03/images/image_00000324_0.png
|
| 1671 |
+
ETHZ/eth03/images/image_00000325_0.png
|
| 1672 |
+
ETHZ/eth03/images/image_00000326_0.png
|
| 1673 |
+
ETHZ/eth03/images/image_00000327_0.png
|
| 1674 |
+
ETHZ/eth03/images/image_00000328_0.png
|
| 1675 |
+
ETHZ/eth03/images/image_00000329_0.png
|
| 1676 |
+
ETHZ/eth03/images/image_00000330_0.png
|
| 1677 |
+
ETHZ/eth03/images/image_00000331_0.png
|
| 1678 |
+
ETHZ/eth03/images/image_00000332_0.png
|
| 1679 |
+
ETHZ/eth03/images/image_00000333_0.png
|
| 1680 |
+
ETHZ/eth03/images/image_00000334_0.png
|
| 1681 |
+
ETHZ/eth03/images/image_00000335_0.png
|
| 1682 |
+
ETHZ/eth03/images/image_00000336_0.png
|
| 1683 |
+
ETHZ/eth03/images/image_00000337_0.png
|
| 1684 |
+
ETHZ/eth03/images/image_00000338_0.png
|
| 1685 |
+
ETHZ/eth03/images/image_00000339_0.png
|
| 1686 |
+
ETHZ/eth03/images/image_00000340_0.png
|
| 1687 |
+
ETHZ/eth03/images/image_00000341_0.png
|
| 1688 |
+
ETHZ/eth03/images/image_00000342_0.png
|
| 1689 |
+
ETHZ/eth03/images/image_00000343_0.png
|
| 1690 |
+
ETHZ/eth03/images/image_00000344_0.png
|
| 1691 |
+
ETHZ/eth03/images/image_00000345_0.png
|
| 1692 |
+
ETHZ/eth03/images/image_00000346_0.png
|
| 1693 |
+
ETHZ/eth03/images/image_00000347_0.png
|
| 1694 |
+
ETHZ/eth03/images/image_00000348_0.png
|
| 1695 |
+
ETHZ/eth03/images/image_00000349_0.png
|
| 1696 |
+
ETHZ/eth03/images/image_00000350_0.png
|
| 1697 |
+
ETHZ/eth03/images/image_00000351_0.png
|
| 1698 |
+
ETHZ/eth03/images/image_00000352_0.png
|
| 1699 |
+
ETHZ/eth03/images/image_00000353_0.png
|
| 1700 |
+
ETHZ/eth03/images/image_00000354_0.png
|
| 1701 |
+
ETHZ/eth03/images/image_00000355_0.png
|
| 1702 |
+
ETHZ/eth03/images/image_00000356_0.png
|
| 1703 |
+
ETHZ/eth03/images/image_00000357_0.png
|
| 1704 |
+
ETHZ/eth03/images/image_00000358_0.png
|
| 1705 |
+
ETHZ/eth03/images/image_00000359_0.png
|
| 1706 |
+
ETHZ/eth03/images/image_00000360_0.png
|
| 1707 |
+
ETHZ/eth03/images/image_00000361_0.png
|
| 1708 |
+
ETHZ/eth03/images/image_00000362_0.png
|
| 1709 |
+
ETHZ/eth03/images/image_00000363_0.png
|
| 1710 |
+
ETHZ/eth03/images/image_00000364_0.png
|
| 1711 |
+
ETHZ/eth03/images/image_00000365_0.png
|
| 1712 |
+
ETHZ/eth03/images/image_00000366_0.png
|
| 1713 |
+
ETHZ/eth03/images/image_00000367_0.png
|
| 1714 |
+
ETHZ/eth03/images/image_00000368_0.png
|
| 1715 |
+
ETHZ/eth03/images/image_00000369_0.png
|
| 1716 |
+
ETHZ/eth03/images/image_00000370_0.png
|
| 1717 |
+
ETHZ/eth03/images/image_00000371_0.png
|
| 1718 |
+
ETHZ/eth03/images/image_00000372_0.png
|
| 1719 |
+
ETHZ/eth03/images/image_00000373_0.png
|
| 1720 |
+
ETHZ/eth03/images/image_00000374_0.png
|
| 1721 |
+
ETHZ/eth03/images/image_00000375_0.png
|
| 1722 |
+
ETHZ/eth03/images/image_00000376_0.png
|
| 1723 |
+
ETHZ/eth03/images/image_00000377_0.png
|
| 1724 |
+
ETHZ/eth03/images/image_00000378_0.png
|
| 1725 |
+
ETHZ/eth03/images/image_00000379_0.png
|
| 1726 |
+
ETHZ/eth03/images/image_00000380_0.png
|
| 1727 |
+
ETHZ/eth03/images/image_00000381_0.png
|
| 1728 |
+
ETHZ/eth03/images/image_00000382_0.png
|
| 1729 |
+
ETHZ/eth03/images/image_00000383_0.png
|
| 1730 |
+
ETHZ/eth03/images/image_00000384_0.png
|
| 1731 |
+
ETHZ/eth03/images/image_00000385_0.png
|
| 1732 |
+
ETHZ/eth03/images/image_00000386_0.png
|
| 1733 |
+
ETHZ/eth03/images/image_00000387_0.png
|
| 1734 |
+
ETHZ/eth03/images/image_00000388_0.png
|
| 1735 |
+
ETHZ/eth03/images/image_00000389_0.png
|
| 1736 |
+
ETHZ/eth03/images/image_00000390_0.png
|
| 1737 |
+
ETHZ/eth03/images/image_00000391_0.png
|
| 1738 |
+
ETHZ/eth03/images/image_00000392_0.png
|
| 1739 |
+
ETHZ/eth03/images/image_00000393_0.png
|
| 1740 |
+
ETHZ/eth03/images/image_00000394_0.png
|
| 1741 |
+
ETHZ/eth03/images/image_00000395_0.png
|
| 1742 |
+
ETHZ/eth03/images/image_00000396_0.png
|
| 1743 |
+
ETHZ/eth03/images/image_00000397_0.png
|
| 1744 |
+
ETHZ/eth03/images/image_00000398_0.png
|
| 1745 |
+
ETHZ/eth03/images/image_00000399_0.png
|
| 1746 |
+
ETHZ/eth03/images/image_00000400_0.png
|
| 1747 |
+
ETHZ/eth03/images/image_00000401_0.png
|
| 1748 |
+
ETHZ/eth03/images/image_00000402_0.png
|
| 1749 |
+
ETHZ/eth03/images/image_00000403_0.png
|
| 1750 |
+
ETHZ/eth03/images/image_00000404_0.png
|
| 1751 |
+
ETHZ/eth03/images/image_00000405_0.png
|
| 1752 |
+
ETHZ/eth03/images/image_00000406_0.png
|
| 1753 |
+
ETHZ/eth03/images/image_00000407_0.png
|
| 1754 |
+
ETHZ/eth03/images/image_00000408_0.png
|
| 1755 |
+
ETHZ/eth03/images/image_00000409_0.png
|
| 1756 |
+
ETHZ/eth03/images/image_00000410_0.png
|
| 1757 |
+
ETHZ/eth03/images/image_00000411_0.png
|
| 1758 |
+
ETHZ/eth03/images/image_00000412_0.png
|
| 1759 |
+
ETHZ/eth03/images/image_00000413_0.png
|
| 1760 |
+
ETHZ/eth03/images/image_00000414_0.png
|
| 1761 |
+
ETHZ/eth03/images/image_00000415_0.png
|
| 1762 |
+
ETHZ/eth03/images/image_00000416_0.png
|
| 1763 |
+
ETHZ/eth03/images/image_00000417_0.png
|
| 1764 |
+
ETHZ/eth03/images/image_00000418_0.png
|
| 1765 |
+
ETHZ/eth03/images/image_00000419_0.png
|
| 1766 |
+
ETHZ/eth03/images/image_00000420_0.png
|
| 1767 |
+
ETHZ/eth03/images/image_00000421_0.png
|
| 1768 |
+
ETHZ/eth03/images/image_00000422_0.png
|
| 1769 |
+
ETHZ/eth03/images/image_00000423_0.png
|
| 1770 |
+
ETHZ/eth03/images/image_00000424_0.png
|
| 1771 |
+
ETHZ/eth03/images/image_00000425_0.png
|
| 1772 |
+
ETHZ/eth03/images/image_00000426_0.png
|
| 1773 |
+
ETHZ/eth03/images/image_00000427_0.png
|
| 1774 |
+
ETHZ/eth03/images/image_00000428_0.png
|
| 1775 |
+
ETHZ/eth03/images/image_00000429_0.png
|
| 1776 |
+
ETHZ/eth03/images/image_00000430_0.png
|
| 1777 |
+
ETHZ/eth03/images/image_00000431_0.png
|
| 1778 |
+
ETHZ/eth03/images/image_00000432_0.png
|
| 1779 |
+
ETHZ/eth03/images/image_00000433_0.png
|
| 1780 |
+
ETHZ/eth03/images/image_00000434_0.png
|
| 1781 |
+
ETHZ/eth03/images/image_00000435_0.png
|
| 1782 |
+
ETHZ/eth03/images/image_00000436_0.png
|
| 1783 |
+
ETHZ/eth03/images/image_00000437_0.png
|
| 1784 |
+
ETHZ/eth03/images/image_00000438_0.png
|
| 1785 |
+
ETHZ/eth03/images/image_00000439_0.png
|
| 1786 |
+
ETHZ/eth03/images/image_00000440_0.png
|
| 1787 |
+
ETHZ/eth03/images/image_00000441_0.png
|
| 1788 |
+
ETHZ/eth03/images/image_00000442_0.png
|
| 1789 |
+
ETHZ/eth03/images/image_00000443_0.png
|
| 1790 |
+
ETHZ/eth03/images/image_00000444_0.png
|
| 1791 |
+
ETHZ/eth03/images/image_00000445_0.png
|
| 1792 |
+
ETHZ/eth03/images/image_00000446_0.png
|
| 1793 |
+
ETHZ/eth03/images/image_00000447_0.png
|
| 1794 |
+
ETHZ/eth03/images/image_00000448_0.png
|
| 1795 |
+
ETHZ/eth03/images/image_00000449_0.png
|
| 1796 |
+
ETHZ/eth03/images/image_00000450_0.png
|
| 1797 |
+
ETHZ/eth03/images/image_00000451_0.png
|
| 1798 |
+
ETHZ/eth03/images/image_00000452_0.png
|
| 1799 |
+
ETHZ/eth03/images/image_00000453_0.png
|
| 1800 |
+
ETHZ/eth05/images/image_00000000_0.png
|
| 1801 |
+
ETHZ/eth05/images/image_00000004_0.png
|
| 1802 |
+
ETHZ/eth05/images/image_00000008_0.png
|
| 1803 |
+
ETHZ/eth05/images/image_00000012_0.png
|
| 1804 |
+
ETHZ/eth05/images/image_00000016_0.png
|
| 1805 |
+
ETHZ/eth05/images/image_00000022_0.png
|
| 1806 |
+
ETHZ/eth05/images/image_00000026_0.png
|
| 1807 |
+
ETHZ/eth05/images/image_00000030_0.png
|
| 1808 |
+
ETHZ/eth05/images/image_00000034_0.png
|
| 1809 |
+
ETHZ/eth05/images/image_00000038_0.png
|
| 1810 |
+
ETHZ/eth05/images/image_00000042_0.png
|
| 1811 |
+
ETHZ/eth05/images/image_00000046_0.png
|
| 1812 |
+
ETHZ/eth05/images/image_00000050_0.png
|
| 1813 |
+
ETHZ/eth05/images/image_00000054_0.png
|
| 1814 |
+
ETHZ/eth05/images/image_00000058_0.png
|
| 1815 |
+
ETHZ/eth05/images/image_00000062_0.png
|
| 1816 |
+
ETHZ/eth05/images/image_00000066_0.png
|
| 1817 |
+
ETHZ/eth05/images/image_00000070_0.png
|
| 1818 |
+
ETHZ/eth05/images/image_00000074_0.png
|
| 1819 |
+
ETHZ/eth05/images/image_00000078_0.png
|
| 1820 |
+
ETHZ/eth05/images/image_00000082_0.png
|
| 1821 |
+
ETHZ/eth05/images/image_00000086_0.png
|
| 1822 |
+
ETHZ/eth05/images/image_00000090_0.png
|
| 1823 |
+
ETHZ/eth05/images/image_00000094_0.png
|
| 1824 |
+
ETHZ/eth05/images/image_00000098_0.png
|
| 1825 |
+
ETHZ/eth05/images/image_00000101_0.png
|
| 1826 |
+
ETHZ/eth05/images/image_00000105_0.png
|
| 1827 |
+
ETHZ/eth05/images/image_00000109_0.png
|
| 1828 |
+
ETHZ/eth05/images/image_00000113_0.png
|
| 1829 |
+
ETHZ/eth05/images/image_00000115_0.png
|
| 1830 |
+
ETHZ/eth05/images/image_00000119_0.png
|
| 1831 |
+
ETHZ/eth05/images/image_00000123_0.png
|
| 1832 |
+
ETHZ/eth05/images/image_00000127_0.png
|
| 1833 |
+
ETHZ/eth05/images/image_00000130_0.png
|
| 1834 |
+
ETHZ/eth05/images/image_00000134_0.png
|
| 1835 |
+
ETHZ/eth05/images/image_00000138_0.png
|
| 1836 |
+
ETHZ/eth05/images/image_00000142_0.png
|
| 1837 |
+
ETHZ/eth05/images/image_00000145_0.png
|
| 1838 |
+
ETHZ/eth05/images/image_00000149_0.png
|
| 1839 |
+
ETHZ/eth05/images/image_00000153_0.png
|
| 1840 |
+
ETHZ/eth05/images/image_00000157_0.png
|
| 1841 |
+
ETHZ/eth05/images/image_00000161_0.png
|
| 1842 |
+
ETHZ/eth05/images/image_00000165_0.png
|
| 1843 |
+
ETHZ/eth05/images/image_00000169_0.png
|
| 1844 |
+
ETHZ/eth05/images/image_00000173_0.png
|
| 1845 |
+
ETHZ/eth05/images/image_00000177_0.png
|
| 1846 |
+
ETHZ/eth05/images/image_00000181_0.png
|
| 1847 |
+
ETHZ/eth05/images/image_00000185_0.png
|
| 1848 |
+
ETHZ/eth05/images/image_00000189_0.png
|
| 1849 |
+
ETHZ/eth05/images/image_00000193_0.png
|
| 1850 |
+
ETHZ/eth05/images/image_00000197_0.png
|
| 1851 |
+
ETHZ/eth05/images/image_00000201_0.png
|
| 1852 |
+
ETHZ/eth05/images/image_00000205_0.png
|
| 1853 |
+
ETHZ/eth05/images/image_00000209_0.png
|
| 1854 |
+
ETHZ/eth05/images/image_00000213_0.png
|
| 1855 |
+
ETHZ/eth05/images/image_00000217_0.png
|
| 1856 |
+
ETHZ/eth07/images/image_00004900_0.png
|
| 1857 |
+
ETHZ/eth07/images/image_00004904_0.png
|
| 1858 |
+
ETHZ/eth07/images/image_00004908_0.png
|
| 1859 |
+
ETHZ/eth07/images/image_00004912_0.png
|
| 1860 |
+
ETHZ/eth07/images/image_00004916_0.png
|
| 1861 |
+
ETHZ/eth07/images/image_00004920_0.png
|
| 1862 |
+
ETHZ/eth07/images/image_00004924_0.png
|
| 1863 |
+
ETHZ/eth07/images/image_00004928_0.png
|
| 1864 |
+
ETHZ/eth07/images/image_00004932_0.png
|
| 1865 |
+
ETHZ/eth07/images/image_00004936_0.png
|
| 1866 |
+
ETHZ/eth07/images/image_00004940_0.png
|
| 1867 |
+
ETHZ/eth07/images/image_00004944_0.png
|
| 1868 |
+
ETHZ/eth07/images/image_00004948_0.png
|
| 1869 |
+
ETHZ/eth07/images/image_00004952_0.png
|
| 1870 |
+
ETHZ/eth07/images/image_00004956_0.png
|
| 1871 |
+
ETHZ/eth07/images/image_00004960_0.png
|
| 1872 |
+
ETHZ/eth07/images/image_00004964_0.png
|
| 1873 |
+
ETHZ/eth07/images/image_00004968_0.png
|
| 1874 |
+
ETHZ/eth07/images/image_00004972_0.png
|
| 1875 |
+
ETHZ/eth07/images/image_00004976_0.png
|
| 1876 |
+
ETHZ/eth07/images/image_00004980_0.png
|
| 1877 |
+
ETHZ/eth07/images/image_00004984_0.png
|
| 1878 |
+
ETHZ/eth07/images/image_00004988_0.png
|
| 1879 |
+
ETHZ/eth07/images/image_00004992_0.png
|
| 1880 |
+
ETHZ/eth07/images/image_00004996_0.png
|
| 1881 |
+
ETHZ/eth07/images/image_00005000_0.png
|
| 1882 |
+
ETHZ/eth07/images/image_00005004_0.png
|
| 1883 |
+
ETHZ/eth07/images/image_00005008_0.png
|
| 1884 |
+
ETHZ/eth07/images/image_00005012_0.png
|
| 1885 |
+
ETHZ/eth07/images/image_00005016_0.png
|
| 1886 |
+
ETHZ/eth07/images/image_00005020_0.png
|
| 1887 |
+
ETHZ/eth07/images/image_00005024_0.png
|
| 1888 |
+
ETHZ/eth07/images/image_00005028_0.png
|
| 1889 |
+
ETHZ/eth07/images/image_00005032_0.png
|
| 1890 |
+
ETHZ/eth07/images/image_00005036_0.png
|
| 1891 |
+
ETHZ/eth07/images/image_00005040_0.png
|
| 1892 |
+
ETHZ/eth07/images/image_00005044_0.png
|
| 1893 |
+
ETHZ/eth07/images/image_00005048_0.png
|
| 1894 |
+
ETHZ/eth07/images/image_00005052_0.png
|
| 1895 |
+
ETHZ/eth07/images/image_00005056_0.png
|
| 1896 |
+
ETHZ/eth07/images/image_00005060_0.png
|
| 1897 |
+
ETHZ/eth07/images/image_00005064_0.png
|
| 1898 |
+
ETHZ/eth07/images/image_00005068_0.png
|
| 1899 |
+
ETHZ/eth07/images/image_00005072_0.png
|
| 1900 |
+
ETHZ/eth07/images/image_00005076_0.png
|
| 1901 |
+
ETHZ/eth07/images/image_00005080_0.png
|
| 1902 |
+
ETHZ/eth07/images/image_00005084_0.png
|
| 1903 |
+
ETHZ/eth07/images/image_00005088_0.png
|
| 1904 |
+
ETHZ/eth07/images/image_00005092_0.png
|
| 1905 |
+
ETHZ/eth07/images/image_00005096_0.png
|
| 1906 |
+
ETHZ/eth07/images/image_00005100_0.png
|
| 1907 |
+
ETHZ/eth07/images/image_00005104_0.png
|
| 1908 |
+
ETHZ/eth07/images/image_00005108_0.png
|
| 1909 |
+
ETHZ/eth07/images/image_00005112_0.png
|
| 1910 |
+
ETHZ/eth07/images/image_00005116_0.png
|
| 1911 |
+
ETHZ/eth07/images/image_00005120_0.png
|
| 1912 |
+
ETHZ/eth07/images/image_00005124_0.png
|
| 1913 |
+
ETHZ/eth07/images/image_00005128_0.png
|
| 1914 |
+
ETHZ/eth07/images/image_00005132_0.png
|
| 1915 |
+
ETHZ/eth07/images/image_00005136_0.png
|
| 1916 |
+
ETHZ/eth07/images/image_00005140_0.png
|
| 1917 |
+
ETHZ/eth07/images/image_00005144_0.png
|
| 1918 |
+
ETHZ/eth07/images/image_00005148_0.png
|
| 1919 |
+
ETHZ/eth07/images/image_00005152_0.png
|
| 1920 |
+
ETHZ/eth07/images/image_00005156_0.png
|
| 1921 |
+
ETHZ/eth07/images/image_00005160_0.png
|
| 1922 |
+
ETHZ/eth07/images/image_00005164_0.png
|
| 1923 |
+
ETHZ/eth07/images/image_00005168_0.png
|
| 1924 |
+
ETHZ/eth07/images/image_00005172_0.png
|
| 1925 |
+
ETHZ/eth07/images/image_00005176_0.png
|
| 1926 |
+
ETHZ/eth07/images/image_00005180_0.png
|
| 1927 |
+
ETHZ/eth07/images/image_00005184_0.png
|
| 1928 |
+
ETHZ/eth07/images/image_00005188_0.png
|
| 1929 |
+
ETHZ/eth07/images/image_00005192_0.png
|
| 1930 |
+
ETHZ/eth07/images/image_00005196_0.png
|
| 1931 |
+
ETHZ/eth07/images/image_00005200_0.png
|
| 1932 |
+
ETHZ/eth07/images/image_00005204_0.png
|
| 1933 |
+
ETHZ/eth07/images/image_00005208_0.png
|
| 1934 |
+
ETHZ/eth07/images/image_00005212_0.png
|
| 1935 |
+
ETHZ/eth07/images/image_00005216_0.png
|
| 1936 |
+
ETHZ/eth07/images/image_00005220_0.png
|
| 1937 |
+
ETHZ/eth07/images/image_00005224_0.png
|
| 1938 |
+
ETHZ/eth07/images/image_00005228_0.png
|
| 1939 |
+
ETHZ/eth07/images/image_00005232_0.png
|
| 1940 |
+
ETHZ/eth07/images/image_00005236_0.png
|
| 1941 |
+
ETHZ/eth07/images/image_00005240_0.png
|
| 1942 |
+
ETHZ/eth07/images/image_00005244_0.png
|
| 1943 |
+
ETHZ/eth07/images/image_00005248_0.png
|
| 1944 |
+
ETHZ/eth07/images/image_00005252_0.png
|
| 1945 |
+
ETHZ/eth07/images/image_00005256_0.png
|
| 1946 |
+
ETHZ/eth07/images/image_00005260_0.png
|
| 1947 |
+
ETHZ/eth07/images/image_00005264_0.png
|
| 1948 |
+
ETHZ/eth07/images/image_00005268_0.png
|
| 1949 |
+
ETHZ/eth07/images/image_00005272_0.png
|
| 1950 |
+
ETHZ/eth07/images/image_00005276_0.png
|
| 1951 |
+
ETHZ/eth07/images/image_00005280_0.png
|
| 1952 |
+
ETHZ/eth07/images/image_00005284_0.png
|
| 1953 |
+
ETHZ/eth07/images/image_00005288_0.png
|
| 1954 |
+
ETHZ/eth07/images/image_00005292_0.png
|
| 1955 |
+
ETHZ/eth07/images/image_00005296_0.png
|
| 1956 |
+
ETHZ/eth07/images/image_00005300_0.png
|
| 1957 |
+
ETHZ/eth07/images/image_00005304_0.png
|
| 1958 |
+
ETHZ/eth07/images/image_00005308_0.png
|
| 1959 |
+
ETHZ/eth07/images/image_00005312_0.png
|
| 1960 |
+
ETHZ/eth07/images/image_00005316_0.png
|
| 1961 |
+
ETHZ/eth07/images/image_00005320_0.png
|
| 1962 |
+
ETHZ/eth07/images/image_00005324_0.png
|
| 1963 |
+
ETHZ/eth07/images/image_00005328_0.png
|
| 1964 |
+
ETHZ/eth07/images/image_00005332_0.png
|
| 1965 |
+
ETHZ/eth07/images/image_00005336_0.png
|
| 1966 |
+
ETHZ/eth07/images/image_00005340_0.png
|
| 1967 |
+
ETHZ/eth07/images/image_00005344_0.png
|
| 1968 |
+
ETHZ/eth07/images/image_00005348_0.png
|
| 1969 |
+
ETHZ/eth07/images/image_00005352_0.png
|
| 1970 |
+
ETHZ/eth07/images/image_00005356_0.png
|
| 1971 |
+
ETHZ/eth07/images/image_00005360_0.png
|
| 1972 |
+
ETHZ/eth07/images/image_00005364_0.png
|
| 1973 |
+
ETHZ/eth07/images/image_00005368_0.png
|
| 1974 |
+
ETHZ/eth07/images/image_00005372_0.png
|
| 1975 |
+
ETHZ/eth07/images/image_00005376_0.png
|
| 1976 |
+
ETHZ/eth07/images/image_00005380_0.png
|
| 1977 |
+
ETHZ/eth07/images/image_00005384_0.png
|
| 1978 |
+
ETHZ/eth07/images/image_00005388_0.png
|
| 1979 |
+
ETHZ/eth07/images/image_00005392_0.png
|
| 1980 |
+
ETHZ/eth07/images/image_00005396_0.png
|
| 1981 |
+
ETHZ/eth07/images/image_00005400_0.png
|
| 1982 |
+
ETHZ/eth07/images/image_00005404_0.png
|
| 1983 |
+
ETHZ/eth07/images/image_00005408_0.png
|
| 1984 |
+
ETHZ/eth07/images/image_00005412_0.png
|
| 1985 |
+
ETHZ/eth07/images/image_00005416_0.png
|
| 1986 |
+
ETHZ/eth07/images/image_00005420_0.png
|
| 1987 |
+
ETHZ/eth07/images/image_00005424_0.png
|
| 1988 |
+
ETHZ/eth07/images/image_00005428_0.png
|
| 1989 |
+
ETHZ/eth07/images/image_00005432_0.png
|
| 1990 |
+
ETHZ/eth07/images/image_00005436_0.png
|
| 1991 |
+
ETHZ/eth07/images/image_00005440_0.png
|
| 1992 |
+
ETHZ/eth07/images/image_00005444_0.png
|
| 1993 |
+
ETHZ/eth07/images/image_00005448_0.png
|
| 1994 |
+
ETHZ/eth07/images/image_00005452_0.png
|
| 1995 |
+
ETHZ/eth07/images/image_00005456_0.png
|
| 1996 |
+
ETHZ/eth07/images/image_00005460_0.png
|
| 1997 |
+
ETHZ/eth07/images/image_00005464_0.png
|
| 1998 |
+
ETHZ/eth07/images/image_00005468_0.png
|
| 1999 |
+
ETHZ/eth07/images/image_00005472_0.png
|
| 2000 |
+
ETHZ/eth07/images/image_00005476_0.png
|
| 2001 |
+
ETHZ/eth07/images/image_00005480_0.png
|
| 2002 |
+
ETHZ/eth07/images/image_00005484_0.png
|
| 2003 |
+
ETHZ/eth07/images/image_00005488_0.png
|
| 2004 |
+
ETHZ/eth07/images/image_00005492_0.png
|
| 2005 |
+
ETHZ/eth07/images/image_00005496_0.png
|
| 2006 |
+
ETHZ/eth07/images/image_00005500_0.png
|
| 2007 |
+
ETHZ/eth07/images/image_00005504_0.png
|
| 2008 |
+
ETHZ/eth07/images/image_00005508_0.png
|
| 2009 |
+
ETHZ/eth07/images/image_00005512_0.png
|
| 2010 |
+
ETHZ/eth07/images/image_00005516_0.png
|
| 2011 |
+
ETHZ/eth07/images/image_00005520_0.png
|
| 2012 |
+
ETHZ/eth07/images/image_00005524_0.png
|
| 2013 |
+
ETHZ/eth07/images/image_00005528_0.png
|
| 2014 |
+
ETHZ/eth07/images/image_00005532_0.png
|
| 2015 |
+
ETHZ/eth07/images/image_00005536_0.png
|
| 2016 |
+
ETHZ/eth07/images/image_00005540_0.png
|
| 2017 |
+
ETHZ/eth07/images/image_00005544_0.png
|
| 2018 |
+
ETHZ/eth07/images/image_00005548_0.png
|
| 2019 |
+
ETHZ/eth07/images/image_00005552_0.png
|
| 2020 |
+
ETHZ/eth07/images/image_00005556_0.png
|
| 2021 |
+
ETHZ/eth07/images/image_00005560_0.png
|
| 2022 |
+
ETHZ/eth07/images/image_00005564_0.png
|
| 2023 |
+
ETHZ/eth07/images/image_00005568_0.png
|
| 2024 |
+
ETHZ/eth07/images/image_00005572_0.png
|
| 2025 |
+
ETHZ/eth07/images/image_00005576_0.png
|
| 2026 |
+
ETHZ/eth07/images/image_00005580_0.png
|
| 2027 |
+
ETHZ/eth07/images/image_00005584_0.png
|
| 2028 |
+
ETHZ/eth07/images/image_00005588_0.png
|
| 2029 |
+
ETHZ/eth07/images/image_00005592_0.png
|
| 2030 |
+
ETHZ/eth07/images/image_00005596_0.png
|
| 2031 |
+
ETHZ/eth07/images/image_00005600_0.png
|
| 2032 |
+
ETHZ/eth07/images/image_00005604_0.png
|
| 2033 |
+
ETHZ/eth07/images/image_00005608_0.png
|
| 2034 |
+
ETHZ/eth07/images/image_00005612_0.png
|
| 2035 |
+
ETHZ/eth07/images/image_00005616_0.png
|
| 2036 |
+
ETHZ/eth07/images/image_00005620_0.png
|
| 2037 |
+
ETHZ/eth07/images/image_00005624_0.png
|
| 2038 |
+
ETHZ/eth07/images/image_00005628_0.png
|
| 2039 |
+
ETHZ/eth07/images/image_00005632_0.png
|
| 2040 |
+
ETHZ/eth07/images/image_00005636_0.png
|
| 2041 |
+
ETHZ/eth07/images/image_00005640_0.png
|
| 2042 |
+
ETHZ/eth07/images/image_00005644_0.png
|
| 2043 |
+
ETHZ/eth07/images/image_00005648_0.png
|
| 2044 |
+
ETHZ/eth07/images/image_00005652_0.png
|
| 2045 |
+
ETHZ/eth07/images/image_00005656_0.png
|
| 2046 |
+
ETHZ/eth07/images/image_00005660_0.png
|
| 2047 |
+
ETHZ/eth07/images/image_00005664_0.png
|
| 2048 |
+
ETHZ/eth07/images/image_00005668_0.png
|
| 2049 |
+
ETHZ/eth07/images/image_00005672_0.png
|
| 2050 |
+
ETHZ/eth07/images/image_00005676_0.png
|
| 2051 |
+
ETHZ/eth07/images/image_00005680_0.png
|
| 2052 |
+
ETHZ/eth07/images/image_00005684_0.png
|
| 2053 |
+
ETHZ/eth07/images/image_00005688_0.png
|
| 2054 |
+
ETHZ/eth07/images/image_00005692_0.png
|
| 2055 |
+
ETHZ/eth07/images/image_00005696_0.png
|
| 2056 |
+
ETHZ/eth07/images/image_00005700_0.png
|
deploy/ONNXRuntime/README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
## ByteTrack-ONNXRuntime in Python
|
| 2 |
+
|
| 3 |
+
This doc introduces how to convert your pytorch model into onnx, and how to run an onnxruntime demo to verify your convertion.
|
| 4 |
+
|
| 5 |
+
### Convert Your Model to ONNX
|
| 6 |
+
|
| 7 |
+
```shell
|
| 8 |
+
cd <ByteTrack_HOME>
|
| 9 |
+
python3 tools/export_onnx.py --output-name bytetrack_s.onnx -f exps/example/mot/yolox_s_mix_det.py -c pretrained/bytetrack_s_mot17.pth.tar
|
| 10 |
+
```
|
| 11 |
+
|
| 12 |
+
### ONNXRuntime Demo
|
| 13 |
+
|
| 14 |
+
You can run onnx demo with **16 FPS** (96-core Intel(R) Xeon(R) Platinum 8163 CPU @ 2.50GHz):
|
| 15 |
+
|
| 16 |
+
```shell
|
| 17 |
+
cd <ByteTrack_HOME>/deploy/ONNXRuntime
|
| 18 |
+
python3 onnx_inference.py
|
| 19 |
+
```
|
deploy/ONNXRuntime/onnx_inference.py
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
import cv2
|
| 5 |
+
import numpy as np
|
| 6 |
+
from loguru import logger
|
| 7 |
+
|
| 8 |
+
import onnxruntime
|
| 9 |
+
|
| 10 |
+
from yolox.data.data_augment import preproc as preprocess
|
| 11 |
+
from yolox.utils import mkdir, multiclass_nms, demo_postprocess, vis
|
| 12 |
+
from yolox.utils.visualize import plot_tracking
|
| 13 |
+
from yolox.tracker.byte_tracker import BYTETracker
|
| 14 |
+
from yolox.tracking_utils.timer import Timer
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def make_parser():
|
| 18 |
+
parser = argparse.ArgumentParser("onnxruntime inference sample")
|
| 19 |
+
parser.add_argument(
|
| 20 |
+
"-m",
|
| 21 |
+
"--model",
|
| 22 |
+
type=str,
|
| 23 |
+
default="../../bytetrack_s.onnx",
|
| 24 |
+
help="Input your onnx model.",
|
| 25 |
+
)
|
| 26 |
+
parser.add_argument(
|
| 27 |
+
"-i",
|
| 28 |
+
"--video_path",
|
| 29 |
+
type=str,
|
| 30 |
+
default='../../videos/palace.mp4',
|
| 31 |
+
help="Path to your input image.",
|
| 32 |
+
)
|
| 33 |
+
parser.add_argument(
|
| 34 |
+
"-o",
|
| 35 |
+
"--output_dir",
|
| 36 |
+
type=str,
|
| 37 |
+
default='demo_output',
|
| 38 |
+
help="Path to your output directory.",
|
| 39 |
+
)
|
| 40 |
+
parser.add_argument(
|
| 41 |
+
"-s",
|
| 42 |
+
"--score_thr",
|
| 43 |
+
type=float,
|
| 44 |
+
default=0.1,
|
| 45 |
+
help="Score threshould to filter the result.",
|
| 46 |
+
)
|
| 47 |
+
parser.add_argument(
|
| 48 |
+
"-n",
|
| 49 |
+
"--nms_thr",
|
| 50 |
+
type=float,
|
| 51 |
+
default=0.7,
|
| 52 |
+
help="NMS threshould.",
|
| 53 |
+
)
|
| 54 |
+
parser.add_argument(
|
| 55 |
+
"--input_shape",
|
| 56 |
+
type=str,
|
| 57 |
+
default="608,1088",
|
| 58 |
+
help="Specify an input shape for inference.",
|
| 59 |
+
)
|
| 60 |
+
parser.add_argument(
|
| 61 |
+
"--with_p6",
|
| 62 |
+
action="store_true",
|
| 63 |
+
help="Whether your model uses p6 in FPN/PAN.",
|
| 64 |
+
)
|
| 65 |
+
# tracking args
|
| 66 |
+
parser.add_argument("--track_thresh", type=float, default=0.5, help="tracking confidence threshold")
|
| 67 |
+
parser.add_argument("--track_buffer", type=int, default=30, help="the frames for keep lost tracks")
|
| 68 |
+
parser.add_argument("--match_thresh", type=int, default=0.8, help="matching threshold for tracking")
|
| 69 |
+
parser.add_argument('--min-box-area', type=float, default=10, help='filter out tiny boxes')
|
| 70 |
+
parser.add_argument("--mot20", dest="mot20", default=False, action="store_true", help="test mot20.")
|
| 71 |
+
return parser
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
class Predictor(object):
|
| 75 |
+
def __init__(self, args):
|
| 76 |
+
self.rgb_means = (0.485, 0.456, 0.406)
|
| 77 |
+
self.std = (0.229, 0.224, 0.225)
|
| 78 |
+
self.args = args
|
| 79 |
+
self.session = onnxruntime.InferenceSession(args.model)
|
| 80 |
+
self.input_shape = tuple(map(int, args.input_shape.split(',')))
|
| 81 |
+
|
| 82 |
+
def inference(self, ori_img, timer):
|
| 83 |
+
img_info = {"id": 0}
|
| 84 |
+
height, width = ori_img.shape[:2]
|
| 85 |
+
img_info["height"] = height
|
| 86 |
+
img_info["width"] = width
|
| 87 |
+
img_info["raw_img"] = ori_img
|
| 88 |
+
|
| 89 |
+
img, ratio = preprocess(ori_img, self.input_shape, self.rgb_means, self.std)
|
| 90 |
+
img_info["ratio"] = ratio
|
| 91 |
+
ort_inputs = {self.session.get_inputs()[0].name: img[None, :, :, :]}
|
| 92 |
+
timer.tic()
|
| 93 |
+
output = self.session.run(None, ort_inputs)
|
| 94 |
+
predictions = demo_postprocess(output[0], self.input_shape, p6=self.args.with_p6)[0]
|
| 95 |
+
|
| 96 |
+
boxes = predictions[:, :4]
|
| 97 |
+
scores = predictions[:, 4:5] * predictions[:, 5:]
|
| 98 |
+
|
| 99 |
+
boxes_xyxy = np.ones_like(boxes)
|
| 100 |
+
boxes_xyxy[:, 0] = boxes[:, 0] - boxes[:, 2]/2.
|
| 101 |
+
boxes_xyxy[:, 1] = boxes[:, 1] - boxes[:, 3]/2.
|
| 102 |
+
boxes_xyxy[:, 2] = boxes[:, 0] + boxes[:, 2]/2.
|
| 103 |
+
boxes_xyxy[:, 3] = boxes[:, 1] + boxes[:, 3]/2.
|
| 104 |
+
boxes_xyxy /= ratio
|
| 105 |
+
dets = multiclass_nms(boxes_xyxy, scores, nms_thr=self.args.nms_thr, score_thr=self.args.score_thr)
|
| 106 |
+
return dets[:, :-1], img_info
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
def imageflow_demo(predictor, args):
|
| 110 |
+
cap = cv2.VideoCapture(args.video_path)
|
| 111 |
+
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # float
|
| 112 |
+
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # float
|
| 113 |
+
fps = cap.get(cv2.CAP_PROP_FPS)
|
| 114 |
+
save_folder = args.output_dir
|
| 115 |
+
os.makedirs(save_folder, exist_ok=True)
|
| 116 |
+
save_path = os.path.join(save_folder, args.video_path.split("/")[-1])
|
| 117 |
+
logger.info(f"video save_path is {save_path}")
|
| 118 |
+
vid_writer = cv2.VideoWriter(
|
| 119 |
+
save_path, cv2.VideoWriter_fourcc(*"mp4v"), fps, (int(width), int(height))
|
| 120 |
+
)
|
| 121 |
+
tracker = BYTETracker(args, frame_rate=30)
|
| 122 |
+
timer = Timer()
|
| 123 |
+
frame_id = 0
|
| 124 |
+
results = []
|
| 125 |
+
while True:
|
| 126 |
+
if frame_id % 20 == 0:
|
| 127 |
+
logger.info('Processing frame {} ({:.2f} fps)'.format(frame_id, 1. / max(1e-5, timer.average_time)))
|
| 128 |
+
ret_val, frame = cap.read()
|
| 129 |
+
if ret_val:
|
| 130 |
+
outputs, img_info = predictor.inference(frame, timer)
|
| 131 |
+
online_targets = tracker.update(outputs, [img_info['height'], img_info['width']], [img_info['height'], img_info['width']])
|
| 132 |
+
online_tlwhs = []
|
| 133 |
+
online_ids = []
|
| 134 |
+
online_scores = []
|
| 135 |
+
for t in online_targets:
|
| 136 |
+
tlwh = t.tlwh
|
| 137 |
+
tid = t.track_id
|
| 138 |
+
vertical = tlwh[2] / tlwh[3] > 1.6
|
| 139 |
+
if tlwh[2] * tlwh[3] > args.min_box_area and not vertical:
|
| 140 |
+
online_tlwhs.append(tlwh)
|
| 141 |
+
online_ids.append(tid)
|
| 142 |
+
online_scores.append(t.score)
|
| 143 |
+
timer.toc()
|
| 144 |
+
results.append((frame_id + 1, online_tlwhs, online_ids, online_scores))
|
| 145 |
+
online_im = plot_tracking(img_info['raw_img'], online_tlwhs, online_ids, frame_id=frame_id + 1,
|
| 146 |
+
fps=1. / timer.average_time)
|
| 147 |
+
vid_writer.write(online_im)
|
| 148 |
+
ch = cv2.waitKey(1)
|
| 149 |
+
if ch == 27 or ch == ord("q") or ch == ord("Q"):
|
| 150 |
+
break
|
| 151 |
+
else:
|
| 152 |
+
break
|
| 153 |
+
frame_id += 1
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
if __name__ == '__main__':
|
| 157 |
+
args = make_parser().parse_args()
|
| 158 |
+
|
| 159 |
+
predictor = Predictor(args)
|
| 160 |
+
imageflow_demo(predictor, args)
|
deploy/TensorRT/cpp/CMakeLists.txt
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
cmake_minimum_required(VERSION 2.6)
|
| 2 |
+
|
| 3 |
+
project(bytetrack)
|
| 4 |
+
|
| 5 |
+
add_definitions(-std=c++11)
|
| 6 |
+
|
| 7 |
+
option(CUDA_USE_STATIC_CUDA_RUNTIME OFF)
|
| 8 |
+
set(CMAKE_CXX_STANDARD 11)
|
| 9 |
+
set(CMAKE_BUILD_TYPE Debug)
|
| 10 |
+
|
| 11 |
+
find_package(CUDA REQUIRED)
|
| 12 |
+
|
| 13 |
+
include_directories(${PROJECT_SOURCE_DIR}/include)
|
| 14 |
+
include_directories(/usr/local/include/eigen3)
|
| 15 |
+
link_directories(${PROJECT_SOURCE_DIR}/include)
|
| 16 |
+
# include and link dirs of cuda and tensorrt, you need adapt them if yours are different
|
| 17 |
+
# cuda
|
| 18 |
+
include_directories(/usr/local/cuda/include)
|
| 19 |
+
link_directories(/usr/local/cuda/lib64)
|
| 20 |
+
# cudnn
|
| 21 |
+
include_directories(/data/cuda/cuda-10.2/cudnn/v8.0.4/include)
|
| 22 |
+
link_directories(/data/cuda/cuda-10.2/cudnn/v8.0.4/lib64)
|
| 23 |
+
# tensorrt
|
| 24 |
+
include_directories(/opt/tiger/demo/TensorRT-7.2.3.4/include)
|
| 25 |
+
link_directories(/opt/tiger/demo/TensorRT-7.2.3.4/lib)
|
| 26 |
+
|
| 27 |
+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Ofast -Wfatal-errors -D_MWAITXINTRIN_H_INCLUDED")
|
| 28 |
+
|
| 29 |
+
find_package(OpenCV)
|
| 30 |
+
include_directories(${OpenCV_INCLUDE_DIRS})
|
| 31 |
+
|
| 32 |
+
file(GLOB My_Source_Files ${PROJECT_SOURCE_DIR}/src/*.cpp)
|
| 33 |
+
add_executable(bytetrack ${My_Source_Files})
|
| 34 |
+
target_link_libraries(bytetrack nvinfer)
|
| 35 |
+
target_link_libraries(bytetrack cudart)
|
| 36 |
+
target_link_libraries(bytetrack ${OpenCV_LIBS})
|
| 37 |
+
|
| 38 |
+
add_definitions(-O2 -pthread)
|
| 39 |
+
|
deploy/TensorRT/cpp/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ByteTrack-TensorRT in C++
|
| 2 |
+
|
| 3 |
+
## Installation
|
| 4 |
+
|
| 5 |
+
Install opencv with ```sudo apt-get install libopencv-dev``` (we don't need a higher version of opencv like v3.3+).
|
| 6 |
+
|
| 7 |
+
Install eigen-3.3.9 [[google]](https://drive.google.com/file/d/1rqO74CYCNrmRAg8Rra0JP3yZtJ-rfket/view?usp=sharing), [[baidu(code:ueq4)]](https://pan.baidu.com/s/15kEfCxpy-T7tz60msxxExg).
|
| 8 |
+
|
| 9 |
+
```shell
|
| 10 |
+
unzip eigen-3.3.9.zip
|
| 11 |
+
cd eigen-3.3.9
|
| 12 |
+
mkdir build
|
| 13 |
+
cd build
|
| 14 |
+
cmake ..
|
| 15 |
+
sudo make install
|
| 16 |
+
```
|
| 17 |
+
|
| 18 |
+
## Prepare serialized engine file
|
| 19 |
+
|
| 20 |
+
Follow the TensorRT Python demo to convert and save the serialized engine file.
|
| 21 |
+
|
| 22 |
+
Check the 'model_trt.engine' file, which will be automatically saved at the YOLOX_output dir.
|
| 23 |
+
|
| 24 |
+
## Build the demo
|
| 25 |
+
|
| 26 |
+
You should set the TensorRT path and CUDA path in CMakeLists.txt.
|
| 27 |
+
|
| 28 |
+
For bytetrack_s model, we set the input frame size 1088 x 608. For bytetrack_m, bytetrack_l, bytetrack_x models, we set the input frame size 1440 x 800. You can modify the INPUT_W and INPUT_H in src/bytetrack.cpp
|
| 29 |
+
|
| 30 |
+
```c++
|
| 31 |
+
static const int INPUT_W = 1088;
|
| 32 |
+
static const int INPUT_H = 608;
|
| 33 |
+
```
|
| 34 |
+
|
| 35 |
+
You can first build the demo:
|
| 36 |
+
|
| 37 |
+
```shell
|
| 38 |
+
cd <ByteTrack_HOME>/demo/TensorRT/cpp
|
| 39 |
+
mkdir build
|
| 40 |
+
cd build
|
| 41 |
+
cmake ..
|
| 42 |
+
make
|
| 43 |
+
```
|
| 44 |
+
|
| 45 |
+
Then you can run the demo with **200 FPS**:
|
| 46 |
+
|
| 47 |
+
```shell
|
| 48 |
+
./bytetrack ../../../../YOLOX_outputs/yolox_s_mix_det/model_trt.engine -i ../../../../videos/palace.mp4
|
| 49 |
+
```
|
| 50 |
+
|
| 51 |
+
(If you find the output video lose some frames, you can convert the input video by running:
|
| 52 |
+
|
| 53 |
+
```shell
|
| 54 |
+
cd <ByteTrack_HOME>
|
| 55 |
+
python3 tools/convert_video.py
|
| 56 |
+
```
|
| 57 |
+
to generate an appropriate input video for TensorRT C++ demo. )
|
| 58 |
+
|
deploy/TensorRT/cpp/include/BYTETracker.h
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include "STrack.h"
|
| 4 |
+
|
| 5 |
+
struct Object
|
| 6 |
+
{
|
| 7 |
+
cv::Rect_<float> rect;
|
| 8 |
+
int label;
|
| 9 |
+
float prob;
|
| 10 |
+
};
|
| 11 |
+
|
| 12 |
+
class BYTETracker
|
| 13 |
+
{
|
| 14 |
+
public:
|
| 15 |
+
BYTETracker(int frame_rate = 30, int track_buffer = 30);
|
| 16 |
+
~BYTETracker();
|
| 17 |
+
|
| 18 |
+
vector<STrack> update(const vector<Object>& objects);
|
| 19 |
+
Scalar get_color(int idx);
|
| 20 |
+
|
| 21 |
+
private:
|
| 22 |
+
vector<STrack*> joint_stracks(vector<STrack*> &tlista, vector<STrack> &tlistb);
|
| 23 |
+
vector<STrack> joint_stracks(vector<STrack> &tlista, vector<STrack> &tlistb);
|
| 24 |
+
|
| 25 |
+
vector<STrack> sub_stracks(vector<STrack> &tlista, vector<STrack> &tlistb);
|
| 26 |
+
void remove_duplicate_stracks(vector<STrack> &resa, vector<STrack> &resb, vector<STrack> &stracksa, vector<STrack> &stracksb);
|
| 27 |
+
|
| 28 |
+
void linear_assignment(vector<vector<float> > &cost_matrix, int cost_matrix_size, int cost_matrix_size_size, float thresh,
|
| 29 |
+
vector<vector<int> > &matches, vector<int> &unmatched_a, vector<int> &unmatched_b);
|
| 30 |
+
vector<vector<float> > iou_distance(vector<STrack*> &atracks, vector<STrack> &btracks, int &dist_size, int &dist_size_size);
|
| 31 |
+
vector<vector<float> > iou_distance(vector<STrack> &atracks, vector<STrack> &btracks);
|
| 32 |
+
vector<vector<float> > ious(vector<vector<float> > &atlbrs, vector<vector<float> > &btlbrs);
|
| 33 |
+
|
| 34 |
+
double lapjv(const vector<vector<float> > &cost, vector<int> &rowsol, vector<int> &colsol,
|
| 35 |
+
bool extend_cost = false, float cost_limit = LONG_MAX, bool return_cost = true);
|
| 36 |
+
|
| 37 |
+
private:
|
| 38 |
+
|
| 39 |
+
float track_thresh;
|
| 40 |
+
float high_thresh;
|
| 41 |
+
float match_thresh;
|
| 42 |
+
int frame_id;
|
| 43 |
+
int max_time_lost;
|
| 44 |
+
|
| 45 |
+
vector<STrack> tracked_stracks;
|
| 46 |
+
vector<STrack> lost_stracks;
|
| 47 |
+
vector<STrack> removed_stracks;
|
| 48 |
+
byte_kalman::KalmanFilter kalman_filter;
|
| 49 |
+
};
|
deploy/TensorRT/cpp/include/STrack.h
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <opencv2/opencv.hpp>
|
| 4 |
+
#include "kalmanFilter.h"
|
| 5 |
+
|
| 6 |
+
using namespace cv;
|
| 7 |
+
using namespace std;
|
| 8 |
+
|
| 9 |
+
enum TrackState { New = 0, Tracked, Lost, Removed };
|
| 10 |
+
|
| 11 |
+
class STrack
|
| 12 |
+
{
|
| 13 |
+
public:
|
| 14 |
+
STrack(vector<float> tlwh_, float score);
|
| 15 |
+
~STrack();
|
| 16 |
+
|
| 17 |
+
vector<float> static tlbr_to_tlwh(vector<float> &tlbr);
|
| 18 |
+
void static multi_predict(vector<STrack*> &stracks, byte_kalman::KalmanFilter &kalman_filter);
|
| 19 |
+
void static_tlwh();
|
| 20 |
+
void static_tlbr();
|
| 21 |
+
vector<float> tlwh_to_xyah(vector<float> tlwh_tmp);
|
| 22 |
+
vector<float> to_xyah();
|
| 23 |
+
void mark_lost();
|
| 24 |
+
void mark_removed();
|
| 25 |
+
int next_id();
|
| 26 |
+
int end_frame();
|
| 27 |
+
|
| 28 |
+
void activate(byte_kalman::KalmanFilter &kalman_filter, int frame_id);
|
| 29 |
+
void re_activate(STrack &new_track, int frame_id, bool new_id = false);
|
| 30 |
+
void update(STrack &new_track, int frame_id);
|
| 31 |
+
|
| 32 |
+
public:
|
| 33 |
+
bool is_activated;
|
| 34 |
+
int track_id;
|
| 35 |
+
int state;
|
| 36 |
+
|
| 37 |
+
vector<float> _tlwh;
|
| 38 |
+
vector<float> tlwh;
|
| 39 |
+
vector<float> tlbr;
|
| 40 |
+
int frame_id;
|
| 41 |
+
int tracklet_len;
|
| 42 |
+
int start_frame;
|
| 43 |
+
|
| 44 |
+
KAL_MEAN mean;
|
| 45 |
+
KAL_COVA covariance;
|
| 46 |
+
float score;
|
| 47 |
+
|
| 48 |
+
private:
|
| 49 |
+
byte_kalman::KalmanFilter kalman_filter;
|
| 50 |
+
};
|
deploy/TensorRT/cpp/include/dataType.h
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <cstddef>
|
| 4 |
+
#include <vector>
|
| 5 |
+
|
| 6 |
+
#include <Eigen/Core>
|
| 7 |
+
#include <Eigen/Dense>
|
| 8 |
+
typedef Eigen::Matrix<float, 1, 4, Eigen::RowMajor> DETECTBOX;
|
| 9 |
+
typedef Eigen::Matrix<float, -1, 4, Eigen::RowMajor> DETECTBOXSS;
|
| 10 |
+
typedef Eigen::Matrix<float, 1, 128, Eigen::RowMajor> FEATURE;
|
| 11 |
+
typedef Eigen::Matrix<float, Eigen::Dynamic, 128, Eigen::RowMajor> FEATURESS;
|
| 12 |
+
//typedef std::vector<FEATURE> FEATURESS;
|
| 13 |
+
|
| 14 |
+
//Kalmanfilter
|
| 15 |
+
//typedef Eigen::Matrix<float, 8, 8, Eigen::RowMajor> KAL_FILTER;
|
| 16 |
+
typedef Eigen::Matrix<float, 1, 8, Eigen::RowMajor> KAL_MEAN;
|
| 17 |
+
typedef Eigen::Matrix<float, 8, 8, Eigen::RowMajor> KAL_COVA;
|
| 18 |
+
typedef Eigen::Matrix<float, 1, 4, Eigen::RowMajor> KAL_HMEAN;
|
| 19 |
+
typedef Eigen::Matrix<float, 4, 4, Eigen::RowMajor> KAL_HCOVA;
|
| 20 |
+
using KAL_DATA = std::pair<KAL_MEAN, KAL_COVA>;
|
| 21 |
+
using KAL_HDATA = std::pair<KAL_HMEAN, KAL_HCOVA>;
|
| 22 |
+
|
| 23 |
+
//main
|
| 24 |
+
using RESULT_DATA = std::pair<int, DETECTBOX>;
|
| 25 |
+
|
| 26 |
+
//tracker:
|
| 27 |
+
using TRACKER_DATA = std::pair<int, FEATURESS>;
|
| 28 |
+
using MATCH_DATA = std::pair<int, int>;
|
| 29 |
+
typedef struct t {
|
| 30 |
+
std::vector<MATCH_DATA> matches;
|
| 31 |
+
std::vector<int> unmatched_tracks;
|
| 32 |
+
std::vector<int> unmatched_detections;
|
| 33 |
+
}TRACHER_MATCHD;
|
| 34 |
+
|
| 35 |
+
//linear_assignment:
|
| 36 |
+
typedef Eigen::Matrix<float, -1, -1, Eigen::RowMajor> DYNAMICM;
|
deploy/TensorRT/cpp/include/kalmanFilter.h
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include "dataType.h"
|
| 4 |
+
|
| 5 |
+
namespace byte_kalman
|
| 6 |
+
{
|
| 7 |
+
class KalmanFilter
|
| 8 |
+
{
|
| 9 |
+
public:
|
| 10 |
+
static const double chi2inv95[10];
|
| 11 |
+
KalmanFilter();
|
| 12 |
+
KAL_DATA initiate(const DETECTBOX& measurement);
|
| 13 |
+
void predict(KAL_MEAN& mean, KAL_COVA& covariance);
|
| 14 |
+
KAL_HDATA project(const KAL_MEAN& mean, const KAL_COVA& covariance);
|
| 15 |
+
KAL_DATA update(const KAL_MEAN& mean,
|
| 16 |
+
const KAL_COVA& covariance,
|
| 17 |
+
const DETECTBOX& measurement);
|
| 18 |
+
|
| 19 |
+
Eigen::Matrix<float, 1, -1> gating_distance(
|
| 20 |
+
const KAL_MEAN& mean,
|
| 21 |
+
const KAL_COVA& covariance,
|
| 22 |
+
const std::vector<DETECTBOX>& measurements,
|
| 23 |
+
bool only_position = false);
|
| 24 |
+
|
| 25 |
+
private:
|
| 26 |
+
Eigen::Matrix<float, 8, 8, Eigen::RowMajor> _motion_mat;
|
| 27 |
+
Eigen::Matrix<float, 4, 8, Eigen::RowMajor> _update_mat;
|
| 28 |
+
float _std_weight_position;
|
| 29 |
+
float _std_weight_velocity;
|
| 30 |
+
};
|
| 31 |
+
}
|
deploy/TensorRT/cpp/include/lapjv.h
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef LAPJV_H
|
| 2 |
+
#define LAPJV_H
|
| 3 |
+
|
| 4 |
+
#define LARGE 1000000
|
| 5 |
+
|
| 6 |
+
#if !defined TRUE
|
| 7 |
+
#define TRUE 1
|
| 8 |
+
#endif
|
| 9 |
+
#if !defined FALSE
|
| 10 |
+
#define FALSE 0
|
| 11 |
+
#endif
|
| 12 |
+
|
| 13 |
+
#define NEW(x, t, n) if ((x = (t *)malloc(sizeof(t) * (n))) == 0) { return -1; }
|
| 14 |
+
#define FREE(x) if (x != 0) { free(x); x = 0; }
|
| 15 |
+
#define SWAP_INDICES(a, b) { int_t _temp_index = a; a = b; b = _temp_index; }
|
| 16 |
+
|
| 17 |
+
#if 0
|
| 18 |
+
#include <assert.h>
|
| 19 |
+
#define ASSERT(cond) assert(cond)
|
| 20 |
+
#define PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
|
| 21 |
+
#define PRINT_COST_ARRAY(a, n) \
|
| 22 |
+
while (1) { \
|
| 23 |
+
printf(#a" = ["); \
|
| 24 |
+
if ((n) > 0) { \
|
| 25 |
+
printf("%f", (a)[0]); \
|
| 26 |
+
for (uint_t j = 1; j < n; j++) { \
|
| 27 |
+
printf(", %f", (a)[j]); \
|
| 28 |
+
} \
|
| 29 |
+
} \
|
| 30 |
+
printf("]\n"); \
|
| 31 |
+
break; \
|
| 32 |
+
}
|
| 33 |
+
#define PRINT_INDEX_ARRAY(a, n) \
|
| 34 |
+
while (1) { \
|
| 35 |
+
printf(#a" = ["); \
|
| 36 |
+
if ((n) > 0) { \
|
| 37 |
+
printf("%d", (a)[0]); \
|
| 38 |
+
for (uint_t j = 1; j < n; j++) { \
|
| 39 |
+
printf(", %d", (a)[j]); \
|
| 40 |
+
} \
|
| 41 |
+
} \
|
| 42 |
+
printf("]\n"); \
|
| 43 |
+
break; \
|
| 44 |
+
}
|
| 45 |
+
#else
|
| 46 |
+
#define ASSERT(cond)
|
| 47 |
+
#define PRINTF(fmt, ...)
|
| 48 |
+
#define PRINT_COST_ARRAY(a, n)
|
| 49 |
+
#define PRINT_INDEX_ARRAY(a, n)
|
| 50 |
+
#endif
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
typedef signed int int_t;
|
| 54 |
+
typedef unsigned int uint_t;
|
| 55 |
+
typedef double cost_t;
|
| 56 |
+
typedef char boolean;
|
| 57 |
+
typedef enum fp_t { FP_1 = 1, FP_2 = 2, FP_DYNAMIC = 3 } fp_t;
|
| 58 |
+
|
| 59 |
+
extern int_t lapjv_internal(
|
| 60 |
+
const uint_t n, cost_t *cost[],
|
| 61 |
+
int_t *x, int_t *y);
|
| 62 |
+
|
| 63 |
+
#endif // LAPJV_H
|
deploy/TensorRT/cpp/include/logging.h
ADDED
|
@@ -0,0 +1,503 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
| 3 |
+
*
|
| 4 |
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
* you may not use this file except in compliance with the License.
|
| 6 |
+
* You may obtain a copy of the License at
|
| 7 |
+
*
|
| 8 |
+
* http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
*
|
| 10 |
+
* Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
* See the License for the specific language governing permissions and
|
| 14 |
+
* limitations under the License.
|
| 15 |
+
*/
|
| 16 |
+
|
| 17 |
+
#ifndef TENSORRT_LOGGING_H
|
| 18 |
+
#define TENSORRT_LOGGING_H
|
| 19 |
+
|
| 20 |
+
#include "NvInferRuntimeCommon.h"
|
| 21 |
+
#include <cassert>
|
| 22 |
+
#include <ctime>
|
| 23 |
+
#include <iomanip>
|
| 24 |
+
#include <iostream>
|
| 25 |
+
#include <ostream>
|
| 26 |
+
#include <sstream>
|
| 27 |
+
#include <string>
|
| 28 |
+
|
| 29 |
+
using Severity = nvinfer1::ILogger::Severity;
|
| 30 |
+
|
| 31 |
+
class LogStreamConsumerBuffer : public std::stringbuf
|
| 32 |
+
{
|
| 33 |
+
public:
|
| 34 |
+
LogStreamConsumerBuffer(std::ostream& stream, const std::string& prefix, bool shouldLog)
|
| 35 |
+
: mOutput(stream)
|
| 36 |
+
, mPrefix(prefix)
|
| 37 |
+
, mShouldLog(shouldLog)
|
| 38 |
+
{
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
LogStreamConsumerBuffer(LogStreamConsumerBuffer&& other)
|
| 42 |
+
: mOutput(other.mOutput)
|
| 43 |
+
{
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
~LogStreamConsumerBuffer()
|
| 47 |
+
{
|
| 48 |
+
// std::streambuf::pbase() gives a pointer to the beginning of the buffered part of the output sequence
|
| 49 |
+
// std::streambuf::pptr() gives a pointer to the current position of the output sequence
|
| 50 |
+
// if the pointer to the beginning is not equal to the pointer to the current position,
|
| 51 |
+
// call putOutput() to log the output to the stream
|
| 52 |
+
if (pbase() != pptr())
|
| 53 |
+
{
|
| 54 |
+
putOutput();
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
// synchronizes the stream buffer and returns 0 on success
|
| 59 |
+
// synchronizing the stream buffer consists of inserting the buffer contents into the stream,
|
| 60 |
+
// resetting the buffer and flushing the stream
|
| 61 |
+
virtual int sync()
|
| 62 |
+
{
|
| 63 |
+
putOutput();
|
| 64 |
+
return 0;
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
void putOutput()
|
| 68 |
+
{
|
| 69 |
+
if (mShouldLog)
|
| 70 |
+
{
|
| 71 |
+
// prepend timestamp
|
| 72 |
+
std::time_t timestamp = std::time(nullptr);
|
| 73 |
+
tm* tm_local = std::localtime(×tamp);
|
| 74 |
+
std::cout << "[";
|
| 75 |
+
std::cout << std::setw(2) << std::setfill('0') << 1 + tm_local->tm_mon << "/";
|
| 76 |
+
std::cout << std::setw(2) << std::setfill('0') << tm_local->tm_mday << "/";
|
| 77 |
+
std::cout << std::setw(4) << std::setfill('0') << 1900 + tm_local->tm_year << "-";
|
| 78 |
+
std::cout << std::setw(2) << std::setfill('0') << tm_local->tm_hour << ":";
|
| 79 |
+
std::cout << std::setw(2) << std::setfill('0') << tm_local->tm_min << ":";
|
| 80 |
+
std::cout << std::setw(2) << std::setfill('0') << tm_local->tm_sec << "] ";
|
| 81 |
+
// std::stringbuf::str() gets the string contents of the buffer
|
| 82 |
+
// insert the buffer contents pre-appended by the appropriate prefix into the stream
|
| 83 |
+
mOutput << mPrefix << str();
|
| 84 |
+
// set the buffer to empty
|
| 85 |
+
str("");
|
| 86 |
+
// flush the stream
|
| 87 |
+
mOutput.flush();
|
| 88 |
+
}
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
void setShouldLog(bool shouldLog)
|
| 92 |
+
{
|
| 93 |
+
mShouldLog = shouldLog;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
private:
|
| 97 |
+
std::ostream& mOutput;
|
| 98 |
+
std::string mPrefix;
|
| 99 |
+
bool mShouldLog;
|
| 100 |
+
};
|
| 101 |
+
|
| 102 |
+
//!
|
| 103 |
+
//! \class LogStreamConsumerBase
|
| 104 |
+
//! \brief Convenience object used to initialize LogStreamConsumerBuffer before std::ostream in LogStreamConsumer
|
| 105 |
+
//!
|
| 106 |
+
class LogStreamConsumerBase
|
| 107 |
+
{
|
| 108 |
+
public:
|
| 109 |
+
LogStreamConsumerBase(std::ostream& stream, const std::string& prefix, bool shouldLog)
|
| 110 |
+
: mBuffer(stream, prefix, shouldLog)
|
| 111 |
+
{
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
protected:
|
| 115 |
+
LogStreamConsumerBuffer mBuffer;
|
| 116 |
+
};
|
| 117 |
+
|
| 118 |
+
//!
|
| 119 |
+
//! \class LogStreamConsumer
|
| 120 |
+
//! \brief Convenience object used to facilitate use of C++ stream syntax when logging messages.
|
| 121 |
+
//! Order of base classes is LogStreamConsumerBase and then std::ostream.
|
| 122 |
+
//! This is because the LogStreamConsumerBase class is used to initialize the LogStreamConsumerBuffer member field
|
| 123 |
+
//! in LogStreamConsumer and then the address of the buffer is passed to std::ostream.
|
| 124 |
+
//! This is necessary to prevent the address of an uninitialized buffer from being passed to std::ostream.
|
| 125 |
+
//! Please do not change the order of the parent classes.
|
| 126 |
+
//!
|
| 127 |
+
class LogStreamConsumer : protected LogStreamConsumerBase, public std::ostream
|
| 128 |
+
{
|
| 129 |
+
public:
|
| 130 |
+
//! \brief Creates a LogStreamConsumer which logs messages with level severity.
|
| 131 |
+
//! Reportable severity determines if the messages are severe enough to be logged.
|
| 132 |
+
LogStreamConsumer(Severity reportableSeverity, Severity severity)
|
| 133 |
+
: LogStreamConsumerBase(severityOstream(severity), severityPrefix(severity), severity <= reportableSeverity)
|
| 134 |
+
, std::ostream(&mBuffer) // links the stream buffer with the stream
|
| 135 |
+
, mShouldLog(severity <= reportableSeverity)
|
| 136 |
+
, mSeverity(severity)
|
| 137 |
+
{
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
LogStreamConsumer(LogStreamConsumer&& other)
|
| 141 |
+
: LogStreamConsumerBase(severityOstream(other.mSeverity), severityPrefix(other.mSeverity), other.mShouldLog)
|
| 142 |
+
, std::ostream(&mBuffer) // links the stream buffer with the stream
|
| 143 |
+
, mShouldLog(other.mShouldLog)
|
| 144 |
+
, mSeverity(other.mSeverity)
|
| 145 |
+
{
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
void setReportableSeverity(Severity reportableSeverity)
|
| 149 |
+
{
|
| 150 |
+
mShouldLog = mSeverity <= reportableSeverity;
|
| 151 |
+
mBuffer.setShouldLog(mShouldLog);
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
private:
|
| 155 |
+
static std::ostream& severityOstream(Severity severity)
|
| 156 |
+
{
|
| 157 |
+
return severity >= Severity::kINFO ? std::cout : std::cerr;
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
static std::string severityPrefix(Severity severity)
|
| 161 |
+
{
|
| 162 |
+
switch (severity)
|
| 163 |
+
{
|
| 164 |
+
case Severity::kINTERNAL_ERROR: return "[F] ";
|
| 165 |
+
case Severity::kERROR: return "[E] ";
|
| 166 |
+
case Severity::kWARNING: return "[W] ";
|
| 167 |
+
case Severity::kINFO: return "[I] ";
|
| 168 |
+
case Severity::kVERBOSE: return "[V] ";
|
| 169 |
+
default: assert(0); return "";
|
| 170 |
+
}
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
bool mShouldLog;
|
| 174 |
+
Severity mSeverity;
|
| 175 |
+
};
|
| 176 |
+
|
| 177 |
+
//! \class Logger
|
| 178 |
+
//!
|
| 179 |
+
//! \brief Class which manages logging of TensorRT tools and samples
|
| 180 |
+
//!
|
| 181 |
+
//! \details This class provides a common interface for TensorRT tools and samples to log information to the console,
|
| 182 |
+
//! and supports logging two types of messages:
|
| 183 |
+
//!
|
| 184 |
+
//! - Debugging messages with an associated severity (info, warning, error, or internal error/fatal)
|
| 185 |
+
//! - Test pass/fail messages
|
| 186 |
+
//!
|
| 187 |
+
//! The advantage of having all samples use this class for logging as opposed to emitting directly to stdout/stderr is
|
| 188 |
+
//! that the logic for controlling the verbosity and formatting of sample output is centralized in one location.
|
| 189 |
+
//!
|
| 190 |
+
//! In the future, this class could be extended to support dumping test results to a file in some standard format
|
| 191 |
+
//! (for example, JUnit XML), and providing additional metadata (e.g. timing the duration of a test run).
|
| 192 |
+
//!
|
| 193 |
+
//! TODO: For backwards compatibility with existing samples, this class inherits directly from the nvinfer1::ILogger
|
| 194 |
+
//! interface, which is problematic since there isn't a clean separation between messages coming from the TensorRT
|
| 195 |
+
//! library and messages coming from the sample.
|
| 196 |
+
//!
|
| 197 |
+
//! In the future (once all samples are updated to use Logger::getTRTLogger() to access the ILogger) we can refactor the
|
| 198 |
+
//! class to eliminate the inheritance and instead make the nvinfer1::ILogger implementation a member of the Logger
|
| 199 |
+
//! object.
|
| 200 |
+
|
| 201 |
+
class Logger : public nvinfer1::ILogger
|
| 202 |
+
{
|
| 203 |
+
public:
|
| 204 |
+
Logger(Severity severity = Severity::kWARNING)
|
| 205 |
+
: mReportableSeverity(severity)
|
| 206 |
+
{
|
| 207 |
+
}
|
| 208 |
+
|
| 209 |
+
//!
|
| 210 |
+
//! \enum TestResult
|
| 211 |
+
//! \brief Represents the state of a given test
|
| 212 |
+
//!
|
| 213 |
+
enum class TestResult
|
| 214 |
+
{
|
| 215 |
+
kRUNNING, //!< The test is running
|
| 216 |
+
kPASSED, //!< The test passed
|
| 217 |
+
kFAILED, //!< The test failed
|
| 218 |
+
kWAIVED //!< The test was waived
|
| 219 |
+
};
|
| 220 |
+
|
| 221 |
+
//!
|
| 222 |
+
//! \brief Forward-compatible method for retrieving the nvinfer::ILogger associated with this Logger
|
| 223 |
+
//! \return The nvinfer1::ILogger associated with this Logger
|
| 224 |
+
//!
|
| 225 |
+
//! TODO Once all samples are updated to use this method to register the logger with TensorRT,
|
| 226 |
+
//! we can eliminate the inheritance of Logger from ILogger
|
| 227 |
+
//!
|
| 228 |
+
nvinfer1::ILogger& getTRTLogger()
|
| 229 |
+
{
|
| 230 |
+
return *this;
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
//!
|
| 234 |
+
//! \brief Implementation of the nvinfer1::ILogger::log() virtual method
|
| 235 |
+
//!
|
| 236 |
+
//! Note samples should not be calling this function directly; it will eventually go away once we eliminate the
|
| 237 |
+
//! inheritance from nvinfer1::ILogger
|
| 238 |
+
//!
|
| 239 |
+
void log(Severity severity, const char* msg) override
|
| 240 |
+
{
|
| 241 |
+
LogStreamConsumer(mReportableSeverity, severity) << "[TRT] " << std::string(msg) << std::endl;
|
| 242 |
+
}
|
| 243 |
+
|
| 244 |
+
//!
|
| 245 |
+
//! \brief Method for controlling the verbosity of logging output
|
| 246 |
+
//!
|
| 247 |
+
//! \param severity The logger will only emit messages that have severity of this level or higher.
|
| 248 |
+
//!
|
| 249 |
+
void setReportableSeverity(Severity severity)
|
| 250 |
+
{
|
| 251 |
+
mReportableSeverity = severity;
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
//!
|
| 255 |
+
//! \brief Opaque handle that holds logging information for a particular test
|
| 256 |
+
//!
|
| 257 |
+
//! This object is an opaque handle to information used by the Logger to print test results.
|
| 258 |
+
//! The sample must call Logger::defineTest() in order to obtain a TestAtom that can be used
|
| 259 |
+
//! with Logger::reportTest{Start,End}().
|
| 260 |
+
//!
|
| 261 |
+
class TestAtom
|
| 262 |
+
{
|
| 263 |
+
public:
|
| 264 |
+
TestAtom(TestAtom&&) = default;
|
| 265 |
+
|
| 266 |
+
private:
|
| 267 |
+
friend class Logger;
|
| 268 |
+
|
| 269 |
+
TestAtom(bool started, const std::string& name, const std::string& cmdline)
|
| 270 |
+
: mStarted(started)
|
| 271 |
+
, mName(name)
|
| 272 |
+
, mCmdline(cmdline)
|
| 273 |
+
{
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
bool mStarted;
|
| 277 |
+
std::string mName;
|
| 278 |
+
std::string mCmdline;
|
| 279 |
+
};
|
| 280 |
+
|
| 281 |
+
//!
|
| 282 |
+
//! \brief Define a test for logging
|
| 283 |
+
//!
|
| 284 |
+
//! \param[in] name The name of the test. This should be a string starting with
|
| 285 |
+
//! "TensorRT" and containing dot-separated strings containing
|
| 286 |
+
//! the characters [A-Za-z0-9_].
|
| 287 |
+
//! For example, "TensorRT.sample_googlenet"
|
| 288 |
+
//! \param[in] cmdline The command line used to reproduce the test
|
| 289 |
+
//
|
| 290 |
+
//! \return a TestAtom that can be used in Logger::reportTest{Start,End}().
|
| 291 |
+
//!
|
| 292 |
+
static TestAtom defineTest(const std::string& name, const std::string& cmdline)
|
| 293 |
+
{
|
| 294 |
+
return TestAtom(false, name, cmdline);
|
| 295 |
+
}
|
| 296 |
+
|
| 297 |
+
//!
|
| 298 |
+
//! \brief A convenience overloaded version of defineTest() that accepts an array of command-line arguments
|
| 299 |
+
//! as input
|
| 300 |
+
//!
|
| 301 |
+
//! \param[in] name The name of the test
|
| 302 |
+
//! \param[in] argc The number of command-line arguments
|
| 303 |
+
//! \param[in] argv The array of command-line arguments (given as C strings)
|
| 304 |
+
//!
|
| 305 |
+
//! \return a TestAtom that can be used in Logger::reportTest{Start,End}().
|
| 306 |
+
static TestAtom defineTest(const std::string& name, int argc, char const* const* argv)
|
| 307 |
+
{
|
| 308 |
+
auto cmdline = genCmdlineString(argc, argv);
|
| 309 |
+
return defineTest(name, cmdline);
|
| 310 |
+
}
|
| 311 |
+
|
| 312 |
+
//!
|
| 313 |
+
//! \brief Report that a test has started.
|
| 314 |
+
//!
|
| 315 |
+
//! \pre reportTestStart() has not been called yet for the given testAtom
|
| 316 |
+
//!
|
| 317 |
+
//! \param[in] testAtom The handle to the test that has started
|
| 318 |
+
//!
|
| 319 |
+
static void reportTestStart(TestAtom& testAtom)
|
| 320 |
+
{
|
| 321 |
+
reportTestResult(testAtom, TestResult::kRUNNING);
|
| 322 |
+
assert(!testAtom.mStarted);
|
| 323 |
+
testAtom.mStarted = true;
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
//!
|
| 327 |
+
//! \brief Report that a test has ended.
|
| 328 |
+
//!
|
| 329 |
+
//! \pre reportTestStart() has been called for the given testAtom
|
| 330 |
+
//!
|
| 331 |
+
//! \param[in] testAtom The handle to the test that has ended
|
| 332 |
+
//! \param[in] result The result of the test. Should be one of TestResult::kPASSED,
|
| 333 |
+
//! TestResult::kFAILED, TestResult::kWAIVED
|
| 334 |
+
//!
|
| 335 |
+
static void reportTestEnd(const TestAtom& testAtom, TestResult result)
|
| 336 |
+
{
|
| 337 |
+
assert(result != TestResult::kRUNNING);
|
| 338 |
+
assert(testAtom.mStarted);
|
| 339 |
+
reportTestResult(testAtom, result);
|
| 340 |
+
}
|
| 341 |
+
|
| 342 |
+
static int reportPass(const TestAtom& testAtom)
|
| 343 |
+
{
|
| 344 |
+
reportTestEnd(testAtom, TestResult::kPASSED);
|
| 345 |
+
return EXIT_SUCCESS;
|
| 346 |
+
}
|
| 347 |
+
|
| 348 |
+
static int reportFail(const TestAtom& testAtom)
|
| 349 |
+
{
|
| 350 |
+
reportTestEnd(testAtom, TestResult::kFAILED);
|
| 351 |
+
return EXIT_FAILURE;
|
| 352 |
+
}
|
| 353 |
+
|
| 354 |
+
static int reportWaive(const TestAtom& testAtom)
|
| 355 |
+
{
|
| 356 |
+
reportTestEnd(testAtom, TestResult::kWAIVED);
|
| 357 |
+
return EXIT_SUCCESS;
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
static int reportTest(const TestAtom& testAtom, bool pass)
|
| 361 |
+
{
|
| 362 |
+
return pass ? reportPass(testAtom) : reportFail(testAtom);
|
| 363 |
+
}
|
| 364 |
+
|
| 365 |
+
Severity getReportableSeverity() const
|
| 366 |
+
{
|
| 367 |
+
return mReportableSeverity;
|
| 368 |
+
}
|
| 369 |
+
|
| 370 |
+
private:
|
| 371 |
+
//!
|
| 372 |
+
//! \brief returns an appropriate string for prefixing a log message with the given severity
|
| 373 |
+
//!
|
| 374 |
+
static const char* severityPrefix(Severity severity)
|
| 375 |
+
{
|
| 376 |
+
switch (severity)
|
| 377 |
+
{
|
| 378 |
+
case Severity::kINTERNAL_ERROR: return "[F] ";
|
| 379 |
+
case Severity::kERROR: return "[E] ";
|
| 380 |
+
case Severity::kWARNING: return "[W] ";
|
| 381 |
+
case Severity::kINFO: return "[I] ";
|
| 382 |
+
case Severity::kVERBOSE: return "[V] ";
|
| 383 |
+
default: assert(0); return "";
|
| 384 |
+
}
|
| 385 |
+
}
|
| 386 |
+
|
| 387 |
+
//!
|
| 388 |
+
//! \brief returns an appropriate string for prefixing a test result message with the given result
|
| 389 |
+
//!
|
| 390 |
+
static const char* testResultString(TestResult result)
|
| 391 |
+
{
|
| 392 |
+
switch (result)
|
| 393 |
+
{
|
| 394 |
+
case TestResult::kRUNNING: return "RUNNING";
|
| 395 |
+
case TestResult::kPASSED: return "PASSED";
|
| 396 |
+
case TestResult::kFAILED: return "FAILED";
|
| 397 |
+
case TestResult::kWAIVED: return "WAIVED";
|
| 398 |
+
default: assert(0); return "";
|
| 399 |
+
}
|
| 400 |
+
}
|
| 401 |
+
|
| 402 |
+
//!
|
| 403 |
+
//! \brief returns an appropriate output stream (cout or cerr) to use with the given severity
|
| 404 |
+
//!
|
| 405 |
+
static std::ostream& severityOstream(Severity severity)
|
| 406 |
+
{
|
| 407 |
+
return severity >= Severity::kINFO ? std::cout : std::cerr;
|
| 408 |
+
}
|
| 409 |
+
|
| 410 |
+
//!
|
| 411 |
+
//! \brief method that implements logging test results
|
| 412 |
+
//!
|
| 413 |
+
static void reportTestResult(const TestAtom& testAtom, TestResult result)
|
| 414 |
+
{
|
| 415 |
+
severityOstream(Severity::kINFO) << "&&&& " << testResultString(result) << " " << testAtom.mName << " # "
|
| 416 |
+
<< testAtom.mCmdline << std::endl;
|
| 417 |
+
}
|
| 418 |
+
|
| 419 |
+
//!
|
| 420 |
+
//! \brief generate a command line string from the given (argc, argv) values
|
| 421 |
+
//!
|
| 422 |
+
static std::string genCmdlineString(int argc, char const* const* argv)
|
| 423 |
+
{
|
| 424 |
+
std::stringstream ss;
|
| 425 |
+
for (int i = 0; i < argc; i++)
|
| 426 |
+
{
|
| 427 |
+
if (i > 0)
|
| 428 |
+
ss << " ";
|
| 429 |
+
ss << argv[i];
|
| 430 |
+
}
|
| 431 |
+
return ss.str();
|
| 432 |
+
}
|
| 433 |
+
|
| 434 |
+
Severity mReportableSeverity;
|
| 435 |
+
};
|
| 436 |
+
|
| 437 |
+
namespace
|
| 438 |
+
{
|
| 439 |
+
|
| 440 |
+
//!
|
| 441 |
+
//! \brief produces a LogStreamConsumer object that can be used to log messages of severity kVERBOSE
|
| 442 |
+
//!
|
| 443 |
+
//! Example usage:
|
| 444 |
+
//!
|
| 445 |
+
//! LOG_VERBOSE(logger) << "hello world" << std::endl;
|
| 446 |
+
//!
|
| 447 |
+
inline LogStreamConsumer LOG_VERBOSE(const Logger& logger)
|
| 448 |
+
{
|
| 449 |
+
return LogStreamConsumer(logger.getReportableSeverity(), Severity::kVERBOSE);
|
| 450 |
+
}
|
| 451 |
+
|
| 452 |
+
//!
|
| 453 |
+
//! \brief produces a LogStreamConsumer object that can be used to log messages of severity kINFO
|
| 454 |
+
//!
|
| 455 |
+
//! Example usage:
|
| 456 |
+
//!
|
| 457 |
+
//! LOG_INFO(logger) << "hello world" << std::endl;
|
| 458 |
+
//!
|
| 459 |
+
inline LogStreamConsumer LOG_INFO(const Logger& logger)
|
| 460 |
+
{
|
| 461 |
+
return LogStreamConsumer(logger.getReportableSeverity(), Severity::kINFO);
|
| 462 |
+
}
|
| 463 |
+
|
| 464 |
+
//!
|
| 465 |
+
//! \brief produces a LogStreamConsumer object that can be used to log messages of severity kWARNING
|
| 466 |
+
//!
|
| 467 |
+
//! Example usage:
|
| 468 |
+
//!
|
| 469 |
+
//! LOG_WARN(logger) << "hello world" << std::endl;
|
| 470 |
+
//!
|
| 471 |
+
inline LogStreamConsumer LOG_WARN(const Logger& logger)
|
| 472 |
+
{
|
| 473 |
+
return LogStreamConsumer(logger.getReportableSeverity(), Severity::kWARNING);
|
| 474 |
+
}
|
| 475 |
+
|
| 476 |
+
//!
|
| 477 |
+
//! \brief produces a LogStreamConsumer object that can be used to log messages of severity kERROR
|
| 478 |
+
//!
|
| 479 |
+
//! Example usage:
|
| 480 |
+
//!
|
| 481 |
+
//! LOG_ERROR(logger) << "hello world" << std::endl;
|
| 482 |
+
//!
|
| 483 |
+
inline LogStreamConsumer LOG_ERROR(const Logger& logger)
|
| 484 |
+
{
|
| 485 |
+
return LogStreamConsumer(logger.getReportableSeverity(), Severity::kERROR);
|
| 486 |
+
}
|
| 487 |
+
|
| 488 |
+
//!
|
| 489 |
+
//! \brief produces a LogStreamConsumer object that can be used to log messages of severity kINTERNAL_ERROR
|
| 490 |
+
// ("fatal" severity)
|
| 491 |
+
//!
|
| 492 |
+
//! Example usage:
|
| 493 |
+
//!
|
| 494 |
+
//! LOG_FATAL(logger) << "hello world" << std::endl;
|
| 495 |
+
//!
|
| 496 |
+
inline LogStreamConsumer LOG_FATAL(const Logger& logger)
|
| 497 |
+
{
|
| 498 |
+
return LogStreamConsumer(logger.getReportableSeverity(), Severity::kINTERNAL_ERROR);
|
| 499 |
+
}
|
| 500 |
+
|
| 501 |
+
} // anonymous namespace
|
| 502 |
+
|
| 503 |
+
#endif // TENSORRT_LOGGING_H
|
deploy/TensorRT/cpp/src/BYTETracker.cpp
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "BYTETracker.h"
|
| 2 |
+
#include <fstream>
|
| 3 |
+
|
| 4 |
+
BYTETracker::BYTETracker(int frame_rate, int track_buffer)
|
| 5 |
+
{
|
| 6 |
+
track_thresh = 0.5;
|
| 7 |
+
high_thresh = 0.6;
|
| 8 |
+
match_thresh = 0.8;
|
| 9 |
+
|
| 10 |
+
frame_id = 0;
|
| 11 |
+
max_time_lost = int(frame_rate / 30.0 * track_buffer);
|
| 12 |
+
cout << "Init ByteTrack!" << endl;
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
BYTETracker::~BYTETracker()
|
| 16 |
+
{
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
vector<STrack> BYTETracker::update(const vector<Object>& objects)
|
| 20 |
+
{
|
| 21 |
+
|
| 22 |
+
////////////////// Step 1: Get detections //////////////////
|
| 23 |
+
this->frame_id++;
|
| 24 |
+
vector<STrack> activated_stracks;
|
| 25 |
+
vector<STrack> refind_stracks;
|
| 26 |
+
vector<STrack> removed_stracks;
|
| 27 |
+
vector<STrack> lost_stracks;
|
| 28 |
+
vector<STrack> detections;
|
| 29 |
+
vector<STrack> detections_low;
|
| 30 |
+
|
| 31 |
+
vector<STrack> detections_cp;
|
| 32 |
+
vector<STrack> tracked_stracks_swap;
|
| 33 |
+
vector<STrack> resa, resb;
|
| 34 |
+
vector<STrack> output_stracks;
|
| 35 |
+
|
| 36 |
+
vector<STrack*> unconfirmed;
|
| 37 |
+
vector<STrack*> tracked_stracks;
|
| 38 |
+
vector<STrack*> strack_pool;
|
| 39 |
+
vector<STrack*> r_tracked_stracks;
|
| 40 |
+
|
| 41 |
+
if (objects.size() > 0)
|
| 42 |
+
{
|
| 43 |
+
for (int i = 0; i < objects.size(); i++)
|
| 44 |
+
{
|
| 45 |
+
vector<float> tlbr_;
|
| 46 |
+
tlbr_.resize(4);
|
| 47 |
+
tlbr_[0] = objects[i].rect.x;
|
| 48 |
+
tlbr_[1] = objects[i].rect.y;
|
| 49 |
+
tlbr_[2] = objects[i].rect.x + objects[i].rect.width;
|
| 50 |
+
tlbr_[3] = objects[i].rect.y + objects[i].rect.height;
|
| 51 |
+
|
| 52 |
+
float score = objects[i].prob;
|
| 53 |
+
|
| 54 |
+
STrack strack(STrack::tlbr_to_tlwh(tlbr_), score);
|
| 55 |
+
if (score >= track_thresh)
|
| 56 |
+
{
|
| 57 |
+
detections.push_back(strack);
|
| 58 |
+
}
|
| 59 |
+
else
|
| 60 |
+
{
|
| 61 |
+
detections_low.push_back(strack);
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
}
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
// Add newly detected tracklets to tracked_stracks
|
| 68 |
+
for (int i = 0; i < this->tracked_stracks.size(); i++)
|
| 69 |
+
{
|
| 70 |
+
if (!this->tracked_stracks[i].is_activated)
|
| 71 |
+
unconfirmed.push_back(&this->tracked_stracks[i]);
|
| 72 |
+
else
|
| 73 |
+
tracked_stracks.push_back(&this->tracked_stracks[i]);
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
////////////////// Step 2: First association, with IoU //////////////////
|
| 77 |
+
strack_pool = joint_stracks(tracked_stracks, this->lost_stracks);
|
| 78 |
+
STrack::multi_predict(strack_pool, this->kalman_filter);
|
| 79 |
+
|
| 80 |
+
vector<vector<float> > dists;
|
| 81 |
+
int dist_size = 0, dist_size_size = 0;
|
| 82 |
+
dists = iou_distance(strack_pool, detections, dist_size, dist_size_size);
|
| 83 |
+
|
| 84 |
+
vector<vector<int> > matches;
|
| 85 |
+
vector<int> u_track, u_detection;
|
| 86 |
+
linear_assignment(dists, dist_size, dist_size_size, match_thresh, matches, u_track, u_detection);
|
| 87 |
+
|
| 88 |
+
for (int i = 0; i < matches.size(); i++)
|
| 89 |
+
{
|
| 90 |
+
STrack *track = strack_pool[matches[i][0]];
|
| 91 |
+
STrack *det = &detections[matches[i][1]];
|
| 92 |
+
if (track->state == TrackState::Tracked)
|
| 93 |
+
{
|
| 94 |
+
track->update(*det, this->frame_id);
|
| 95 |
+
activated_stracks.push_back(*track);
|
| 96 |
+
}
|
| 97 |
+
else
|
| 98 |
+
{
|
| 99 |
+
track->re_activate(*det, this->frame_id, false);
|
| 100 |
+
refind_stracks.push_back(*track);
|
| 101 |
+
}
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
////////////////// Step 3: Second association, using low score dets //////////////////
|
| 105 |
+
for (int i = 0; i < u_detection.size(); i++)
|
| 106 |
+
{
|
| 107 |
+
detections_cp.push_back(detections[u_detection[i]]);
|
| 108 |
+
}
|
| 109 |
+
detections.clear();
|
| 110 |
+
detections.assign(detections_low.begin(), detections_low.end());
|
| 111 |
+
|
| 112 |
+
for (int i = 0; i < u_track.size(); i++)
|
| 113 |
+
{
|
| 114 |
+
if (strack_pool[u_track[i]]->state == TrackState::Tracked)
|
| 115 |
+
{
|
| 116 |
+
r_tracked_stracks.push_back(strack_pool[u_track[i]]);
|
| 117 |
+
}
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
dists.clear();
|
| 121 |
+
dists = iou_distance(r_tracked_stracks, detections, dist_size, dist_size_size);
|
| 122 |
+
|
| 123 |
+
matches.clear();
|
| 124 |
+
u_track.clear();
|
| 125 |
+
u_detection.clear();
|
| 126 |
+
linear_assignment(dists, dist_size, dist_size_size, 0.5, matches, u_track, u_detection);
|
| 127 |
+
|
| 128 |
+
for (int i = 0; i < matches.size(); i++)
|
| 129 |
+
{
|
| 130 |
+
STrack *track = r_tracked_stracks[matches[i][0]];
|
| 131 |
+
STrack *det = &detections[matches[i][1]];
|
| 132 |
+
if (track->state == TrackState::Tracked)
|
| 133 |
+
{
|
| 134 |
+
track->update(*det, this->frame_id);
|
| 135 |
+
activated_stracks.push_back(*track);
|
| 136 |
+
}
|
| 137 |
+
else
|
| 138 |
+
{
|
| 139 |
+
track->re_activate(*det, this->frame_id, false);
|
| 140 |
+
refind_stracks.push_back(*track);
|
| 141 |
+
}
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
for (int i = 0; i < u_track.size(); i++)
|
| 145 |
+
{
|
| 146 |
+
STrack *track = r_tracked_stracks[u_track[i]];
|
| 147 |
+
if (track->state != TrackState::Lost)
|
| 148 |
+
{
|
| 149 |
+
track->mark_lost();
|
| 150 |
+
lost_stracks.push_back(*track);
|
| 151 |
+
}
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
// Deal with unconfirmed tracks, usually tracks with only one beginning frame
|
| 155 |
+
detections.clear();
|
| 156 |
+
detections.assign(detections_cp.begin(), detections_cp.end());
|
| 157 |
+
|
| 158 |
+
dists.clear();
|
| 159 |
+
dists = iou_distance(unconfirmed, detections, dist_size, dist_size_size);
|
| 160 |
+
|
| 161 |
+
matches.clear();
|
| 162 |
+
vector<int> u_unconfirmed;
|
| 163 |
+
u_detection.clear();
|
| 164 |
+
linear_assignment(dists, dist_size, dist_size_size, 0.7, matches, u_unconfirmed, u_detection);
|
| 165 |
+
|
| 166 |
+
for (int i = 0; i < matches.size(); i++)
|
| 167 |
+
{
|
| 168 |
+
unconfirmed[matches[i][0]]->update(detections[matches[i][1]], this->frame_id);
|
| 169 |
+
activated_stracks.push_back(*unconfirmed[matches[i][0]]);
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
for (int i = 0; i < u_unconfirmed.size(); i++)
|
| 173 |
+
{
|
| 174 |
+
STrack *track = unconfirmed[u_unconfirmed[i]];
|
| 175 |
+
track->mark_removed();
|
| 176 |
+
removed_stracks.push_back(*track);
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
////////////////// Step 4: Init new stracks //////////////////
|
| 180 |
+
for (int i = 0; i < u_detection.size(); i++)
|
| 181 |
+
{
|
| 182 |
+
STrack *track = &detections[u_detection[i]];
|
| 183 |
+
if (track->score < this->high_thresh)
|
| 184 |
+
continue;
|
| 185 |
+
track->activate(this->kalman_filter, this->frame_id);
|
| 186 |
+
activated_stracks.push_back(*track);
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
////////////////// Step 5: Update state //////////////////
|
| 190 |
+
for (int i = 0; i < this->lost_stracks.size(); i++)
|
| 191 |
+
{
|
| 192 |
+
if (this->frame_id - this->lost_stracks[i].end_frame() > this->max_time_lost)
|
| 193 |
+
{
|
| 194 |
+
this->lost_stracks[i].mark_removed();
|
| 195 |
+
removed_stracks.push_back(this->lost_stracks[i]);
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
for (int i = 0; i < this->tracked_stracks.size(); i++)
|
| 200 |
+
{
|
| 201 |
+
if (this->tracked_stracks[i].state == TrackState::Tracked)
|
| 202 |
+
{
|
| 203 |
+
tracked_stracks_swap.push_back(this->tracked_stracks[i]);
|
| 204 |
+
}
|
| 205 |
+
}
|
| 206 |
+
this->tracked_stracks.clear();
|
| 207 |
+
this->tracked_stracks.assign(tracked_stracks_swap.begin(), tracked_stracks_swap.end());
|
| 208 |
+
|
| 209 |
+
this->tracked_stracks = joint_stracks(this->tracked_stracks, activated_stracks);
|
| 210 |
+
this->tracked_stracks = joint_stracks(this->tracked_stracks, refind_stracks);
|
| 211 |
+
|
| 212 |
+
//std::cout << activated_stracks.size() << std::endl;
|
| 213 |
+
|
| 214 |
+
this->lost_stracks = sub_stracks(this->lost_stracks, this->tracked_stracks);
|
| 215 |
+
for (int i = 0; i < lost_stracks.size(); i++)
|
| 216 |
+
{
|
| 217 |
+
this->lost_stracks.push_back(lost_stracks[i]);
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
+
this->lost_stracks = sub_stracks(this->lost_stracks, this->removed_stracks);
|
| 221 |
+
for (int i = 0; i < removed_stracks.size(); i++)
|
| 222 |
+
{
|
| 223 |
+
this->removed_stracks.push_back(removed_stracks[i]);
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
remove_duplicate_stracks(resa, resb, this->tracked_stracks, this->lost_stracks);
|
| 227 |
+
|
| 228 |
+
this->tracked_stracks.clear();
|
| 229 |
+
this->tracked_stracks.assign(resa.begin(), resa.end());
|
| 230 |
+
this->lost_stracks.clear();
|
| 231 |
+
this->lost_stracks.assign(resb.begin(), resb.end());
|
| 232 |
+
|
| 233 |
+
for (int i = 0; i < this->tracked_stracks.size(); i++)
|
| 234 |
+
{
|
| 235 |
+
if (this->tracked_stracks[i].is_activated)
|
| 236 |
+
{
|
| 237 |
+
output_stracks.push_back(this->tracked_stracks[i]);
|
| 238 |
+
}
|
| 239 |
+
}
|
| 240 |
+
return output_stracks;
|
| 241 |
+
}
|
deploy/TensorRT/cpp/src/STrack.cpp
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "STrack.h"
|
| 2 |
+
|
| 3 |
+
STrack::STrack(vector<float> tlwh_, float score)
|
| 4 |
+
{
|
| 5 |
+
_tlwh.resize(4);
|
| 6 |
+
_tlwh.assign(tlwh_.begin(), tlwh_.end());
|
| 7 |
+
|
| 8 |
+
is_activated = false;
|
| 9 |
+
track_id = 0;
|
| 10 |
+
state = TrackState::New;
|
| 11 |
+
|
| 12 |
+
tlwh.resize(4);
|
| 13 |
+
tlbr.resize(4);
|
| 14 |
+
|
| 15 |
+
static_tlwh();
|
| 16 |
+
static_tlbr();
|
| 17 |
+
frame_id = 0;
|
| 18 |
+
tracklet_len = 0;
|
| 19 |
+
this->score = score;
|
| 20 |
+
start_frame = 0;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
STrack::~STrack()
|
| 24 |
+
{
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
void STrack::activate(byte_kalman::KalmanFilter &kalman_filter, int frame_id)
|
| 28 |
+
{
|
| 29 |
+
this->kalman_filter = kalman_filter;
|
| 30 |
+
this->track_id = this->next_id();
|
| 31 |
+
|
| 32 |
+
vector<float> _tlwh_tmp(4);
|
| 33 |
+
_tlwh_tmp[0] = this->_tlwh[0];
|
| 34 |
+
_tlwh_tmp[1] = this->_tlwh[1];
|
| 35 |
+
_tlwh_tmp[2] = this->_tlwh[2];
|
| 36 |
+
_tlwh_tmp[3] = this->_tlwh[3];
|
| 37 |
+
vector<float> xyah = tlwh_to_xyah(_tlwh_tmp);
|
| 38 |
+
DETECTBOX xyah_box;
|
| 39 |
+
xyah_box[0] = xyah[0];
|
| 40 |
+
xyah_box[1] = xyah[1];
|
| 41 |
+
xyah_box[2] = xyah[2];
|
| 42 |
+
xyah_box[3] = xyah[3];
|
| 43 |
+
auto mc = this->kalman_filter.initiate(xyah_box);
|
| 44 |
+
this->mean = mc.first;
|
| 45 |
+
this->covariance = mc.second;
|
| 46 |
+
|
| 47 |
+
static_tlwh();
|
| 48 |
+
static_tlbr();
|
| 49 |
+
|
| 50 |
+
this->tracklet_len = 0;
|
| 51 |
+
this->state = TrackState::Tracked;
|
| 52 |
+
if (frame_id == 1)
|
| 53 |
+
{
|
| 54 |
+
this->is_activated = true;
|
| 55 |
+
}
|
| 56 |
+
//this->is_activated = true;
|
| 57 |
+
this->frame_id = frame_id;
|
| 58 |
+
this->start_frame = frame_id;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
void STrack::re_activate(STrack &new_track, int frame_id, bool new_id)
|
| 62 |
+
{
|
| 63 |
+
vector<float> xyah = tlwh_to_xyah(new_track.tlwh);
|
| 64 |
+
DETECTBOX xyah_box;
|
| 65 |
+
xyah_box[0] = xyah[0];
|
| 66 |
+
xyah_box[1] = xyah[1];
|
| 67 |
+
xyah_box[2] = xyah[2];
|
| 68 |
+
xyah_box[3] = xyah[3];
|
| 69 |
+
auto mc = this->kalman_filter.update(this->mean, this->covariance, xyah_box);
|
| 70 |
+
this->mean = mc.first;
|
| 71 |
+
this->covariance = mc.second;
|
| 72 |
+
|
| 73 |
+
static_tlwh();
|
| 74 |
+
static_tlbr();
|
| 75 |
+
|
| 76 |
+
this->tracklet_len = 0;
|
| 77 |
+
this->state = TrackState::Tracked;
|
| 78 |
+
this->is_activated = true;
|
| 79 |
+
this->frame_id = frame_id;
|
| 80 |
+
this->score = new_track.score;
|
| 81 |
+
if (new_id)
|
| 82 |
+
this->track_id = next_id();
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
void STrack::update(STrack &new_track, int frame_id)
|
| 86 |
+
{
|
| 87 |
+
this->frame_id = frame_id;
|
| 88 |
+
this->tracklet_len++;
|
| 89 |
+
|
| 90 |
+
vector<float> xyah = tlwh_to_xyah(new_track.tlwh);
|
| 91 |
+
DETECTBOX xyah_box;
|
| 92 |
+
xyah_box[0] = xyah[0];
|
| 93 |
+
xyah_box[1] = xyah[1];
|
| 94 |
+
xyah_box[2] = xyah[2];
|
| 95 |
+
xyah_box[3] = xyah[3];
|
| 96 |
+
|
| 97 |
+
auto mc = this->kalman_filter.update(this->mean, this->covariance, xyah_box);
|
| 98 |
+
this->mean = mc.first;
|
| 99 |
+
this->covariance = mc.second;
|
| 100 |
+
|
| 101 |
+
static_tlwh();
|
| 102 |
+
static_tlbr();
|
| 103 |
+
|
| 104 |
+
this->state = TrackState::Tracked;
|
| 105 |
+
this->is_activated = true;
|
| 106 |
+
|
| 107 |
+
this->score = new_track.score;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
void STrack::static_tlwh()
|
| 111 |
+
{
|
| 112 |
+
if (this->state == TrackState::New)
|
| 113 |
+
{
|
| 114 |
+
tlwh[0] = _tlwh[0];
|
| 115 |
+
tlwh[1] = _tlwh[1];
|
| 116 |
+
tlwh[2] = _tlwh[2];
|
| 117 |
+
tlwh[3] = _tlwh[3];
|
| 118 |
+
return;
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
tlwh[0] = mean[0];
|
| 122 |
+
tlwh[1] = mean[1];
|
| 123 |
+
tlwh[2] = mean[2];
|
| 124 |
+
tlwh[3] = mean[3];
|
| 125 |
+
|
| 126 |
+
tlwh[2] *= tlwh[3];
|
| 127 |
+
tlwh[0] -= tlwh[2] / 2;
|
| 128 |
+
tlwh[1] -= tlwh[3] / 2;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
void STrack::static_tlbr()
|
| 132 |
+
{
|
| 133 |
+
tlbr.clear();
|
| 134 |
+
tlbr.assign(tlwh.begin(), tlwh.end());
|
| 135 |
+
tlbr[2] += tlbr[0];
|
| 136 |
+
tlbr[3] += tlbr[1];
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
vector<float> STrack::tlwh_to_xyah(vector<float> tlwh_tmp)
|
| 140 |
+
{
|
| 141 |
+
vector<float> tlwh_output = tlwh_tmp;
|
| 142 |
+
tlwh_output[0] += tlwh_output[2] / 2;
|
| 143 |
+
tlwh_output[1] += tlwh_output[3] / 2;
|
| 144 |
+
tlwh_output[2] /= tlwh_output[3];
|
| 145 |
+
return tlwh_output;
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
vector<float> STrack::to_xyah()
|
| 149 |
+
{
|
| 150 |
+
return tlwh_to_xyah(tlwh);
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
vector<float> STrack::tlbr_to_tlwh(vector<float> &tlbr)
|
| 154 |
+
{
|
| 155 |
+
tlbr[2] -= tlbr[0];
|
| 156 |
+
tlbr[3] -= tlbr[1];
|
| 157 |
+
return tlbr;
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
void STrack::mark_lost()
|
| 161 |
+
{
|
| 162 |
+
state = TrackState::Lost;
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
void STrack::mark_removed()
|
| 166 |
+
{
|
| 167 |
+
state = TrackState::Removed;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
int STrack::next_id()
|
| 171 |
+
{
|
| 172 |
+
static int _count = 0;
|
| 173 |
+
_count++;
|
| 174 |
+
return _count;
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
int STrack::end_frame()
|
| 178 |
+
{
|
| 179 |
+
return this->frame_id;
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
void STrack::multi_predict(vector<STrack*> &stracks, byte_kalman::KalmanFilter &kalman_filter)
|
| 183 |
+
{
|
| 184 |
+
for (int i = 0; i < stracks.size(); i++)
|
| 185 |
+
{
|
| 186 |
+
if (stracks[i]->state != TrackState::Tracked)
|
| 187 |
+
{
|
| 188 |
+
stracks[i]->mean[7] = 0;
|
| 189 |
+
}
|
| 190 |
+
kalman_filter.predict(stracks[i]->mean, stracks[i]->covariance);
|
| 191 |
+
}
|
| 192 |
+
}
|
deploy/TensorRT/cpp/src/bytetrack.cpp
ADDED
|
@@ -0,0 +1,506 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <fstream>
|
| 2 |
+
#include <iostream>
|
| 3 |
+
#include <sstream>
|
| 4 |
+
#include <numeric>
|
| 5 |
+
#include <chrono>
|
| 6 |
+
#include <vector>
|
| 7 |
+
#include <opencv2/opencv.hpp>
|
| 8 |
+
#include <dirent.h>
|
| 9 |
+
#include "NvInfer.h"
|
| 10 |
+
#include "cuda_runtime_api.h"
|
| 11 |
+
#include "logging.h"
|
| 12 |
+
#include "BYTETracker.h"
|
| 13 |
+
|
| 14 |
+
#define CHECK(status) \
|
| 15 |
+
do\
|
| 16 |
+
{\
|
| 17 |
+
auto ret = (status);\
|
| 18 |
+
if (ret != 0)\
|
| 19 |
+
{\
|
| 20 |
+
cerr << "Cuda failure: " << ret << endl;\
|
| 21 |
+
abort();\
|
| 22 |
+
}\
|
| 23 |
+
} while (0)
|
| 24 |
+
|
| 25 |
+
#define DEVICE 0 // GPU id
|
| 26 |
+
#define NMS_THRESH 0.7
|
| 27 |
+
#define BBOX_CONF_THRESH 0.1
|
| 28 |
+
|
| 29 |
+
using namespace nvinfer1;
|
| 30 |
+
|
| 31 |
+
// stuff we know about the network and the input/output blobs
|
| 32 |
+
static const int INPUT_W = 1088;
|
| 33 |
+
static const int INPUT_H = 608;
|
| 34 |
+
const char* INPUT_BLOB_NAME = "input_0";
|
| 35 |
+
const char* OUTPUT_BLOB_NAME = "output_0";
|
| 36 |
+
static Logger gLogger;
|
| 37 |
+
|
| 38 |
+
Mat static_resize(Mat& img) {
|
| 39 |
+
float r = min(INPUT_W / (img.cols*1.0), INPUT_H / (img.rows*1.0));
|
| 40 |
+
// r = std::min(r, 1.0f);
|
| 41 |
+
int unpad_w = r * img.cols;
|
| 42 |
+
int unpad_h = r * img.rows;
|
| 43 |
+
Mat re(unpad_h, unpad_w, CV_8UC3);
|
| 44 |
+
resize(img, re, re.size());
|
| 45 |
+
Mat out(INPUT_H, INPUT_W, CV_8UC3, Scalar(114, 114, 114));
|
| 46 |
+
re.copyTo(out(Rect(0, 0, re.cols, re.rows)));
|
| 47 |
+
return out;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
struct GridAndStride
|
| 51 |
+
{
|
| 52 |
+
int grid0;
|
| 53 |
+
int grid1;
|
| 54 |
+
int stride;
|
| 55 |
+
};
|
| 56 |
+
|
| 57 |
+
static void generate_grids_and_stride(const int target_w, const int target_h, vector<int>& strides, vector<GridAndStride>& grid_strides)
|
| 58 |
+
{
|
| 59 |
+
for (auto stride : strides)
|
| 60 |
+
{
|
| 61 |
+
int num_grid_w = target_w / stride;
|
| 62 |
+
int num_grid_h = target_h / stride;
|
| 63 |
+
for (int g1 = 0; g1 < num_grid_h; g1++)
|
| 64 |
+
{
|
| 65 |
+
for (int g0 = 0; g0 < num_grid_w; g0++)
|
| 66 |
+
{
|
| 67 |
+
grid_strides.push_back((GridAndStride){g0, g1, stride});
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
static inline float intersection_area(const Object& a, const Object& b)
|
| 74 |
+
{
|
| 75 |
+
Rect_<float> inter = a.rect & b.rect;
|
| 76 |
+
return inter.area();
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
static void qsort_descent_inplace(vector<Object>& faceobjects, int left, int right)
|
| 80 |
+
{
|
| 81 |
+
int i = left;
|
| 82 |
+
int j = right;
|
| 83 |
+
float p = faceobjects[(left + right) / 2].prob;
|
| 84 |
+
|
| 85 |
+
while (i <= j)
|
| 86 |
+
{
|
| 87 |
+
while (faceobjects[i].prob > p)
|
| 88 |
+
i++;
|
| 89 |
+
|
| 90 |
+
while (faceobjects[j].prob < p)
|
| 91 |
+
j--;
|
| 92 |
+
|
| 93 |
+
if (i <= j)
|
| 94 |
+
{
|
| 95 |
+
// swap
|
| 96 |
+
swap(faceobjects[i], faceobjects[j]);
|
| 97 |
+
|
| 98 |
+
i++;
|
| 99 |
+
j--;
|
| 100 |
+
}
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
#pragma omp parallel sections
|
| 104 |
+
{
|
| 105 |
+
#pragma omp section
|
| 106 |
+
{
|
| 107 |
+
if (left < j) qsort_descent_inplace(faceobjects, left, j);
|
| 108 |
+
}
|
| 109 |
+
#pragma omp section
|
| 110 |
+
{
|
| 111 |
+
if (i < right) qsort_descent_inplace(faceobjects, i, right);
|
| 112 |
+
}
|
| 113 |
+
}
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
static void qsort_descent_inplace(vector<Object>& objects)
|
| 117 |
+
{
|
| 118 |
+
if (objects.empty())
|
| 119 |
+
return;
|
| 120 |
+
|
| 121 |
+
qsort_descent_inplace(objects, 0, objects.size() - 1);
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
static void nms_sorted_bboxes(const vector<Object>& faceobjects, vector<int>& picked, float nms_threshold)
|
| 125 |
+
{
|
| 126 |
+
picked.clear();
|
| 127 |
+
|
| 128 |
+
const int n = faceobjects.size();
|
| 129 |
+
|
| 130 |
+
vector<float> areas(n);
|
| 131 |
+
for (int i = 0; i < n; i++)
|
| 132 |
+
{
|
| 133 |
+
areas[i] = faceobjects[i].rect.area();
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
for (int i = 0; i < n; i++)
|
| 137 |
+
{
|
| 138 |
+
const Object& a = faceobjects[i];
|
| 139 |
+
|
| 140 |
+
int keep = 1;
|
| 141 |
+
for (int j = 0; j < (int)picked.size(); j++)
|
| 142 |
+
{
|
| 143 |
+
const Object& b = faceobjects[picked[j]];
|
| 144 |
+
|
| 145 |
+
// intersection over union
|
| 146 |
+
float inter_area = intersection_area(a, b);
|
| 147 |
+
float union_area = areas[i] + areas[picked[j]] - inter_area;
|
| 148 |
+
// float IoU = inter_area / union_area
|
| 149 |
+
if (inter_area / union_area > nms_threshold)
|
| 150 |
+
keep = 0;
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
if (keep)
|
| 154 |
+
picked.push_back(i);
|
| 155 |
+
}
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
static void generate_yolox_proposals(vector<GridAndStride> grid_strides, float* feat_blob, float prob_threshold, vector<Object>& objects)
|
| 160 |
+
{
|
| 161 |
+
const int num_class = 1;
|
| 162 |
+
|
| 163 |
+
const int num_anchors = grid_strides.size();
|
| 164 |
+
|
| 165 |
+
for (int anchor_idx = 0; anchor_idx < num_anchors; anchor_idx++)
|
| 166 |
+
{
|
| 167 |
+
const int grid0 = grid_strides[anchor_idx].grid0;
|
| 168 |
+
const int grid1 = grid_strides[anchor_idx].grid1;
|
| 169 |
+
const int stride = grid_strides[anchor_idx].stride;
|
| 170 |
+
|
| 171 |
+
const int basic_pos = anchor_idx * (num_class + 5);
|
| 172 |
+
|
| 173 |
+
// yolox/models/yolo_head.py decode logic
|
| 174 |
+
float x_center = (feat_blob[basic_pos+0] + grid0) * stride;
|
| 175 |
+
float y_center = (feat_blob[basic_pos+1] + grid1) * stride;
|
| 176 |
+
float w = exp(feat_blob[basic_pos+2]) * stride;
|
| 177 |
+
float h = exp(feat_blob[basic_pos+3]) * stride;
|
| 178 |
+
float x0 = x_center - w * 0.5f;
|
| 179 |
+
float y0 = y_center - h * 0.5f;
|
| 180 |
+
|
| 181 |
+
float box_objectness = feat_blob[basic_pos+4];
|
| 182 |
+
for (int class_idx = 0; class_idx < num_class; class_idx++)
|
| 183 |
+
{
|
| 184 |
+
float box_cls_score = feat_blob[basic_pos + 5 + class_idx];
|
| 185 |
+
float box_prob = box_objectness * box_cls_score;
|
| 186 |
+
if (box_prob > prob_threshold)
|
| 187 |
+
{
|
| 188 |
+
Object obj;
|
| 189 |
+
obj.rect.x = x0;
|
| 190 |
+
obj.rect.y = y0;
|
| 191 |
+
obj.rect.width = w;
|
| 192 |
+
obj.rect.height = h;
|
| 193 |
+
obj.label = class_idx;
|
| 194 |
+
obj.prob = box_prob;
|
| 195 |
+
|
| 196 |
+
objects.push_back(obj);
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
} // class loop
|
| 200 |
+
|
| 201 |
+
} // point anchor loop
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
float* blobFromImage(Mat& img){
|
| 205 |
+
cvtColor(img, img, COLOR_BGR2RGB);
|
| 206 |
+
|
| 207 |
+
float* blob = new float[img.total()*3];
|
| 208 |
+
int channels = 3;
|
| 209 |
+
int img_h = img.rows;
|
| 210 |
+
int img_w = img.cols;
|
| 211 |
+
vector<float> mean = {0.485, 0.456, 0.406};
|
| 212 |
+
vector<float> std = {0.229, 0.224, 0.225};
|
| 213 |
+
for (size_t c = 0; c < channels; c++)
|
| 214 |
+
{
|
| 215 |
+
for (size_t h = 0; h < img_h; h++)
|
| 216 |
+
{
|
| 217 |
+
for (size_t w = 0; w < img_w; w++)
|
| 218 |
+
{
|
| 219 |
+
blob[c * img_w * img_h + h * img_w + w] =
|
| 220 |
+
(((float)img.at<Vec3b>(h, w)[c]) / 255.0f - mean[c]) / std[c];
|
| 221 |
+
}
|
| 222 |
+
}
|
| 223 |
+
}
|
| 224 |
+
return blob;
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
|
| 228 |
+
static void decode_outputs(float* prob, vector<Object>& objects, float scale, const int img_w, const int img_h) {
|
| 229 |
+
vector<Object> proposals;
|
| 230 |
+
vector<int> strides = {8, 16, 32};
|
| 231 |
+
vector<GridAndStride> grid_strides;
|
| 232 |
+
generate_grids_and_stride(INPUT_W, INPUT_H, strides, grid_strides);
|
| 233 |
+
generate_yolox_proposals(grid_strides, prob, BBOX_CONF_THRESH, proposals);
|
| 234 |
+
//std::cout << "num of boxes before nms: " << proposals.size() << std::endl;
|
| 235 |
+
|
| 236 |
+
qsort_descent_inplace(proposals);
|
| 237 |
+
|
| 238 |
+
vector<int> picked;
|
| 239 |
+
nms_sorted_bboxes(proposals, picked, NMS_THRESH);
|
| 240 |
+
|
| 241 |
+
|
| 242 |
+
int count = picked.size();
|
| 243 |
+
|
| 244 |
+
//std::cout << "num of boxes: " << count << std::endl;
|
| 245 |
+
|
| 246 |
+
objects.resize(count);
|
| 247 |
+
for (int i = 0; i < count; i++)
|
| 248 |
+
{
|
| 249 |
+
objects[i] = proposals[picked[i]];
|
| 250 |
+
|
| 251 |
+
// adjust offset to original unpadded
|
| 252 |
+
float x0 = (objects[i].rect.x) / scale;
|
| 253 |
+
float y0 = (objects[i].rect.y) / scale;
|
| 254 |
+
float x1 = (objects[i].rect.x + objects[i].rect.width) / scale;
|
| 255 |
+
float y1 = (objects[i].rect.y + objects[i].rect.height) / scale;
|
| 256 |
+
|
| 257 |
+
// clip
|
| 258 |
+
// x0 = std::max(std::min(x0, (float)(img_w - 1)), 0.f);
|
| 259 |
+
// y0 = std::max(std::min(y0, (float)(img_h - 1)), 0.f);
|
| 260 |
+
// x1 = std::max(std::min(x1, (float)(img_w - 1)), 0.f);
|
| 261 |
+
// y1 = std::max(std::min(y1, (float)(img_h - 1)), 0.f);
|
| 262 |
+
|
| 263 |
+
objects[i].rect.x = x0;
|
| 264 |
+
objects[i].rect.y = y0;
|
| 265 |
+
objects[i].rect.width = x1 - x0;
|
| 266 |
+
objects[i].rect.height = y1 - y0;
|
| 267 |
+
}
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
const float color_list[80][3] =
|
| 271 |
+
{
|
| 272 |
+
{0.000, 0.447, 0.741},
|
| 273 |
+
{0.850, 0.325, 0.098},
|
| 274 |
+
{0.929, 0.694, 0.125},
|
| 275 |
+
{0.494, 0.184, 0.556},
|
| 276 |
+
{0.466, 0.674, 0.188},
|
| 277 |
+
{0.301, 0.745, 0.933},
|
| 278 |
+
{0.635, 0.078, 0.184},
|
| 279 |
+
{0.300, 0.300, 0.300},
|
| 280 |
+
{0.600, 0.600, 0.600},
|
| 281 |
+
{1.000, 0.000, 0.000},
|
| 282 |
+
{1.000, 0.500, 0.000},
|
| 283 |
+
{0.749, 0.749, 0.000},
|
| 284 |
+
{0.000, 1.000, 0.000},
|
| 285 |
+
{0.000, 0.000, 1.000},
|
| 286 |
+
{0.667, 0.000, 1.000},
|
| 287 |
+
{0.333, 0.333, 0.000},
|
| 288 |
+
{0.333, 0.667, 0.000},
|
| 289 |
+
{0.333, 1.000, 0.000},
|
| 290 |
+
{0.667, 0.333, 0.000},
|
| 291 |
+
{0.667, 0.667, 0.000},
|
| 292 |
+
{0.667, 1.000, 0.000},
|
| 293 |
+
{1.000, 0.333, 0.000},
|
| 294 |
+
{1.000, 0.667, 0.000},
|
| 295 |
+
{1.000, 1.000, 0.000},
|
| 296 |
+
{0.000, 0.333, 0.500},
|
| 297 |
+
{0.000, 0.667, 0.500},
|
| 298 |
+
{0.000, 1.000, 0.500},
|
| 299 |
+
{0.333, 0.000, 0.500},
|
| 300 |
+
{0.333, 0.333, 0.500},
|
| 301 |
+
{0.333, 0.667, 0.500},
|
| 302 |
+
{0.333, 1.000, 0.500},
|
| 303 |
+
{0.667, 0.000, 0.500},
|
| 304 |
+
{0.667, 0.333, 0.500},
|
| 305 |
+
{0.667, 0.667, 0.500},
|
| 306 |
+
{0.667, 1.000, 0.500},
|
| 307 |
+
{1.000, 0.000, 0.500},
|
| 308 |
+
{1.000, 0.333, 0.500},
|
| 309 |
+
{1.000, 0.667, 0.500},
|
| 310 |
+
{1.000, 1.000, 0.500},
|
| 311 |
+
{0.000, 0.333, 1.000},
|
| 312 |
+
{0.000, 0.667, 1.000},
|
| 313 |
+
{0.000, 1.000, 1.000},
|
| 314 |
+
{0.333, 0.000, 1.000},
|
| 315 |
+
{0.333, 0.333, 1.000},
|
| 316 |
+
{0.333, 0.667, 1.000},
|
| 317 |
+
{0.333, 1.000, 1.000},
|
| 318 |
+
{0.667, 0.000, 1.000},
|
| 319 |
+
{0.667, 0.333, 1.000},
|
| 320 |
+
{0.667, 0.667, 1.000},
|
| 321 |
+
{0.667, 1.000, 1.000},
|
| 322 |
+
{1.000, 0.000, 1.000},
|
| 323 |
+
{1.000, 0.333, 1.000},
|
| 324 |
+
{1.000, 0.667, 1.000},
|
| 325 |
+
{0.333, 0.000, 0.000},
|
| 326 |
+
{0.500, 0.000, 0.000},
|
| 327 |
+
{0.667, 0.000, 0.000},
|
| 328 |
+
{0.833, 0.000, 0.000},
|
| 329 |
+
{1.000, 0.000, 0.000},
|
| 330 |
+
{0.000, 0.167, 0.000},
|
| 331 |
+
{0.000, 0.333, 0.000},
|
| 332 |
+
{0.000, 0.500, 0.000},
|
| 333 |
+
{0.000, 0.667, 0.000},
|
| 334 |
+
{0.000, 0.833, 0.000},
|
| 335 |
+
{0.000, 1.000, 0.000},
|
| 336 |
+
{0.000, 0.000, 0.167},
|
| 337 |
+
{0.000, 0.000, 0.333},
|
| 338 |
+
{0.000, 0.000, 0.500},
|
| 339 |
+
{0.000, 0.000, 0.667},
|
| 340 |
+
{0.000, 0.000, 0.833},
|
| 341 |
+
{0.000, 0.000, 1.000},
|
| 342 |
+
{0.000, 0.000, 0.000},
|
| 343 |
+
{0.143, 0.143, 0.143},
|
| 344 |
+
{0.286, 0.286, 0.286},
|
| 345 |
+
{0.429, 0.429, 0.429},
|
| 346 |
+
{0.571, 0.571, 0.571},
|
| 347 |
+
{0.714, 0.714, 0.714},
|
| 348 |
+
{0.857, 0.857, 0.857},
|
| 349 |
+
{0.000, 0.447, 0.741},
|
| 350 |
+
{0.314, 0.717, 0.741},
|
| 351 |
+
{0.50, 0.5, 0}
|
| 352 |
+
};
|
| 353 |
+
|
| 354 |
+
void doInference(IExecutionContext& context, float* input, float* output, const int output_size, Size input_shape) {
|
| 355 |
+
const ICudaEngine& engine = context.getEngine();
|
| 356 |
+
|
| 357 |
+
// Pointers to input and output device buffers to pass to engine.
|
| 358 |
+
// Engine requires exactly IEngine::getNbBindings() number of buffers.
|
| 359 |
+
assert(engine.getNbBindings() == 2);
|
| 360 |
+
void* buffers[2];
|
| 361 |
+
|
| 362 |
+
// In order to bind the buffers, we need to know the names of the input and output tensors.
|
| 363 |
+
// Note that indices are guaranteed to be less than IEngine::getNbBindings()
|
| 364 |
+
const int inputIndex = engine.getBindingIndex(INPUT_BLOB_NAME);
|
| 365 |
+
|
| 366 |
+
assert(engine.getBindingDataType(inputIndex) == nvinfer1::DataType::kFLOAT);
|
| 367 |
+
const int outputIndex = engine.getBindingIndex(OUTPUT_BLOB_NAME);
|
| 368 |
+
assert(engine.getBindingDataType(outputIndex) == nvinfer1::DataType::kFLOAT);
|
| 369 |
+
int mBatchSize = engine.getMaxBatchSize();
|
| 370 |
+
|
| 371 |
+
// Create GPU buffers on device
|
| 372 |
+
CHECK(cudaMalloc(&buffers[inputIndex], 3 * input_shape.height * input_shape.width * sizeof(float)));
|
| 373 |
+
CHECK(cudaMalloc(&buffers[outputIndex], output_size*sizeof(float)));
|
| 374 |
+
|
| 375 |
+
// Create stream
|
| 376 |
+
cudaStream_t stream;
|
| 377 |
+
CHECK(cudaStreamCreate(&stream));
|
| 378 |
+
|
| 379 |
+
// DMA input batch data to device, infer on the batch asynchronously, and DMA output back to host
|
| 380 |
+
CHECK(cudaMemcpyAsync(buffers[inputIndex], input, 3 * input_shape.height * input_shape.width * sizeof(float), cudaMemcpyHostToDevice, stream));
|
| 381 |
+
context.enqueue(1, buffers, stream, nullptr);
|
| 382 |
+
CHECK(cudaMemcpyAsync(output, buffers[outputIndex], output_size * sizeof(float), cudaMemcpyDeviceToHost, stream));
|
| 383 |
+
cudaStreamSynchronize(stream);
|
| 384 |
+
|
| 385 |
+
// Release stream and buffers
|
| 386 |
+
cudaStreamDestroy(stream);
|
| 387 |
+
CHECK(cudaFree(buffers[inputIndex]));
|
| 388 |
+
CHECK(cudaFree(buffers[outputIndex]));
|
| 389 |
+
}
|
| 390 |
+
|
| 391 |
+
int main(int argc, char** argv) {
|
| 392 |
+
cudaSetDevice(DEVICE);
|
| 393 |
+
|
| 394 |
+
// create a model using the API directly and serialize it to a stream
|
| 395 |
+
char *trtModelStream{nullptr};
|
| 396 |
+
size_t size{0};
|
| 397 |
+
|
| 398 |
+
if (argc == 4 && string(argv[2]) == "-i") {
|
| 399 |
+
const string engine_file_path {argv[1]};
|
| 400 |
+
ifstream file(engine_file_path, ios::binary);
|
| 401 |
+
if (file.good()) {
|
| 402 |
+
file.seekg(0, file.end);
|
| 403 |
+
size = file.tellg();
|
| 404 |
+
file.seekg(0, file.beg);
|
| 405 |
+
trtModelStream = new char[size];
|
| 406 |
+
assert(trtModelStream);
|
| 407 |
+
file.read(trtModelStream, size);
|
| 408 |
+
file.close();
|
| 409 |
+
}
|
| 410 |
+
} else {
|
| 411 |
+
cerr << "arguments not right!" << endl;
|
| 412 |
+
cerr << "run 'python3 tools/trt.py -f exps/example/mot/yolox_s_mix_det.py -c pretrained/bytetrack_s_mot17.pth.tar' to serialize model first!" << std::endl;
|
| 413 |
+
cerr << "Then use the following command:" << endl;
|
| 414 |
+
cerr << "cd demo/TensorRT/cpp/build" << endl;
|
| 415 |
+
cerr << "./bytetrack ../../../../YOLOX_outputs/yolox_s_mix_det/model_trt.engine -i ../../../../videos/palace.mp4 // deserialize file and run inference" << std::endl;
|
| 416 |
+
return -1;
|
| 417 |
+
}
|
| 418 |
+
const string input_video_path {argv[3]};
|
| 419 |
+
|
| 420 |
+
IRuntime* runtime = createInferRuntime(gLogger);
|
| 421 |
+
assert(runtime != nullptr);
|
| 422 |
+
ICudaEngine* engine = runtime->deserializeCudaEngine(trtModelStream, size);
|
| 423 |
+
assert(engine != nullptr);
|
| 424 |
+
IExecutionContext* context = engine->createExecutionContext();
|
| 425 |
+
assert(context != nullptr);
|
| 426 |
+
delete[] trtModelStream;
|
| 427 |
+
auto out_dims = engine->getBindingDimensions(1);
|
| 428 |
+
auto output_size = 1;
|
| 429 |
+
for(int j=0;j<out_dims.nbDims;j++) {
|
| 430 |
+
output_size *= out_dims.d[j];
|
| 431 |
+
}
|
| 432 |
+
static float* prob = new float[output_size];
|
| 433 |
+
|
| 434 |
+
VideoCapture cap(input_video_path);
|
| 435 |
+
if (!cap.isOpened())
|
| 436 |
+
return 0;
|
| 437 |
+
|
| 438 |
+
int img_w = cap.get(CV_CAP_PROP_FRAME_WIDTH);
|
| 439 |
+
int img_h = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
|
| 440 |
+
int fps = cap.get(CV_CAP_PROP_FPS);
|
| 441 |
+
long nFrame = static_cast<long>(cap.get(CV_CAP_PROP_FRAME_COUNT));
|
| 442 |
+
cout << "Total frames: " << nFrame << endl;
|
| 443 |
+
|
| 444 |
+
VideoWriter writer("demo.mp4", CV_FOURCC('m', 'p', '4', 'v'), fps, Size(img_w, img_h));
|
| 445 |
+
|
| 446 |
+
Mat img;
|
| 447 |
+
BYTETracker tracker(fps, 30);
|
| 448 |
+
int num_frames = 0;
|
| 449 |
+
int total_ms = 0;
|
| 450 |
+
while (true)
|
| 451 |
+
{
|
| 452 |
+
if(!cap.read(img))
|
| 453 |
+
break;
|
| 454 |
+
num_frames ++;
|
| 455 |
+
if (num_frames % 20 == 0)
|
| 456 |
+
{
|
| 457 |
+
cout << "Processing frame " << num_frames << " (" << num_frames * 1000000 / total_ms << " fps)" << endl;
|
| 458 |
+
}
|
| 459 |
+
if (img.empty())
|
| 460 |
+
break;
|
| 461 |
+
Mat pr_img = static_resize(img);
|
| 462 |
+
|
| 463 |
+
float* blob;
|
| 464 |
+
blob = blobFromImage(pr_img);
|
| 465 |
+
float scale = min(INPUT_W / (img.cols*1.0), INPUT_H / (img.rows*1.0));
|
| 466 |
+
|
| 467 |
+
// run inference
|
| 468 |
+
auto start = chrono::system_clock::now();
|
| 469 |
+
doInference(*context, blob, prob, output_size, pr_img.size());
|
| 470 |
+
vector<Object> objects;
|
| 471 |
+
decode_outputs(prob, objects, scale, img_w, img_h);
|
| 472 |
+
vector<STrack> output_stracks = tracker.update(objects);
|
| 473 |
+
auto end = chrono::system_clock::now();
|
| 474 |
+
total_ms = total_ms + chrono::duration_cast<chrono::microseconds>(end - start).count();
|
| 475 |
+
|
| 476 |
+
for (int i = 0; i < output_stracks.size(); i++)
|
| 477 |
+
{
|
| 478 |
+
vector<float> tlwh = output_stracks[i].tlwh;
|
| 479 |
+
bool vertical = tlwh[2] / tlwh[3] > 1.6;
|
| 480 |
+
if (tlwh[2] * tlwh[3] > 20 && !vertical)
|
| 481 |
+
{
|
| 482 |
+
Scalar s = tracker.get_color(output_stracks[i].track_id);
|
| 483 |
+
putText(img, format("%d", output_stracks[i].track_id), Point(tlwh[0], tlwh[1] - 5),
|
| 484 |
+
0, 0.6, Scalar(0, 0, 255), 2, LINE_AA);
|
| 485 |
+
rectangle(img, Rect(tlwh[0], tlwh[1], tlwh[2], tlwh[3]), s, 2);
|
| 486 |
+
}
|
| 487 |
+
}
|
| 488 |
+
putText(img, format("frame: %d fps: %d num: %d", num_frames, num_frames * 1000000 / total_ms, output_stracks.size()),
|
| 489 |
+
Point(0, 30), 0, 0.6, Scalar(0, 0, 255), 2, LINE_AA);
|
| 490 |
+
writer.write(img);
|
| 491 |
+
|
| 492 |
+
delete blob;
|
| 493 |
+
char c = waitKey(1);
|
| 494 |
+
if (c > 0)
|
| 495 |
+
{
|
| 496 |
+
break;
|
| 497 |
+
}
|
| 498 |
+
}
|
| 499 |
+
cap.release();
|
| 500 |
+
cout << "FPS: " << num_frames * 1000000 / total_ms << endl;
|
| 501 |
+
// destroy the engine
|
| 502 |
+
context->destroy();
|
| 503 |
+
engine->destroy();
|
| 504 |
+
runtime->destroy();
|
| 505 |
+
return 0;
|
| 506 |
+
}
|
deploy/TensorRT/cpp/src/kalmanFilter.cpp
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "kalmanFilter.h"
|
| 2 |
+
#include <Eigen/Cholesky>
|
| 3 |
+
|
| 4 |
+
namespace byte_kalman
|
| 5 |
+
{
|
| 6 |
+
const double KalmanFilter::chi2inv95[10] = {
|
| 7 |
+
0,
|
| 8 |
+
3.8415,
|
| 9 |
+
5.9915,
|
| 10 |
+
7.8147,
|
| 11 |
+
9.4877,
|
| 12 |
+
11.070,
|
| 13 |
+
12.592,
|
| 14 |
+
14.067,
|
| 15 |
+
15.507,
|
| 16 |
+
16.919
|
| 17 |
+
};
|
| 18 |
+
KalmanFilter::KalmanFilter()
|
| 19 |
+
{
|
| 20 |
+
int ndim = 4;
|
| 21 |
+
double dt = 1.;
|
| 22 |
+
|
| 23 |
+
_motion_mat = Eigen::MatrixXf::Identity(8, 8);
|
| 24 |
+
for (int i = 0; i < ndim; i++) {
|
| 25 |
+
_motion_mat(i, ndim + i) = dt;
|
| 26 |
+
}
|
| 27 |
+
_update_mat = Eigen::MatrixXf::Identity(4, 8);
|
| 28 |
+
|
| 29 |
+
this->_std_weight_position = 1. / 20;
|
| 30 |
+
this->_std_weight_velocity = 1. / 160;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
KAL_DATA KalmanFilter::initiate(const DETECTBOX &measurement)
|
| 34 |
+
{
|
| 35 |
+
DETECTBOX mean_pos = measurement;
|
| 36 |
+
DETECTBOX mean_vel;
|
| 37 |
+
for (int i = 0; i < 4; i++) mean_vel(i) = 0;
|
| 38 |
+
|
| 39 |
+
KAL_MEAN mean;
|
| 40 |
+
for (int i = 0; i < 8; i++) {
|
| 41 |
+
if (i < 4) mean(i) = mean_pos(i);
|
| 42 |
+
else mean(i) = mean_vel(i - 4);
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
KAL_MEAN std;
|
| 46 |
+
std(0) = 2 * _std_weight_position * measurement[3];
|
| 47 |
+
std(1) = 2 * _std_weight_position * measurement[3];
|
| 48 |
+
std(2) = 1e-2;
|
| 49 |
+
std(3) = 2 * _std_weight_position * measurement[3];
|
| 50 |
+
std(4) = 10 * _std_weight_velocity * measurement[3];
|
| 51 |
+
std(5) = 10 * _std_weight_velocity * measurement[3];
|
| 52 |
+
std(6) = 1e-5;
|
| 53 |
+
std(7) = 10 * _std_weight_velocity * measurement[3];
|
| 54 |
+
|
| 55 |
+
KAL_MEAN tmp = std.array().square();
|
| 56 |
+
KAL_COVA var = tmp.asDiagonal();
|
| 57 |
+
return std::make_pair(mean, var);
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
void KalmanFilter::predict(KAL_MEAN &mean, KAL_COVA &covariance)
|
| 61 |
+
{
|
| 62 |
+
//revise the data;
|
| 63 |
+
DETECTBOX std_pos;
|
| 64 |
+
std_pos << _std_weight_position * mean(3),
|
| 65 |
+
_std_weight_position * mean(3),
|
| 66 |
+
1e-2,
|
| 67 |
+
_std_weight_position * mean(3);
|
| 68 |
+
DETECTBOX std_vel;
|
| 69 |
+
std_vel << _std_weight_velocity * mean(3),
|
| 70 |
+
_std_weight_velocity * mean(3),
|
| 71 |
+
1e-5,
|
| 72 |
+
_std_weight_velocity * mean(3);
|
| 73 |
+
KAL_MEAN tmp;
|
| 74 |
+
tmp.block<1, 4>(0, 0) = std_pos;
|
| 75 |
+
tmp.block<1, 4>(0, 4) = std_vel;
|
| 76 |
+
tmp = tmp.array().square();
|
| 77 |
+
KAL_COVA motion_cov = tmp.asDiagonal();
|
| 78 |
+
KAL_MEAN mean1 = this->_motion_mat * mean.transpose();
|
| 79 |
+
KAL_COVA covariance1 = this->_motion_mat * covariance *(_motion_mat.transpose());
|
| 80 |
+
covariance1 += motion_cov;
|
| 81 |
+
|
| 82 |
+
mean = mean1;
|
| 83 |
+
covariance = covariance1;
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
KAL_HDATA KalmanFilter::project(const KAL_MEAN &mean, const KAL_COVA &covariance)
|
| 87 |
+
{
|
| 88 |
+
DETECTBOX std;
|
| 89 |
+
std << _std_weight_position * mean(3), _std_weight_position * mean(3),
|
| 90 |
+
1e-1, _std_weight_position * mean(3);
|
| 91 |
+
KAL_HMEAN mean1 = _update_mat * mean.transpose();
|
| 92 |
+
KAL_HCOVA covariance1 = _update_mat * covariance * (_update_mat.transpose());
|
| 93 |
+
Eigen::Matrix<float, 4, 4> diag = std.asDiagonal();
|
| 94 |
+
diag = diag.array().square().matrix();
|
| 95 |
+
covariance1 += diag;
|
| 96 |
+
// covariance1.diagonal() << diag;
|
| 97 |
+
return std::make_pair(mean1, covariance1);
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
KAL_DATA
|
| 101 |
+
KalmanFilter::update(
|
| 102 |
+
const KAL_MEAN &mean,
|
| 103 |
+
const KAL_COVA &covariance,
|
| 104 |
+
const DETECTBOX &measurement)
|
| 105 |
+
{
|
| 106 |
+
KAL_HDATA pa = project(mean, covariance);
|
| 107 |
+
KAL_HMEAN projected_mean = pa.first;
|
| 108 |
+
KAL_HCOVA projected_cov = pa.second;
|
| 109 |
+
|
| 110 |
+
//chol_factor, lower =
|
| 111 |
+
//scipy.linalg.cho_factor(projected_cov, lower=True, check_finite=False)
|
| 112 |
+
//kalmain_gain =
|
| 113 |
+
//scipy.linalg.cho_solve((cho_factor, lower),
|
| 114 |
+
//np.dot(covariance, self._upadte_mat.T).T,
|
| 115 |
+
//check_finite=False).T
|
| 116 |
+
Eigen::Matrix<float, 4, 8> B = (covariance * (_update_mat.transpose())).transpose();
|
| 117 |
+
Eigen::Matrix<float, 8, 4> kalman_gain = (projected_cov.llt().solve(B)).transpose(); // eg.8x4
|
| 118 |
+
Eigen::Matrix<float, 1, 4> innovation = measurement - projected_mean; //eg.1x4
|
| 119 |
+
auto tmp = innovation * (kalman_gain.transpose());
|
| 120 |
+
KAL_MEAN new_mean = (mean.array() + tmp.array()).matrix();
|
| 121 |
+
KAL_COVA new_covariance = covariance - kalman_gain * projected_cov*(kalman_gain.transpose());
|
| 122 |
+
return std::make_pair(new_mean, new_covariance);
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
Eigen::Matrix<float, 1, -1>
|
| 126 |
+
KalmanFilter::gating_distance(
|
| 127 |
+
const KAL_MEAN &mean,
|
| 128 |
+
const KAL_COVA &covariance,
|
| 129 |
+
const std::vector<DETECTBOX> &measurements,
|
| 130 |
+
bool only_position)
|
| 131 |
+
{
|
| 132 |
+
KAL_HDATA pa = this->project(mean, covariance);
|
| 133 |
+
if (only_position) {
|
| 134 |
+
printf("not implement!");
|
| 135 |
+
exit(0);
|
| 136 |
+
}
|
| 137 |
+
KAL_HMEAN mean1 = pa.first;
|
| 138 |
+
KAL_HCOVA covariance1 = pa.second;
|
| 139 |
+
|
| 140 |
+
// Eigen::Matrix<float, -1, 4, Eigen::RowMajor> d(size, 4);
|
| 141 |
+
DETECTBOXSS d(measurements.size(), 4);
|
| 142 |
+
int pos = 0;
|
| 143 |
+
for (DETECTBOX box : measurements) {
|
| 144 |
+
d.row(pos++) = box - mean1;
|
| 145 |
+
}
|
| 146 |
+
Eigen::Matrix<float, -1, -1, Eigen::RowMajor> factor = covariance1.llt().matrixL();
|
| 147 |
+
Eigen::Matrix<float, -1, -1> z = factor.triangularView<Eigen::Lower>().solve<Eigen::OnTheRight>(d).transpose();
|
| 148 |
+
auto zz = ((z.array())*(z.array())).matrix();
|
| 149 |
+
auto square_maha = zz.colwise().sum();
|
| 150 |
+
return square_maha;
|
| 151 |
+
}
|
| 152 |
+
}
|
deploy/TensorRT/cpp/src/lapjv.cpp
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <stdio.h>
|
| 2 |
+
#include <stdlib.h>
|
| 3 |
+
#include <string.h>
|
| 4 |
+
|
| 5 |
+
#include "lapjv.h"
|
| 6 |
+
|
| 7 |
+
/** Column-reduction and reduction transfer for a dense cost matrix.
|
| 8 |
+
*/
|
| 9 |
+
int_t _ccrrt_dense(const uint_t n, cost_t *cost[],
|
| 10 |
+
int_t *free_rows, int_t *x, int_t *y, cost_t *v)
|
| 11 |
+
{
|
| 12 |
+
int_t n_free_rows;
|
| 13 |
+
boolean *unique;
|
| 14 |
+
|
| 15 |
+
for (uint_t i = 0; i < n; i++) {
|
| 16 |
+
x[i] = -1;
|
| 17 |
+
v[i] = LARGE;
|
| 18 |
+
y[i] = 0;
|
| 19 |
+
}
|
| 20 |
+
for (uint_t i = 0; i < n; i++) {
|
| 21 |
+
for (uint_t j = 0; j < n; j++) {
|
| 22 |
+
const cost_t c = cost[i][j];
|
| 23 |
+
if (c < v[j]) {
|
| 24 |
+
v[j] = c;
|
| 25 |
+
y[j] = i;
|
| 26 |
+
}
|
| 27 |
+
PRINTF("i=%d, j=%d, c[i,j]=%f, v[j]=%f y[j]=%d\n", i, j, c, v[j], y[j]);
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
PRINT_COST_ARRAY(v, n);
|
| 31 |
+
PRINT_INDEX_ARRAY(y, n);
|
| 32 |
+
NEW(unique, boolean, n);
|
| 33 |
+
memset(unique, TRUE, n);
|
| 34 |
+
{
|
| 35 |
+
int_t j = n;
|
| 36 |
+
do {
|
| 37 |
+
j--;
|
| 38 |
+
const int_t i = y[j];
|
| 39 |
+
if (x[i] < 0) {
|
| 40 |
+
x[i] = j;
|
| 41 |
+
}
|
| 42 |
+
else {
|
| 43 |
+
unique[i] = FALSE;
|
| 44 |
+
y[j] = -1;
|
| 45 |
+
}
|
| 46 |
+
} while (j > 0);
|
| 47 |
+
}
|
| 48 |
+
n_free_rows = 0;
|
| 49 |
+
for (uint_t i = 0; i < n; i++) {
|
| 50 |
+
if (x[i] < 0) {
|
| 51 |
+
free_rows[n_free_rows++] = i;
|
| 52 |
+
}
|
| 53 |
+
else if (unique[i]) {
|
| 54 |
+
const int_t j = x[i];
|
| 55 |
+
cost_t min = LARGE;
|
| 56 |
+
for (uint_t j2 = 0; j2 < n; j2++) {
|
| 57 |
+
if (j2 == (uint_t)j) {
|
| 58 |
+
continue;
|
| 59 |
+
}
|
| 60 |
+
const cost_t c = cost[i][j2] - v[j2];
|
| 61 |
+
if (c < min) {
|
| 62 |
+
min = c;
|
| 63 |
+
}
|
| 64 |
+
}
|
| 65 |
+
PRINTF("v[%d] = %f - %f\n", j, v[j], min);
|
| 66 |
+
v[j] -= min;
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
FREE(unique);
|
| 70 |
+
return n_free_rows;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
/** Augmenting row reduction for a dense cost matrix.
|
| 75 |
+
*/
|
| 76 |
+
int_t _carr_dense(
|
| 77 |
+
const uint_t n, cost_t *cost[],
|
| 78 |
+
const uint_t n_free_rows,
|
| 79 |
+
int_t *free_rows, int_t *x, int_t *y, cost_t *v)
|
| 80 |
+
{
|
| 81 |
+
uint_t current = 0;
|
| 82 |
+
int_t new_free_rows = 0;
|
| 83 |
+
uint_t rr_cnt = 0;
|
| 84 |
+
PRINT_INDEX_ARRAY(x, n);
|
| 85 |
+
PRINT_INDEX_ARRAY(y, n);
|
| 86 |
+
PRINT_COST_ARRAY(v, n);
|
| 87 |
+
PRINT_INDEX_ARRAY(free_rows, n_free_rows);
|
| 88 |
+
while (current < n_free_rows) {
|
| 89 |
+
int_t i0;
|
| 90 |
+
int_t j1, j2;
|
| 91 |
+
cost_t v1, v2, v1_new;
|
| 92 |
+
boolean v1_lowers;
|
| 93 |
+
|
| 94 |
+
rr_cnt++;
|
| 95 |
+
PRINTF("current = %d rr_cnt = %d\n", current, rr_cnt);
|
| 96 |
+
const int_t free_i = free_rows[current++];
|
| 97 |
+
j1 = 0;
|
| 98 |
+
v1 = cost[free_i][0] - v[0];
|
| 99 |
+
j2 = -1;
|
| 100 |
+
v2 = LARGE;
|
| 101 |
+
for (uint_t j = 1; j < n; j++) {
|
| 102 |
+
PRINTF("%d = %f %d = %f\n", j1, v1, j2, v2);
|
| 103 |
+
const cost_t c = cost[free_i][j] - v[j];
|
| 104 |
+
if (c < v2) {
|
| 105 |
+
if (c >= v1) {
|
| 106 |
+
v2 = c;
|
| 107 |
+
j2 = j;
|
| 108 |
+
}
|
| 109 |
+
else {
|
| 110 |
+
v2 = v1;
|
| 111 |
+
v1 = c;
|
| 112 |
+
j2 = j1;
|
| 113 |
+
j1 = j;
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
}
|
| 117 |
+
i0 = y[j1];
|
| 118 |
+
v1_new = v[j1] - (v2 - v1);
|
| 119 |
+
v1_lowers = v1_new < v[j1];
|
| 120 |
+
PRINTF("%d %d 1=%d,%f 2=%d,%f v1'=%f(%d,%g) \n", free_i, i0, j1, v1, j2, v2, v1_new, v1_lowers, v[j1] - v1_new);
|
| 121 |
+
if (rr_cnt < current * n) {
|
| 122 |
+
if (v1_lowers) {
|
| 123 |
+
v[j1] = v1_new;
|
| 124 |
+
}
|
| 125 |
+
else if (i0 >= 0 && j2 >= 0) {
|
| 126 |
+
j1 = j2;
|
| 127 |
+
i0 = y[j2];
|
| 128 |
+
}
|
| 129 |
+
if (i0 >= 0) {
|
| 130 |
+
if (v1_lowers) {
|
| 131 |
+
free_rows[--current] = i0;
|
| 132 |
+
}
|
| 133 |
+
else {
|
| 134 |
+
free_rows[new_free_rows++] = i0;
|
| 135 |
+
}
|
| 136 |
+
}
|
| 137 |
+
}
|
| 138 |
+
else {
|
| 139 |
+
PRINTF("rr_cnt=%d >= %d (current=%d * n=%d)\n", rr_cnt, current * n, current, n);
|
| 140 |
+
if (i0 >= 0) {
|
| 141 |
+
free_rows[new_free_rows++] = i0;
|
| 142 |
+
}
|
| 143 |
+
}
|
| 144 |
+
x[free_i] = j1;
|
| 145 |
+
y[j1] = free_i;
|
| 146 |
+
}
|
| 147 |
+
return new_free_rows;
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
/** Find columns with minimum d[j] and put them on the SCAN list.
|
| 152 |
+
*/
|
| 153 |
+
uint_t _find_dense(const uint_t n, uint_t lo, cost_t *d, int_t *cols, int_t *y)
|
| 154 |
+
{
|
| 155 |
+
uint_t hi = lo + 1;
|
| 156 |
+
cost_t mind = d[cols[lo]];
|
| 157 |
+
for (uint_t k = hi; k < n; k++) {
|
| 158 |
+
int_t j = cols[k];
|
| 159 |
+
if (d[j] <= mind) {
|
| 160 |
+
if (d[j] < mind) {
|
| 161 |
+
hi = lo;
|
| 162 |
+
mind = d[j];
|
| 163 |
+
}
|
| 164 |
+
cols[k] = cols[hi];
|
| 165 |
+
cols[hi++] = j;
|
| 166 |
+
}
|
| 167 |
+
}
|
| 168 |
+
return hi;
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
// Scan all columns in TODO starting from arbitrary column in SCAN
|
| 173 |
+
// and try to decrease d of the TODO columns using the SCAN column.
|
| 174 |
+
int_t _scan_dense(const uint_t n, cost_t *cost[],
|
| 175 |
+
uint_t *plo, uint_t*phi,
|
| 176 |
+
cost_t *d, int_t *cols, int_t *pred,
|
| 177 |
+
int_t *y, cost_t *v)
|
| 178 |
+
{
|
| 179 |
+
uint_t lo = *plo;
|
| 180 |
+
uint_t hi = *phi;
|
| 181 |
+
cost_t h, cred_ij;
|
| 182 |
+
|
| 183 |
+
while (lo != hi) {
|
| 184 |
+
int_t j = cols[lo++];
|
| 185 |
+
const int_t i = y[j];
|
| 186 |
+
const cost_t mind = d[j];
|
| 187 |
+
h = cost[i][j] - v[j] - mind;
|
| 188 |
+
PRINTF("i=%d j=%d h=%f\n", i, j, h);
|
| 189 |
+
// For all columns in TODO
|
| 190 |
+
for (uint_t k = hi; k < n; k++) {
|
| 191 |
+
j = cols[k];
|
| 192 |
+
cred_ij = cost[i][j] - v[j] - h;
|
| 193 |
+
if (cred_ij < d[j]) {
|
| 194 |
+
d[j] = cred_ij;
|
| 195 |
+
pred[j] = i;
|
| 196 |
+
if (cred_ij == mind) {
|
| 197 |
+
if (y[j] < 0) {
|
| 198 |
+
return j;
|
| 199 |
+
}
|
| 200 |
+
cols[k] = cols[hi];
|
| 201 |
+
cols[hi++] = j;
|
| 202 |
+
}
|
| 203 |
+
}
|
| 204 |
+
}
|
| 205 |
+
}
|
| 206 |
+
*plo = lo;
|
| 207 |
+
*phi = hi;
|
| 208 |
+
return -1;
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
/** Single iteration of modified Dijkstra shortest path algorithm as explained in the JV paper.
|
| 213 |
+
*
|
| 214 |
+
* This is a dense matrix version.
|
| 215 |
+
*
|
| 216 |
+
* \return The closest free column index.
|
| 217 |
+
*/
|
| 218 |
+
int_t find_path_dense(
|
| 219 |
+
const uint_t n, cost_t *cost[],
|
| 220 |
+
const int_t start_i,
|
| 221 |
+
int_t *y, cost_t *v,
|
| 222 |
+
int_t *pred)
|
| 223 |
+
{
|
| 224 |
+
uint_t lo = 0, hi = 0;
|
| 225 |
+
int_t final_j = -1;
|
| 226 |
+
uint_t n_ready = 0;
|
| 227 |
+
int_t *cols;
|
| 228 |
+
cost_t *d;
|
| 229 |
+
|
| 230 |
+
NEW(cols, int_t, n);
|
| 231 |
+
NEW(d, cost_t, n);
|
| 232 |
+
|
| 233 |
+
for (uint_t i = 0; i < n; i++) {
|
| 234 |
+
cols[i] = i;
|
| 235 |
+
pred[i] = start_i;
|
| 236 |
+
d[i] = cost[start_i][i] - v[i];
|
| 237 |
+
}
|
| 238 |
+
PRINT_COST_ARRAY(d, n);
|
| 239 |
+
while (final_j == -1) {
|
| 240 |
+
// No columns left on the SCAN list.
|
| 241 |
+
if (lo == hi) {
|
| 242 |
+
PRINTF("%d..%d -> find\n", lo, hi);
|
| 243 |
+
n_ready = lo;
|
| 244 |
+
hi = _find_dense(n, lo, d, cols, y);
|
| 245 |
+
PRINTF("check %d..%d\n", lo, hi);
|
| 246 |
+
PRINT_INDEX_ARRAY(cols, n);
|
| 247 |
+
for (uint_t k = lo; k < hi; k++) {
|
| 248 |
+
const int_t j = cols[k];
|
| 249 |
+
if (y[j] < 0) {
|
| 250 |
+
final_j = j;
|
| 251 |
+
}
|
| 252 |
+
}
|
| 253 |
+
}
|
| 254 |
+
if (final_j == -1) {
|
| 255 |
+
PRINTF("%d..%d -> scan\n", lo, hi);
|
| 256 |
+
final_j = _scan_dense(
|
| 257 |
+
n, cost, &lo, &hi, d, cols, pred, y, v);
|
| 258 |
+
PRINT_COST_ARRAY(d, n);
|
| 259 |
+
PRINT_INDEX_ARRAY(cols, n);
|
| 260 |
+
PRINT_INDEX_ARRAY(pred, n);
|
| 261 |
+
}
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
PRINTF("found final_j=%d\n", final_j);
|
| 265 |
+
PRINT_INDEX_ARRAY(cols, n);
|
| 266 |
+
{
|
| 267 |
+
const cost_t mind = d[cols[lo]];
|
| 268 |
+
for (uint_t k = 0; k < n_ready; k++) {
|
| 269 |
+
const int_t j = cols[k];
|
| 270 |
+
v[j] += d[j] - mind;
|
| 271 |
+
}
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
FREE(cols);
|
| 275 |
+
FREE(d);
|
| 276 |
+
|
| 277 |
+
return final_j;
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
|
| 281 |
+
/** Augment for a dense cost matrix.
|
| 282 |
+
*/
|
| 283 |
+
int_t _ca_dense(
|
| 284 |
+
const uint_t n, cost_t *cost[],
|
| 285 |
+
const uint_t n_free_rows,
|
| 286 |
+
int_t *free_rows, int_t *x, int_t *y, cost_t *v)
|
| 287 |
+
{
|
| 288 |
+
int_t *pred;
|
| 289 |
+
|
| 290 |
+
NEW(pred, int_t, n);
|
| 291 |
+
|
| 292 |
+
for (int_t *pfree_i = free_rows; pfree_i < free_rows + n_free_rows; pfree_i++) {
|
| 293 |
+
int_t i = -1, j;
|
| 294 |
+
uint_t k = 0;
|
| 295 |
+
|
| 296 |
+
PRINTF("looking at free_i=%d\n", *pfree_i);
|
| 297 |
+
j = find_path_dense(n, cost, *pfree_i, y, v, pred);
|
| 298 |
+
ASSERT(j >= 0);
|
| 299 |
+
ASSERT(j < n);
|
| 300 |
+
while (i != *pfree_i) {
|
| 301 |
+
PRINTF("augment %d\n", j);
|
| 302 |
+
PRINT_INDEX_ARRAY(pred, n);
|
| 303 |
+
i = pred[j];
|
| 304 |
+
PRINTF("y[%d]=%d -> %d\n", j, y[j], i);
|
| 305 |
+
y[j] = i;
|
| 306 |
+
PRINT_INDEX_ARRAY(x, n);
|
| 307 |
+
SWAP_INDICES(j, x[i]);
|
| 308 |
+
k++;
|
| 309 |
+
if (k >= n) {
|
| 310 |
+
ASSERT(FALSE);
|
| 311 |
+
}
|
| 312 |
+
}
|
| 313 |
+
}
|
| 314 |
+
FREE(pred);
|
| 315 |
+
return 0;
|
| 316 |
+
}
|
| 317 |
+
|
| 318 |
+
|
| 319 |
+
/** Solve dense sparse LAP.
|
| 320 |
+
*/
|
| 321 |
+
int lapjv_internal(
|
| 322 |
+
const uint_t n, cost_t *cost[],
|
| 323 |
+
int_t *x, int_t *y)
|
| 324 |
+
{
|
| 325 |
+
int ret;
|
| 326 |
+
int_t *free_rows;
|
| 327 |
+
cost_t *v;
|
| 328 |
+
|
| 329 |
+
NEW(free_rows, int_t, n);
|
| 330 |
+
NEW(v, cost_t, n);
|
| 331 |
+
ret = _ccrrt_dense(n, cost, free_rows, x, y, v);
|
| 332 |
+
int i = 0;
|
| 333 |
+
while (ret > 0 && i < 2) {
|
| 334 |
+
ret = _carr_dense(n, cost, ret, free_rows, x, y, v);
|
| 335 |
+
i++;
|
| 336 |
+
}
|
| 337 |
+
if (ret > 0) {
|
| 338 |
+
ret = _ca_dense(n, cost, ret, free_rows, x, y, v);
|
| 339 |
+
}
|
| 340 |
+
FREE(v);
|
| 341 |
+
FREE(free_rows);
|
| 342 |
+
return ret;
|
| 343 |
+
}
|
deploy/TensorRT/cpp/src/utils.cpp
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "BYTETracker.h"
|
| 2 |
+
#include "lapjv.h"
|
| 3 |
+
|
| 4 |
+
vector<STrack*> BYTETracker::joint_stracks(vector<STrack*> &tlista, vector<STrack> &tlistb)
|
| 5 |
+
{
|
| 6 |
+
map<int, int> exists;
|
| 7 |
+
vector<STrack*> res;
|
| 8 |
+
for (int i = 0; i < tlista.size(); i++)
|
| 9 |
+
{
|
| 10 |
+
exists.insert(pair<int, int>(tlista[i]->track_id, 1));
|
| 11 |
+
res.push_back(tlista[i]);
|
| 12 |
+
}
|
| 13 |
+
for (int i = 0; i < tlistb.size(); i++)
|
| 14 |
+
{
|
| 15 |
+
int tid = tlistb[i].track_id;
|
| 16 |
+
if (!exists[tid] || exists.count(tid) == 0)
|
| 17 |
+
{
|
| 18 |
+
exists[tid] = 1;
|
| 19 |
+
res.push_back(&tlistb[i]);
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
return res;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
vector<STrack> BYTETracker::joint_stracks(vector<STrack> &tlista, vector<STrack> &tlistb)
|
| 26 |
+
{
|
| 27 |
+
map<int, int> exists;
|
| 28 |
+
vector<STrack> res;
|
| 29 |
+
for (int i = 0; i < tlista.size(); i++)
|
| 30 |
+
{
|
| 31 |
+
exists.insert(pair<int, int>(tlista[i].track_id, 1));
|
| 32 |
+
res.push_back(tlista[i]);
|
| 33 |
+
}
|
| 34 |
+
for (int i = 0; i < tlistb.size(); i++)
|
| 35 |
+
{
|
| 36 |
+
int tid = tlistb[i].track_id;
|
| 37 |
+
if (!exists[tid] || exists.count(tid) == 0)
|
| 38 |
+
{
|
| 39 |
+
exists[tid] = 1;
|
| 40 |
+
res.push_back(tlistb[i]);
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
return res;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
vector<STrack> BYTETracker::sub_stracks(vector<STrack> &tlista, vector<STrack> &tlistb)
|
| 47 |
+
{
|
| 48 |
+
map<int, STrack> stracks;
|
| 49 |
+
for (int i = 0; i < tlista.size(); i++)
|
| 50 |
+
{
|
| 51 |
+
stracks.insert(pair<int, STrack>(tlista[i].track_id, tlista[i]));
|
| 52 |
+
}
|
| 53 |
+
for (int i = 0; i < tlistb.size(); i++)
|
| 54 |
+
{
|
| 55 |
+
int tid = tlistb[i].track_id;
|
| 56 |
+
if (stracks.count(tid) != 0)
|
| 57 |
+
{
|
| 58 |
+
stracks.erase(tid);
|
| 59 |
+
}
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
vector<STrack> res;
|
| 63 |
+
std::map<int, STrack>::iterator it;
|
| 64 |
+
for (it = stracks.begin(); it != stracks.end(); ++it)
|
| 65 |
+
{
|
| 66 |
+
res.push_back(it->second);
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
return res;
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
void BYTETracker::remove_duplicate_stracks(vector<STrack> &resa, vector<STrack> &resb, vector<STrack> &stracksa, vector<STrack> &stracksb)
|
| 73 |
+
{
|
| 74 |
+
vector<vector<float> > pdist = iou_distance(stracksa, stracksb);
|
| 75 |
+
vector<pair<int, int> > pairs;
|
| 76 |
+
for (int i = 0; i < pdist.size(); i++)
|
| 77 |
+
{
|
| 78 |
+
for (int j = 0; j < pdist[i].size(); j++)
|
| 79 |
+
{
|
| 80 |
+
if (pdist[i][j] < 0.15)
|
| 81 |
+
{
|
| 82 |
+
pairs.push_back(pair<int, int>(i, j));
|
| 83 |
+
}
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
vector<int> dupa, dupb;
|
| 88 |
+
for (int i = 0; i < pairs.size(); i++)
|
| 89 |
+
{
|
| 90 |
+
int timep = stracksa[pairs[i].first].frame_id - stracksa[pairs[i].first].start_frame;
|
| 91 |
+
int timeq = stracksb[pairs[i].second].frame_id - stracksb[pairs[i].second].start_frame;
|
| 92 |
+
if (timep > timeq)
|
| 93 |
+
dupb.push_back(pairs[i].second);
|
| 94 |
+
else
|
| 95 |
+
dupa.push_back(pairs[i].first);
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
for (int i = 0; i < stracksa.size(); i++)
|
| 99 |
+
{
|
| 100 |
+
vector<int>::iterator iter = find(dupa.begin(), dupa.end(), i);
|
| 101 |
+
if (iter == dupa.end())
|
| 102 |
+
{
|
| 103 |
+
resa.push_back(stracksa[i]);
|
| 104 |
+
}
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
for (int i = 0; i < stracksb.size(); i++)
|
| 108 |
+
{
|
| 109 |
+
vector<int>::iterator iter = find(dupb.begin(), dupb.end(), i);
|
| 110 |
+
if (iter == dupb.end())
|
| 111 |
+
{
|
| 112 |
+
resb.push_back(stracksb[i]);
|
| 113 |
+
}
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
void BYTETracker::linear_assignment(vector<vector<float> > &cost_matrix, int cost_matrix_size, int cost_matrix_size_size, float thresh,
|
| 118 |
+
vector<vector<int> > &matches, vector<int> &unmatched_a, vector<int> &unmatched_b)
|
| 119 |
+
{
|
| 120 |
+
if (cost_matrix.size() == 0)
|
| 121 |
+
{
|
| 122 |
+
for (int i = 0; i < cost_matrix_size; i++)
|
| 123 |
+
{
|
| 124 |
+
unmatched_a.push_back(i);
|
| 125 |
+
}
|
| 126 |
+
for (int i = 0; i < cost_matrix_size_size; i++)
|
| 127 |
+
{
|
| 128 |
+
unmatched_b.push_back(i);
|
| 129 |
+
}
|
| 130 |
+
return;
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
vector<int> rowsol; vector<int> colsol;
|
| 134 |
+
float c = lapjv(cost_matrix, rowsol, colsol, true, thresh);
|
| 135 |
+
for (int i = 0; i < rowsol.size(); i++)
|
| 136 |
+
{
|
| 137 |
+
if (rowsol[i] >= 0)
|
| 138 |
+
{
|
| 139 |
+
vector<int> match;
|
| 140 |
+
match.push_back(i);
|
| 141 |
+
match.push_back(rowsol[i]);
|
| 142 |
+
matches.push_back(match);
|
| 143 |
+
}
|
| 144 |
+
else
|
| 145 |
+
{
|
| 146 |
+
unmatched_a.push_back(i);
|
| 147 |
+
}
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
for (int i = 0; i < colsol.size(); i++)
|
| 151 |
+
{
|
| 152 |
+
if (colsol[i] < 0)
|
| 153 |
+
{
|
| 154 |
+
unmatched_b.push_back(i);
|
| 155 |
+
}
|
| 156 |
+
}
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
vector<vector<float> > BYTETracker::ious(vector<vector<float> > &atlbrs, vector<vector<float> > &btlbrs)
|
| 160 |
+
{
|
| 161 |
+
vector<vector<float> > ious;
|
| 162 |
+
if (atlbrs.size()*btlbrs.size() == 0)
|
| 163 |
+
return ious;
|
| 164 |
+
|
| 165 |
+
ious.resize(atlbrs.size());
|
| 166 |
+
for (int i = 0; i < ious.size(); i++)
|
| 167 |
+
{
|
| 168 |
+
ious[i].resize(btlbrs.size());
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
//bbox_ious
|
| 172 |
+
for (int k = 0; k < btlbrs.size(); k++)
|
| 173 |
+
{
|
| 174 |
+
vector<float> ious_tmp;
|
| 175 |
+
float box_area = (btlbrs[k][2] - btlbrs[k][0] + 1)*(btlbrs[k][3] - btlbrs[k][1] + 1);
|
| 176 |
+
for (int n = 0; n < atlbrs.size(); n++)
|
| 177 |
+
{
|
| 178 |
+
float iw = min(atlbrs[n][2], btlbrs[k][2]) - max(atlbrs[n][0], btlbrs[k][0]) + 1;
|
| 179 |
+
if (iw > 0)
|
| 180 |
+
{
|
| 181 |
+
float ih = min(atlbrs[n][3], btlbrs[k][3]) - max(atlbrs[n][1], btlbrs[k][1]) + 1;
|
| 182 |
+
if(ih > 0)
|
| 183 |
+
{
|
| 184 |
+
float ua = (atlbrs[n][2] - atlbrs[n][0] + 1)*(atlbrs[n][3] - atlbrs[n][1] + 1) + box_area - iw * ih;
|
| 185 |
+
ious[n][k] = iw * ih / ua;
|
| 186 |
+
}
|
| 187 |
+
else
|
| 188 |
+
{
|
| 189 |
+
ious[n][k] = 0.0;
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
else
|
| 193 |
+
{
|
| 194 |
+
ious[n][k] = 0.0;
|
| 195 |
+
}
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
return ious;
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
vector<vector<float> > BYTETracker::iou_distance(vector<STrack*> &atracks, vector<STrack> &btracks, int &dist_size, int &dist_size_size)
|
| 203 |
+
{
|
| 204 |
+
vector<vector<float> > cost_matrix;
|
| 205 |
+
if (atracks.size() * btracks.size() == 0)
|
| 206 |
+
{
|
| 207 |
+
dist_size = atracks.size();
|
| 208 |
+
dist_size_size = btracks.size();
|
| 209 |
+
return cost_matrix;
|
| 210 |
+
}
|
| 211 |
+
vector<vector<float> > atlbrs, btlbrs;
|
| 212 |
+
for (int i = 0; i < atracks.size(); i++)
|
| 213 |
+
{
|
| 214 |
+
atlbrs.push_back(atracks[i]->tlbr);
|
| 215 |
+
}
|
| 216 |
+
for (int i = 0; i < btracks.size(); i++)
|
| 217 |
+
{
|
| 218 |
+
btlbrs.push_back(btracks[i].tlbr);
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
dist_size = atracks.size();
|
| 222 |
+
dist_size_size = btracks.size();
|
| 223 |
+
|
| 224 |
+
vector<vector<float> > _ious = ious(atlbrs, btlbrs);
|
| 225 |
+
|
| 226 |
+
for (int i = 0; i < _ious.size();i++)
|
| 227 |
+
{
|
| 228 |
+
vector<float> _iou;
|
| 229 |
+
for (int j = 0; j < _ious[i].size(); j++)
|
| 230 |
+
{
|
| 231 |
+
_iou.push_back(1 - _ious[i][j]);
|
| 232 |
+
}
|
| 233 |
+
cost_matrix.push_back(_iou);
|
| 234 |
+
}
|
| 235 |
+
|
| 236 |
+
return cost_matrix;
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
vector<vector<float> > BYTETracker::iou_distance(vector<STrack> &atracks, vector<STrack> &btracks)
|
| 240 |
+
{
|
| 241 |
+
vector<vector<float> > atlbrs, btlbrs;
|
| 242 |
+
for (int i = 0; i < atracks.size(); i++)
|
| 243 |
+
{
|
| 244 |
+
atlbrs.push_back(atracks[i].tlbr);
|
| 245 |
+
}
|
| 246 |
+
for (int i = 0; i < btracks.size(); i++)
|
| 247 |
+
{
|
| 248 |
+
btlbrs.push_back(btracks[i].tlbr);
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
vector<vector<float> > _ious = ious(atlbrs, btlbrs);
|
| 252 |
+
vector<vector<float> > cost_matrix;
|
| 253 |
+
for (int i = 0; i < _ious.size(); i++)
|
| 254 |
+
{
|
| 255 |
+
vector<float> _iou;
|
| 256 |
+
for (int j = 0; j < _ious[i].size(); j++)
|
| 257 |
+
{
|
| 258 |
+
_iou.push_back(1 - _ious[i][j]);
|
| 259 |
+
}
|
| 260 |
+
cost_matrix.push_back(_iou);
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
return cost_matrix;
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
double BYTETracker::lapjv(const vector<vector<float> > &cost, vector<int> &rowsol, vector<int> &colsol,
|
| 267 |
+
bool extend_cost, float cost_limit, bool return_cost)
|
| 268 |
+
{
|
| 269 |
+
vector<vector<float> > cost_c;
|
| 270 |
+
cost_c.assign(cost.begin(), cost.end());
|
| 271 |
+
|
| 272 |
+
vector<vector<float> > cost_c_extended;
|
| 273 |
+
|
| 274 |
+
int n_rows = cost.size();
|
| 275 |
+
int n_cols = cost[0].size();
|
| 276 |
+
rowsol.resize(n_rows);
|
| 277 |
+
colsol.resize(n_cols);
|
| 278 |
+
|
| 279 |
+
int n = 0;
|
| 280 |
+
if (n_rows == n_cols)
|
| 281 |
+
{
|
| 282 |
+
n = n_rows;
|
| 283 |
+
}
|
| 284 |
+
else
|
| 285 |
+
{
|
| 286 |
+
if (!extend_cost)
|
| 287 |
+
{
|
| 288 |
+
cout << "set extend_cost=True" << endl;
|
| 289 |
+
system("pause");
|
| 290 |
+
exit(0);
|
| 291 |
+
}
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
if (extend_cost || cost_limit < LONG_MAX)
|
| 295 |
+
{
|
| 296 |
+
n = n_rows + n_cols;
|
| 297 |
+
cost_c_extended.resize(n);
|
| 298 |
+
for (int i = 0; i < cost_c_extended.size(); i++)
|
| 299 |
+
cost_c_extended[i].resize(n);
|
| 300 |
+
|
| 301 |
+
if (cost_limit < LONG_MAX)
|
| 302 |
+
{
|
| 303 |
+
for (int i = 0; i < cost_c_extended.size(); i++)
|
| 304 |
+
{
|
| 305 |
+
for (int j = 0; j < cost_c_extended[i].size(); j++)
|
| 306 |
+
{
|
| 307 |
+
cost_c_extended[i][j] = cost_limit / 2.0;
|
| 308 |
+
}
|
| 309 |
+
}
|
| 310 |
+
}
|
| 311 |
+
else
|
| 312 |
+
{
|
| 313 |
+
float cost_max = -1;
|
| 314 |
+
for (int i = 0; i < cost_c.size(); i++)
|
| 315 |
+
{
|
| 316 |
+
for (int j = 0; j < cost_c[i].size(); j++)
|
| 317 |
+
{
|
| 318 |
+
if (cost_c[i][j] > cost_max)
|
| 319 |
+
cost_max = cost_c[i][j];
|
| 320 |
+
}
|
| 321 |
+
}
|
| 322 |
+
for (int i = 0; i < cost_c_extended.size(); i++)
|
| 323 |
+
{
|
| 324 |
+
for (int j = 0; j < cost_c_extended[i].size(); j++)
|
| 325 |
+
{
|
| 326 |
+
cost_c_extended[i][j] = cost_max + 1;
|
| 327 |
+
}
|
| 328 |
+
}
|
| 329 |
+
}
|
| 330 |
+
|
| 331 |
+
for (int i = n_rows; i < cost_c_extended.size(); i++)
|
| 332 |
+
{
|
| 333 |
+
for (int j = n_cols; j < cost_c_extended[i].size(); j++)
|
| 334 |
+
{
|
| 335 |
+
cost_c_extended[i][j] = 0;
|
| 336 |
+
}
|
| 337 |
+
}
|
| 338 |
+
for (int i = 0; i < n_rows; i++)
|
| 339 |
+
{
|
| 340 |
+
for (int j = 0; j < n_cols; j++)
|
| 341 |
+
{
|
| 342 |
+
cost_c_extended[i][j] = cost_c[i][j];
|
| 343 |
+
}
|
| 344 |
+
}
|
| 345 |
+
|
| 346 |
+
cost_c.clear();
|
| 347 |
+
cost_c.assign(cost_c_extended.begin(), cost_c_extended.end());
|
| 348 |
+
}
|
| 349 |
+
|
| 350 |
+
double **cost_ptr;
|
| 351 |
+
cost_ptr = new double *[sizeof(double *) * n];
|
| 352 |
+
for (int i = 0; i < n; i++)
|
| 353 |
+
cost_ptr[i] = new double[sizeof(double) * n];
|
| 354 |
+
|
| 355 |
+
for (int i = 0; i < n; i++)
|
| 356 |
+
{
|
| 357 |
+
for (int j = 0; j < n; j++)
|
| 358 |
+
{
|
| 359 |
+
cost_ptr[i][j] = cost_c[i][j];
|
| 360 |
+
}
|
| 361 |
+
}
|
| 362 |
+
|
| 363 |
+
int* x_c = new int[sizeof(int) * n];
|
| 364 |
+
int *y_c = new int[sizeof(int) * n];
|
| 365 |
+
|
| 366 |
+
int ret = lapjv_internal(n, cost_ptr, x_c, y_c);
|
| 367 |
+
if (ret != 0)
|
| 368 |
+
{
|
| 369 |
+
cout << "Calculate Wrong!" << endl;
|
| 370 |
+
system("pause");
|
| 371 |
+
exit(0);
|
| 372 |
+
}
|
| 373 |
+
|
| 374 |
+
double opt = 0.0;
|
| 375 |
+
|
| 376 |
+
if (n != n_rows)
|
| 377 |
+
{
|
| 378 |
+
for (int i = 0; i < n; i++)
|
| 379 |
+
{
|
| 380 |
+
if (x_c[i] >= n_cols)
|
| 381 |
+
x_c[i] = -1;
|
| 382 |
+
if (y_c[i] >= n_rows)
|
| 383 |
+
y_c[i] = -1;
|
| 384 |
+
}
|
| 385 |
+
for (int i = 0; i < n_rows; i++)
|
| 386 |
+
{
|
| 387 |
+
rowsol[i] = x_c[i];
|
| 388 |
+
}
|
| 389 |
+
for (int i = 0; i < n_cols; i++)
|
| 390 |
+
{
|
| 391 |
+
colsol[i] = y_c[i];
|
| 392 |
+
}
|
| 393 |
+
|
| 394 |
+
if (return_cost)
|
| 395 |
+
{
|
| 396 |
+
for (int i = 0; i < rowsol.size(); i++)
|
| 397 |
+
{
|
| 398 |
+
if (rowsol[i] != -1)
|
| 399 |
+
{
|
| 400 |
+
//cout << i << "\t" << rowsol[i] << "\t" << cost_ptr[i][rowsol[i]] << endl;
|
| 401 |
+
opt += cost_ptr[i][rowsol[i]];
|
| 402 |
+
}
|
| 403 |
+
}
|
| 404 |
+
}
|
| 405 |
+
}
|
| 406 |
+
else if (return_cost)
|
| 407 |
+
{
|
| 408 |
+
for (int i = 0; i < rowsol.size(); i++)
|
| 409 |
+
{
|
| 410 |
+
opt += cost_ptr[i][rowsol[i]];
|
| 411 |
+
}
|
| 412 |
+
}
|
| 413 |
+
|
| 414 |
+
for (int i = 0; i < n; i++)
|
| 415 |
+
{
|
| 416 |
+
delete[]cost_ptr[i];
|
| 417 |
+
}
|
| 418 |
+
delete[]cost_ptr;
|
| 419 |
+
delete[]x_c;
|
| 420 |
+
delete[]y_c;
|
| 421 |
+
|
| 422 |
+
return opt;
|
| 423 |
+
}
|
| 424 |
+
|
| 425 |
+
Scalar BYTETracker::get_color(int idx)
|
| 426 |
+
{
|
| 427 |
+
idx += 3;
|
| 428 |
+
return Scalar(37 * idx % 255, 17 * idx % 255, 29 * idx % 255);
|
| 429 |
+
}
|
deploy/TensorRT/python/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ByteTrack-TensorRT in Python
|
| 2 |
+
|
| 3 |
+
## Install TensorRT Toolkit
|
| 4 |
+
Please follow the [TensorRT Installation Guide](https://docs.nvidia.com/deeplearning/tensorrt/install-guide/index.html) and [torch2trt gitrepo](https://github.com/NVIDIA-AI-IOT/torch2trt) to install TensorRT (Version 7 recommended) and torch2trt.
|
| 5 |
+
|
| 6 |
+
## Convert model
|
| 7 |
+
|
| 8 |
+
You can convert the Pytorch model “bytetrack_s_mot17” to TensorRT model by running:
|
| 9 |
+
|
| 10 |
+
```shell
|
| 11 |
+
cd <ByteTrack_HOME>
|
| 12 |
+
python3 tools/trt.py -f exps/example/mot/yolox_s_mix_det.py -c pretrained/bytetrack_s_mot17.pth.tar
|
| 13 |
+
```
|
| 14 |
+
|
| 15 |
+
## Run TensorRT demo
|
| 16 |
+
|
| 17 |
+
You can use the converted model_trt.pth to run TensorRT demo with **130 FPS**:
|
| 18 |
+
|
| 19 |
+
```shell
|
| 20 |
+
cd <ByteTrack_HOME>
|
| 21 |
+
python3 tools/demo_track.py video -f exps/example/mot/yolox_s_mix_det.py --trt --save_result
|
| 22 |
+
```
|
deploy/ncnn/cpp/CMakeLists.txt
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
macro(ncnn_add_example name)
|
| 2 |
+
add_executable(${name} ${name}.cpp)
|
| 3 |
+
if(OpenCV_FOUND)
|
| 4 |
+
target_include_directories(${name} PRIVATE ${OpenCV_INCLUDE_DIRS})
|
| 5 |
+
target_link_libraries(${name} PRIVATE ncnn ${OpenCV_LIBS})
|
| 6 |
+
elseif(NCNN_SIMPLEOCV)
|
| 7 |
+
target_compile_definitions(${name} PUBLIC USE_NCNN_SIMPLEOCV)
|
| 8 |
+
target_link_libraries(${name} PRIVATE ncnn)
|
| 9 |
+
endif()
|
| 10 |
+
|
| 11 |
+
# add test to a virtual project group
|
| 12 |
+
set_property(TARGET ${name} PROPERTY FOLDER "examples")
|
| 13 |
+
endmacro()
|
| 14 |
+
|
| 15 |
+
if(NCNN_PIXEL)
|
| 16 |
+
find_package(OpenCV QUIET COMPONENTS opencv_world)
|
| 17 |
+
# for opencv 2.4 on ubuntu 16.04, there is no opencv_world but OpenCV_FOUND will be TRUE
|
| 18 |
+
if("${OpenCV_LIBS}" STREQUAL "")
|
| 19 |
+
set(OpenCV_FOUND FALSE)
|
| 20 |
+
endif()
|
| 21 |
+
if(NOT OpenCV_FOUND)
|
| 22 |
+
find_package(OpenCV QUIET COMPONENTS core highgui imgproc imgcodecs videoio)
|
| 23 |
+
endif()
|
| 24 |
+
if(NOT OpenCV_FOUND)
|
| 25 |
+
find_package(OpenCV QUIET COMPONENTS core highgui imgproc)
|
| 26 |
+
endif()
|
| 27 |
+
|
| 28 |
+
if(OpenCV_FOUND OR NCNN_SIMPLEOCV)
|
| 29 |
+
if(OpenCV_FOUND)
|
| 30 |
+
message(STATUS "OpenCV library: ${OpenCV_INSTALL_PATH}")
|
| 31 |
+
message(STATUS " version: ${OpenCV_VERSION}")
|
| 32 |
+
message(STATUS " libraries: ${OpenCV_LIBS}")
|
| 33 |
+
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
|
| 34 |
+
|
| 35 |
+
if(${OpenCV_VERSION_MAJOR} GREATER 3)
|
| 36 |
+
set(CMAKE_CXX_STANDARD 11)
|
| 37 |
+
endif()
|
| 38 |
+
endif()
|
| 39 |
+
|
| 40 |
+
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src)
|
| 41 |
+
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../src)
|
| 42 |
+
include_directories(include)
|
| 43 |
+
include_directories(/usr/local/include/eigen3)
|
| 44 |
+
|
| 45 |
+
ncnn_add_example(squeezenet)
|
| 46 |
+
ncnn_add_example(squeezenet_c_api)
|
| 47 |
+
ncnn_add_example(fasterrcnn)
|
| 48 |
+
ncnn_add_example(rfcn)
|
| 49 |
+
ncnn_add_example(yolov2)
|
| 50 |
+
ncnn_add_example(yolov3)
|
| 51 |
+
if(OpenCV_FOUND)
|
| 52 |
+
ncnn_add_example(yolov4)
|
| 53 |
+
endif()
|
| 54 |
+
ncnn_add_example(yolov5)
|
| 55 |
+
ncnn_add_example(yolox)
|
| 56 |
+
ncnn_add_example(mobilenetv2ssdlite)
|
| 57 |
+
ncnn_add_example(mobilenetssd)
|
| 58 |
+
ncnn_add_example(squeezenetssd)
|
| 59 |
+
ncnn_add_example(shufflenetv2)
|
| 60 |
+
ncnn_add_example(peleenetssd_seg)
|
| 61 |
+
ncnn_add_example(simplepose)
|
| 62 |
+
ncnn_add_example(retinaface)
|
| 63 |
+
ncnn_add_example(yolact)
|
| 64 |
+
ncnn_add_example(nanodet)
|
| 65 |
+
ncnn_add_example(scrfd)
|
| 66 |
+
ncnn_add_example(scrfd_crowdhuman)
|
| 67 |
+
ncnn_add_example(rvm)
|
| 68 |
+
file(GLOB My_Source_Files src/*.cpp)
|
| 69 |
+
add_executable(bytetrack ${My_Source_Files})
|
| 70 |
+
if(OpenCV_FOUND)
|
| 71 |
+
target_include_directories(bytetrack PRIVATE ${OpenCV_INCLUDE_DIRS})
|
| 72 |
+
target_link_libraries(bytetrack PRIVATE ncnn ${OpenCV_LIBS})
|
| 73 |
+
elseif(NCNN_SIMPLEOCV)
|
| 74 |
+
target_compile_definitions(bytetrack PUBLIC USE_NCNN_SIMPLEOCV)
|
| 75 |
+
target_link_libraries(bytetrack PRIVATE ncnn)
|
| 76 |
+
endif()
|
| 77 |
+
# add test to a virtual project group
|
| 78 |
+
set_property(TARGET bytetrack PROPERTY FOLDER "examples")
|
| 79 |
+
else()
|
| 80 |
+
message(WARNING "OpenCV not found and NCNN_SIMPLEOCV disabled, examples won't be built")
|
| 81 |
+
endif()
|
| 82 |
+
else()
|
| 83 |
+
message(WARNING "NCNN_PIXEL not enabled, examples won't be built")
|
| 84 |
+
endif()
|
deploy/ncnn/cpp/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ByteTrack-CPP-ncnn
|
| 2 |
+
|
| 3 |
+
## Installation
|
| 4 |
+
|
| 5 |
+
Clone [ncnn](https://github.com/Tencent/ncnn) first, then please following [build tutorial of ncnn](https://github.com/Tencent/ncnn/wiki/how-to-build) to build on your own device.
|
| 6 |
+
|
| 7 |
+
Install eigen-3.3.9 [[google]](https://drive.google.com/file/d/1rqO74CYCNrmRAg8Rra0JP3yZtJ-rfket/view?usp=sharing), [[baidu(code:ueq4)]](https://pan.baidu.com/s/15kEfCxpy-T7tz60msxxExg).
|
| 8 |
+
|
| 9 |
+
```shell
|
| 10 |
+
unzip eigen-3.3.9.zip
|
| 11 |
+
cd eigen-3.3.9
|
| 12 |
+
mkdir build
|
| 13 |
+
cd build
|
| 14 |
+
cmake ..
|
| 15 |
+
sudo make install
|
| 16 |
+
```
|
| 17 |
+
|
| 18 |
+
## Generate onnx file
|
| 19 |
+
Use provided tools to generate onnx file.
|
| 20 |
+
For example, if you want to generate onnx file of bytetrack_s_mot17.pth, please run the following command:
|
| 21 |
+
```shell
|
| 22 |
+
cd <ByteTrack_HOME>
|
| 23 |
+
python3 tools/export_onnx.py -f exps/example/mot/yolox_s_mix_det.py -c pretrained/bytetrack_s_mot17.pth.tar
|
| 24 |
+
```
|
| 25 |
+
Then, a bytetrack_s.onnx file is generated under <ByteTrack_HOME>.
|
| 26 |
+
|
| 27 |
+
## Generate ncnn param and bin file
|
| 28 |
+
Put bytetrack_s.onnx under ncnn/build/tools/onnx and then run:
|
| 29 |
+
|
| 30 |
+
```shell
|
| 31 |
+
cd ncnn/build/tools/onnx
|
| 32 |
+
./onnx2ncnn bytetrack_s.onnx bytetrack_s.param bytetrack_s.bin
|
| 33 |
+
```
|
| 34 |
+
|
| 35 |
+
Since Focus module is not supported in ncnn. Warnings like:
|
| 36 |
+
```shell
|
| 37 |
+
Unsupported slice step !
|
| 38 |
+
```
|
| 39 |
+
will be printed. However, don't worry! C++ version of Focus layer is already implemented in src/bytetrack.cpp.
|
| 40 |
+
|
| 41 |
+
## Modify param file
|
| 42 |
+
Open **bytetrack_s.param**, and modify it.
|
| 43 |
+
Before (just an example):
|
| 44 |
+
```
|
| 45 |
+
235 268
|
| 46 |
+
Input images 0 1 images
|
| 47 |
+
Split splitncnn_input0 1 4 images images_splitncnn_0 images_splitncnn_1 images_splitncnn_2 images_splitncnn_3
|
| 48 |
+
Crop Slice_4 1 1 images_splitncnn_3 467 -23309=1,0 -23310=1,2147483647 -23311=1,1
|
| 49 |
+
Crop Slice_9 1 1 467 472 -23309=1,0 -23310=1,2147483647 -23311=1,2
|
| 50 |
+
Crop Slice_14 1 1 images_splitncnn_2 477 -23309=1,0 -23310=1,2147483647 -23311=1,1
|
| 51 |
+
Crop Slice_19 1 1 477 482 -23309=1,1 -23310=1,2147483647 -23311=1,2
|
| 52 |
+
Crop Slice_24 1 1 images_splitncnn_1 487 -23309=1,1 -23310=1,2147483647 -23311=1,1
|
| 53 |
+
Crop Slice_29 1 1 487 492 -23309=1,0 -23310=1,2147483647 -23311=1,2
|
| 54 |
+
Crop Slice_34 1 1 images_splitncnn_0 497 -23309=1,1 -23310=1,2147483647 -23311=1,1
|
| 55 |
+
Crop Slice_39 1 1 497 502 -23309=1,1 -23310=1,2147483647 -23311=1,2
|
| 56 |
+
Concat Concat_40 4 1 472 492 482 502 503 0=0
|
| 57 |
+
...
|
| 58 |
+
```
|
| 59 |
+
* Change first number for 235 to 235 - 9 = 226(since we will remove 10 layers and add 1 layers, total layers number should minus 9).
|
| 60 |
+
* Then remove 10 lines of code from Split to Concat, but remember the last but 2nd number: 503.
|
| 61 |
+
* Add YoloV5Focus layer After Input (using previous number 503):
|
| 62 |
+
```
|
| 63 |
+
YoloV5Focus focus 1 1 images 503
|
| 64 |
+
```
|
| 65 |
+
After(just an exmaple):
|
| 66 |
+
```
|
| 67 |
+
226 328
|
| 68 |
+
Input images 0 1 images
|
| 69 |
+
YoloV5Focus focus 1 1 images 503
|
| 70 |
+
...
|
| 71 |
+
```
|
| 72 |
+
|
| 73 |
+
## Use ncnn_optimize to generate new param and bin
|
| 74 |
+
```shell
|
| 75 |
+
# suppose you are still under ncnn/build/tools/onnx dir.
|
| 76 |
+
../ncnnoptimize bytetrack_s.param bytetrack_s.bin bytetrack_s_op.param bytetrack_s_op.bin 65536
|
| 77 |
+
```
|
| 78 |
+
|
| 79 |
+
## Copy files and build ByteTrack
|
| 80 |
+
Copy or move 'src', 'include' folders and 'CMakeLists.txt' file into ncnn/examples. Copy bytetrack_s_op.param, bytetrack_s_op.bin and <ByteTrack_HOME>/videos/palace.mp4 into ncnn/build/examples. Then, build ByteTrack:
|
| 81 |
+
|
| 82 |
+
```shell
|
| 83 |
+
cd ncnn/build/examples
|
| 84 |
+
cmake ..
|
| 85 |
+
make
|
| 86 |
+
```
|
| 87 |
+
|
| 88 |
+
## Run the demo
|
| 89 |
+
You can run the ncnn demo with **5 FPS** (96-core Intel(R) Xeon(R) Platinum 8163 CPU @ 2.50GHz):
|
| 90 |
+
```shell
|
| 91 |
+
./bytetrack palace.mp4
|
| 92 |
+
```
|
| 93 |
+
|
| 94 |
+
You can modify 'num_threads' to optimize the running speed in [bytetrack.cpp](https://github.com/ifzhang/ByteTrack/blob/2e9a67895da6b47b948015f6861bba0bacd4e72f/deploy/ncnn/cpp/src/bytetrack.cpp#L309) according to the number of your CPU cores:
|
| 95 |
+
|
| 96 |
+
```
|
| 97 |
+
yolox.opt.num_threads = 20;
|
| 98 |
+
```
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
## Acknowledgement
|
| 102 |
+
|
| 103 |
+
* [ncnn](https://github.com/Tencent/ncnn)
|
deploy/ncnn/cpp/include/BYTETracker.h
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include "STrack.h"
|
| 4 |
+
|
| 5 |
+
struct Object
|
| 6 |
+
{
|
| 7 |
+
cv::Rect_<float> rect;
|
| 8 |
+
int label;
|
| 9 |
+
float prob;
|
| 10 |
+
};
|
| 11 |
+
|
| 12 |
+
class BYTETracker
|
| 13 |
+
{
|
| 14 |
+
public:
|
| 15 |
+
BYTETracker(int frame_rate = 30, int track_buffer = 30);
|
| 16 |
+
~BYTETracker();
|
| 17 |
+
|
| 18 |
+
vector<STrack> update(const vector<Object>& objects);
|
| 19 |
+
Scalar get_color(int idx);
|
| 20 |
+
|
| 21 |
+
private:
|
| 22 |
+
vector<STrack*> joint_stracks(vector<STrack*> &tlista, vector<STrack> &tlistb);
|
| 23 |
+
vector<STrack> joint_stracks(vector<STrack> &tlista, vector<STrack> &tlistb);
|
| 24 |
+
|
| 25 |
+
vector<STrack> sub_stracks(vector<STrack> &tlista, vector<STrack> &tlistb);
|
| 26 |
+
void remove_duplicate_stracks(vector<STrack> &resa, vector<STrack> &resb, vector<STrack> &stracksa, vector<STrack> &stracksb);
|
| 27 |
+
|
| 28 |
+
void linear_assignment(vector<vector<float> > &cost_matrix, int cost_matrix_size, int cost_matrix_size_size, float thresh,
|
| 29 |
+
vector<vector<int> > &matches, vector<int> &unmatched_a, vector<int> &unmatched_b);
|
| 30 |
+
vector<vector<float> > iou_distance(vector<STrack*> &atracks, vector<STrack> &btracks, int &dist_size, int &dist_size_size);
|
| 31 |
+
vector<vector<float> > iou_distance(vector<STrack> &atracks, vector<STrack> &btracks);
|
| 32 |
+
vector<vector<float> > ious(vector<vector<float> > &atlbrs, vector<vector<float> > &btlbrs);
|
| 33 |
+
|
| 34 |
+
double lapjv(const vector<vector<float> > &cost, vector<int> &rowsol, vector<int> &colsol,
|
| 35 |
+
bool extend_cost = false, float cost_limit = LONG_MAX, bool return_cost = true);
|
| 36 |
+
|
| 37 |
+
private:
|
| 38 |
+
|
| 39 |
+
float track_thresh;
|
| 40 |
+
float high_thresh;
|
| 41 |
+
float match_thresh;
|
| 42 |
+
int frame_id;
|
| 43 |
+
int max_time_lost;
|
| 44 |
+
|
| 45 |
+
vector<STrack> tracked_stracks;
|
| 46 |
+
vector<STrack> lost_stracks;
|
| 47 |
+
vector<STrack> removed_stracks;
|
| 48 |
+
byte_kalman::KalmanFilter kalman_filter;
|
| 49 |
+
};
|
deploy/ncnn/cpp/include/STrack.h
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <opencv2/opencv.hpp>
|
| 4 |
+
#include "kalmanFilter.h"
|
| 5 |
+
|
| 6 |
+
using namespace cv;
|
| 7 |
+
using namespace std;
|
| 8 |
+
|
| 9 |
+
enum TrackState { New = 0, Tracked, Lost, Removed };
|
| 10 |
+
|
| 11 |
+
class STrack
|
| 12 |
+
{
|
| 13 |
+
public:
|
| 14 |
+
STrack(vector<float> tlwh_, float score);
|
| 15 |
+
~STrack();
|
| 16 |
+
|
| 17 |
+
vector<float> static tlbr_to_tlwh(vector<float> &tlbr);
|
| 18 |
+
void static multi_predict(vector<STrack*> &stracks, byte_kalman::KalmanFilter &kalman_filter);
|
| 19 |
+
void static_tlwh();
|
| 20 |
+
void static_tlbr();
|
| 21 |
+
vector<float> tlwh_to_xyah(vector<float> tlwh_tmp);
|
| 22 |
+
vector<float> to_xyah();
|
| 23 |
+
void mark_lost();
|
| 24 |
+
void mark_removed();
|
| 25 |
+
int next_id();
|
| 26 |
+
int end_frame();
|
| 27 |
+
|
| 28 |
+
void activate(byte_kalman::KalmanFilter &kalman_filter, int frame_id);
|
| 29 |
+
void re_activate(STrack &new_track, int frame_id, bool new_id = false);
|
| 30 |
+
void update(STrack &new_track, int frame_id);
|
| 31 |
+
|
| 32 |
+
public:
|
| 33 |
+
bool is_activated;
|
| 34 |
+
int track_id;
|
| 35 |
+
int state;
|
| 36 |
+
|
| 37 |
+
vector<float> _tlwh;
|
| 38 |
+
vector<float> tlwh;
|
| 39 |
+
vector<float> tlbr;
|
| 40 |
+
int frame_id;
|
| 41 |
+
int tracklet_len;
|
| 42 |
+
int start_frame;
|
| 43 |
+
|
| 44 |
+
KAL_MEAN mean;
|
| 45 |
+
KAL_COVA covariance;
|
| 46 |
+
float score;
|
| 47 |
+
|
| 48 |
+
private:
|
| 49 |
+
byte_kalman::KalmanFilter kalman_filter;
|
| 50 |
+
};
|
deploy/ncnn/cpp/include/dataType.h
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <cstddef>
|
| 4 |
+
#include <vector>
|
| 5 |
+
|
| 6 |
+
#include <Eigen/Core>
|
| 7 |
+
#include <Eigen/Dense>
|
| 8 |
+
typedef Eigen::Matrix<float, 1, 4, Eigen::RowMajor> DETECTBOX;
|
| 9 |
+
typedef Eigen::Matrix<float, -1, 4, Eigen::RowMajor> DETECTBOXSS;
|
| 10 |
+
typedef Eigen::Matrix<float, 1, 128, Eigen::RowMajor> FEATURE;
|
| 11 |
+
typedef Eigen::Matrix<float, Eigen::Dynamic, 128, Eigen::RowMajor> FEATURESS;
|
| 12 |
+
//typedef std::vector<FEATURE> FEATURESS;
|
| 13 |
+
|
| 14 |
+
//Kalmanfilter
|
| 15 |
+
//typedef Eigen::Matrix<float, 8, 8, Eigen::RowMajor> KAL_FILTER;
|
| 16 |
+
typedef Eigen::Matrix<float, 1, 8, Eigen::RowMajor> KAL_MEAN;
|
| 17 |
+
typedef Eigen::Matrix<float, 8, 8, Eigen::RowMajor> KAL_COVA;
|
| 18 |
+
typedef Eigen::Matrix<float, 1, 4, Eigen::RowMajor> KAL_HMEAN;
|
| 19 |
+
typedef Eigen::Matrix<float, 4, 4, Eigen::RowMajor> KAL_HCOVA;
|
| 20 |
+
using KAL_DATA = std::pair<KAL_MEAN, KAL_COVA>;
|
| 21 |
+
using KAL_HDATA = std::pair<KAL_HMEAN, KAL_HCOVA>;
|
| 22 |
+
|
| 23 |
+
//main
|
| 24 |
+
using RESULT_DATA = std::pair<int, DETECTBOX>;
|
| 25 |
+
|
| 26 |
+
//tracker:
|
| 27 |
+
using TRACKER_DATA = std::pair<int, FEATURESS>;
|
| 28 |
+
using MATCH_DATA = std::pair<int, int>;
|
| 29 |
+
typedef struct t {
|
| 30 |
+
std::vector<MATCH_DATA> matches;
|
| 31 |
+
std::vector<int> unmatched_tracks;
|
| 32 |
+
std::vector<int> unmatched_detections;
|
| 33 |
+
}TRACHER_MATCHD;
|
| 34 |
+
|
| 35 |
+
//linear_assignment:
|
| 36 |
+
typedef Eigen::Matrix<float, -1, -1, Eigen::RowMajor> DYNAMICM;
|
deploy/ncnn/cpp/include/kalmanFilter.h
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include "dataType.h"
|
| 4 |
+
|
| 5 |
+
namespace byte_kalman
|
| 6 |
+
{
|
| 7 |
+
class KalmanFilter
|
| 8 |
+
{
|
| 9 |
+
public:
|
| 10 |
+
static const double chi2inv95[10];
|
| 11 |
+
KalmanFilter();
|
| 12 |
+
KAL_DATA initiate(const DETECTBOX& measurement);
|
| 13 |
+
void predict(KAL_MEAN& mean, KAL_COVA& covariance);
|
| 14 |
+
KAL_HDATA project(const KAL_MEAN& mean, const KAL_COVA& covariance);
|
| 15 |
+
KAL_DATA update(const KAL_MEAN& mean,
|
| 16 |
+
const KAL_COVA& covariance,
|
| 17 |
+
const DETECTBOX& measurement);
|
| 18 |
+
|
| 19 |
+
Eigen::Matrix<float, 1, -1> gating_distance(
|
| 20 |
+
const KAL_MEAN& mean,
|
| 21 |
+
const KAL_COVA& covariance,
|
| 22 |
+
const std::vector<DETECTBOX>& measurements,
|
| 23 |
+
bool only_position = false);
|
| 24 |
+
|
| 25 |
+
private:
|
| 26 |
+
Eigen::Matrix<float, 8, 8, Eigen::RowMajor> _motion_mat;
|
| 27 |
+
Eigen::Matrix<float, 4, 8, Eigen::RowMajor> _update_mat;
|
| 28 |
+
float _std_weight_position;
|
| 29 |
+
float _std_weight_velocity;
|
| 30 |
+
};
|
| 31 |
+
}
|
deploy/ncnn/cpp/include/lapjv.h
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef LAPJV_H
|
| 2 |
+
#define LAPJV_H
|
| 3 |
+
|
| 4 |
+
#define LARGE 1000000
|
| 5 |
+
|
| 6 |
+
#if !defined TRUE
|
| 7 |
+
#define TRUE 1
|
| 8 |
+
#endif
|
| 9 |
+
#if !defined FALSE
|
| 10 |
+
#define FALSE 0
|
| 11 |
+
#endif
|
| 12 |
+
|
| 13 |
+
#define NEW(x, t, n) if ((x = (t *)malloc(sizeof(t) * (n))) == 0) { return -1; }
|
| 14 |
+
#define FREE(x) if (x != 0) { free(x); x = 0; }
|
| 15 |
+
#define SWAP_INDICES(a, b) { int_t _temp_index = a; a = b; b = _temp_index; }
|
| 16 |
+
|
| 17 |
+
#if 0
|
| 18 |
+
#include <assert.h>
|
| 19 |
+
#define ASSERT(cond) assert(cond)
|
| 20 |
+
#define PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
|
| 21 |
+
#define PRINT_COST_ARRAY(a, n) \
|
| 22 |
+
while (1) { \
|
| 23 |
+
printf(#a" = ["); \
|
| 24 |
+
if ((n) > 0) { \
|
| 25 |
+
printf("%f", (a)[0]); \
|
| 26 |
+
for (uint_t j = 1; j < n; j++) { \
|
| 27 |
+
printf(", %f", (a)[j]); \
|
| 28 |
+
} \
|
| 29 |
+
} \
|
| 30 |
+
printf("]\n"); \
|
| 31 |
+
break; \
|
| 32 |
+
}
|
| 33 |
+
#define PRINT_INDEX_ARRAY(a, n) \
|
| 34 |
+
while (1) { \
|
| 35 |
+
printf(#a" = ["); \
|
| 36 |
+
if ((n) > 0) { \
|
| 37 |
+
printf("%d", (a)[0]); \
|
| 38 |
+
for (uint_t j = 1; j < n; j++) { \
|
| 39 |
+
printf(", %d", (a)[j]); \
|
| 40 |
+
} \
|
| 41 |
+
} \
|
| 42 |
+
printf("]\n"); \
|
| 43 |
+
break; \
|
| 44 |
+
}
|
| 45 |
+
#else
|
| 46 |
+
#define ASSERT(cond)
|
| 47 |
+
#define PRINTF(fmt, ...)
|
| 48 |
+
#define PRINT_COST_ARRAY(a, n)
|
| 49 |
+
#define PRINT_INDEX_ARRAY(a, n)
|
| 50 |
+
#endif
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
typedef signed int int_t;
|
| 54 |
+
typedef unsigned int uint_t;
|
| 55 |
+
typedef double cost_t;
|
| 56 |
+
typedef char boolean;
|
| 57 |
+
typedef enum fp_t { FP_1 = 1, FP_2 = 2, FP_DYNAMIC = 3 } fp_t;
|
| 58 |
+
|
| 59 |
+
extern int_t lapjv_internal(
|
| 60 |
+
const uint_t n, cost_t *cost[],
|
| 61 |
+
int_t *x, int_t *y);
|
| 62 |
+
|
| 63 |
+
#endif // LAPJV_H
|
deploy/ncnn/cpp/src/BYTETracker.cpp
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "BYTETracker.h"
|
| 2 |
+
#include <fstream>
|
| 3 |
+
|
| 4 |
+
BYTETracker::BYTETracker(int frame_rate, int track_buffer)
|
| 5 |
+
{
|
| 6 |
+
track_thresh = 0.5;
|
| 7 |
+
high_thresh = 0.6;
|
| 8 |
+
match_thresh = 0.8;
|
| 9 |
+
|
| 10 |
+
frame_id = 0;
|
| 11 |
+
max_time_lost = int(frame_rate / 30.0 * track_buffer);
|
| 12 |
+
cout << "Init ByteTrack!" << endl;
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
BYTETracker::~BYTETracker()
|
| 16 |
+
{
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
vector<STrack> BYTETracker::update(const vector<Object>& objects)
|
| 20 |
+
{
|
| 21 |
+
|
| 22 |
+
////////////////// Step 1: Get detections //////////////////
|
| 23 |
+
this->frame_id++;
|
| 24 |
+
vector<STrack> activated_stracks;
|
| 25 |
+
vector<STrack> refind_stracks;
|
| 26 |
+
vector<STrack> removed_stracks;
|
| 27 |
+
vector<STrack> lost_stracks;
|
| 28 |
+
vector<STrack> detections;
|
| 29 |
+
vector<STrack> detections_low;
|
| 30 |
+
|
| 31 |
+
vector<STrack> detections_cp;
|
| 32 |
+
vector<STrack> tracked_stracks_swap;
|
| 33 |
+
vector<STrack> resa, resb;
|
| 34 |
+
vector<STrack> output_stracks;
|
| 35 |
+
|
| 36 |
+
vector<STrack*> unconfirmed;
|
| 37 |
+
vector<STrack*> tracked_stracks;
|
| 38 |
+
vector<STrack*> strack_pool;
|
| 39 |
+
vector<STrack*> r_tracked_stracks;
|
| 40 |
+
|
| 41 |
+
if (objects.size() > 0)
|
| 42 |
+
{
|
| 43 |
+
for (int i = 0; i < objects.size(); i++)
|
| 44 |
+
{
|
| 45 |
+
vector<float> tlbr_;
|
| 46 |
+
tlbr_.resize(4);
|
| 47 |
+
tlbr_[0] = objects[i].rect.x;
|
| 48 |
+
tlbr_[1] = objects[i].rect.y;
|
| 49 |
+
tlbr_[2] = objects[i].rect.x + objects[i].rect.width;
|
| 50 |
+
tlbr_[3] = objects[i].rect.y + objects[i].rect.height;
|
| 51 |
+
|
| 52 |
+
float score = objects[i].prob;
|
| 53 |
+
|
| 54 |
+
STrack strack(STrack::tlbr_to_tlwh(tlbr_), score);
|
| 55 |
+
if (score >= track_thresh)
|
| 56 |
+
{
|
| 57 |
+
detections.push_back(strack);
|
| 58 |
+
}
|
| 59 |
+
else
|
| 60 |
+
{
|
| 61 |
+
detections_low.push_back(strack);
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
}
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
// Add newly detected tracklets to tracked_stracks
|
| 68 |
+
for (int i = 0; i < this->tracked_stracks.size(); i++)
|
| 69 |
+
{
|
| 70 |
+
if (!this->tracked_stracks[i].is_activated)
|
| 71 |
+
unconfirmed.push_back(&this->tracked_stracks[i]);
|
| 72 |
+
else
|
| 73 |
+
tracked_stracks.push_back(&this->tracked_stracks[i]);
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
////////////////// Step 2: First association, with IoU //////////////////
|
| 77 |
+
strack_pool = joint_stracks(tracked_stracks, this->lost_stracks);
|
| 78 |
+
STrack::multi_predict(strack_pool, this->kalman_filter);
|
| 79 |
+
|
| 80 |
+
vector<vector<float> > dists;
|
| 81 |
+
int dist_size = 0, dist_size_size = 0;
|
| 82 |
+
dists = iou_distance(strack_pool, detections, dist_size, dist_size_size);
|
| 83 |
+
|
| 84 |
+
vector<vector<int> > matches;
|
| 85 |
+
vector<int> u_track, u_detection;
|
| 86 |
+
linear_assignment(dists, dist_size, dist_size_size, match_thresh, matches, u_track, u_detection);
|
| 87 |
+
|
| 88 |
+
for (int i = 0; i < matches.size(); i++)
|
| 89 |
+
{
|
| 90 |
+
STrack *track = strack_pool[matches[i][0]];
|
| 91 |
+
STrack *det = &detections[matches[i][1]];
|
| 92 |
+
if (track->state == TrackState::Tracked)
|
| 93 |
+
{
|
| 94 |
+
track->update(*det, this->frame_id);
|
| 95 |
+
activated_stracks.push_back(*track);
|
| 96 |
+
}
|
| 97 |
+
else
|
| 98 |
+
{
|
| 99 |
+
track->re_activate(*det, this->frame_id, false);
|
| 100 |
+
refind_stracks.push_back(*track);
|
| 101 |
+
}
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
////////////////// Step 3: Second association, using low score dets //////////////////
|
| 105 |
+
for (int i = 0; i < u_detection.size(); i++)
|
| 106 |
+
{
|
| 107 |
+
detections_cp.push_back(detections[u_detection[i]]);
|
| 108 |
+
}
|
| 109 |
+
detections.clear();
|
| 110 |
+
detections.assign(detections_low.begin(), detections_low.end());
|
| 111 |
+
|
| 112 |
+
for (int i = 0; i < u_track.size(); i++)
|
| 113 |
+
{
|
| 114 |
+
if (strack_pool[u_track[i]]->state == TrackState::Tracked)
|
| 115 |
+
{
|
| 116 |
+
r_tracked_stracks.push_back(strack_pool[u_track[i]]);
|
| 117 |
+
}
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
dists.clear();
|
| 121 |
+
dists = iou_distance(r_tracked_stracks, detections, dist_size, dist_size_size);
|
| 122 |
+
|
| 123 |
+
matches.clear();
|
| 124 |
+
u_track.clear();
|
| 125 |
+
u_detection.clear();
|
| 126 |
+
linear_assignment(dists, dist_size, dist_size_size, 0.5, matches, u_track, u_detection);
|
| 127 |
+
|
| 128 |
+
for (int i = 0; i < matches.size(); i++)
|
| 129 |
+
{
|
| 130 |
+
STrack *track = r_tracked_stracks[matches[i][0]];
|
| 131 |
+
STrack *det = &detections[matches[i][1]];
|
| 132 |
+
if (track->state == TrackState::Tracked)
|
| 133 |
+
{
|
| 134 |
+
track->update(*det, this->frame_id);
|
| 135 |
+
activated_stracks.push_back(*track);
|
| 136 |
+
}
|
| 137 |
+
else
|
| 138 |
+
{
|
| 139 |
+
track->re_activate(*det, this->frame_id, false);
|
| 140 |
+
refind_stracks.push_back(*track);
|
| 141 |
+
}
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
for (int i = 0; i < u_track.size(); i++)
|
| 145 |
+
{
|
| 146 |
+
STrack *track = r_tracked_stracks[u_track[i]];
|
| 147 |
+
if (track->state != TrackState::Lost)
|
| 148 |
+
{
|
| 149 |
+
track->mark_lost();
|
| 150 |
+
lost_stracks.push_back(*track);
|
| 151 |
+
}
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
// Deal with unconfirmed tracks, usually tracks with only one beginning frame
|
| 155 |
+
detections.clear();
|
| 156 |
+
detections.assign(detections_cp.begin(), detections_cp.end());
|
| 157 |
+
|
| 158 |
+
dists.clear();
|
| 159 |
+
dists = iou_distance(unconfirmed, detections, dist_size, dist_size_size);
|
| 160 |
+
|
| 161 |
+
matches.clear();
|
| 162 |
+
vector<int> u_unconfirmed;
|
| 163 |
+
u_detection.clear();
|
| 164 |
+
linear_assignment(dists, dist_size, dist_size_size, 0.7, matches, u_unconfirmed, u_detection);
|
| 165 |
+
|
| 166 |
+
for (int i = 0; i < matches.size(); i++)
|
| 167 |
+
{
|
| 168 |
+
unconfirmed[matches[i][0]]->update(detections[matches[i][1]], this->frame_id);
|
| 169 |
+
activated_stracks.push_back(*unconfirmed[matches[i][0]]);
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
for (int i = 0; i < u_unconfirmed.size(); i++)
|
| 173 |
+
{
|
| 174 |
+
STrack *track = unconfirmed[u_unconfirmed[i]];
|
| 175 |
+
track->mark_removed();
|
| 176 |
+
removed_stracks.push_back(*track);
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
////////////////// Step 4: Init new stracks //////////////////
|
| 180 |
+
for (int i = 0; i < u_detection.size(); i++)
|
| 181 |
+
{
|
| 182 |
+
STrack *track = &detections[u_detection[i]];
|
| 183 |
+
if (track->score < this->high_thresh)
|
| 184 |
+
continue;
|
| 185 |
+
track->activate(this->kalman_filter, this->frame_id);
|
| 186 |
+
activated_stracks.push_back(*track);
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
////////////////// Step 5: Update state //////////////////
|
| 190 |
+
for (int i = 0; i < this->lost_stracks.size(); i++)
|
| 191 |
+
{
|
| 192 |
+
if (this->frame_id - this->lost_stracks[i].end_frame() > this->max_time_lost)
|
| 193 |
+
{
|
| 194 |
+
this->lost_stracks[i].mark_removed();
|
| 195 |
+
removed_stracks.push_back(this->lost_stracks[i]);
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
for (int i = 0; i < this->tracked_stracks.size(); i++)
|
| 200 |
+
{
|
| 201 |
+
if (this->tracked_stracks[i].state == TrackState::Tracked)
|
| 202 |
+
{
|
| 203 |
+
tracked_stracks_swap.push_back(this->tracked_stracks[i]);
|
| 204 |
+
}
|
| 205 |
+
}
|
| 206 |
+
this->tracked_stracks.clear();
|
| 207 |
+
this->tracked_stracks.assign(tracked_stracks_swap.begin(), tracked_stracks_swap.end());
|
| 208 |
+
|
| 209 |
+
this->tracked_stracks = joint_stracks(this->tracked_stracks, activated_stracks);
|
| 210 |
+
this->tracked_stracks = joint_stracks(this->tracked_stracks, refind_stracks);
|
| 211 |
+
|
| 212 |
+
//std::cout << activated_stracks.size() << std::endl;
|
| 213 |
+
|
| 214 |
+
this->lost_stracks = sub_stracks(this->lost_stracks, this->tracked_stracks);
|
| 215 |
+
for (int i = 0; i < lost_stracks.size(); i++)
|
| 216 |
+
{
|
| 217 |
+
this->lost_stracks.push_back(lost_stracks[i]);
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
+
this->lost_stracks = sub_stracks(this->lost_stracks, this->removed_stracks);
|
| 221 |
+
for (int i = 0; i < removed_stracks.size(); i++)
|
| 222 |
+
{
|
| 223 |
+
this->removed_stracks.push_back(removed_stracks[i]);
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
remove_duplicate_stracks(resa, resb, this->tracked_stracks, this->lost_stracks);
|
| 227 |
+
|
| 228 |
+
this->tracked_stracks.clear();
|
| 229 |
+
this->tracked_stracks.assign(resa.begin(), resa.end());
|
| 230 |
+
this->lost_stracks.clear();
|
| 231 |
+
this->lost_stracks.assign(resb.begin(), resb.end());
|
| 232 |
+
|
| 233 |
+
for (int i = 0; i < this->tracked_stracks.size(); i++)
|
| 234 |
+
{
|
| 235 |
+
if (this->tracked_stracks[i].is_activated)
|
| 236 |
+
{
|
| 237 |
+
output_stracks.push_back(this->tracked_stracks[i]);
|
| 238 |
+
}
|
| 239 |
+
}
|
| 240 |
+
return output_stracks;
|
| 241 |
+
}
|
deploy/ncnn/cpp/src/STrack.cpp
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "STrack.h"
|
| 2 |
+
|
| 3 |
+
STrack::STrack(vector<float> tlwh_, float score)
|
| 4 |
+
{
|
| 5 |
+
_tlwh.resize(4);
|
| 6 |
+
_tlwh.assign(tlwh_.begin(), tlwh_.end());
|
| 7 |
+
|
| 8 |
+
is_activated = false;
|
| 9 |
+
track_id = 0;
|
| 10 |
+
state = TrackState::New;
|
| 11 |
+
|
| 12 |
+
tlwh.resize(4);
|
| 13 |
+
tlbr.resize(4);
|
| 14 |
+
|
| 15 |
+
static_tlwh();
|
| 16 |
+
static_tlbr();
|
| 17 |
+
frame_id = 0;
|
| 18 |
+
tracklet_len = 0;
|
| 19 |
+
this->score = score;
|
| 20 |
+
start_frame = 0;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
STrack::~STrack()
|
| 24 |
+
{
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
void STrack::activate(byte_kalman::KalmanFilter &kalman_filter, int frame_id)
|
| 28 |
+
{
|
| 29 |
+
this->kalman_filter = kalman_filter;
|
| 30 |
+
this->track_id = this->next_id();
|
| 31 |
+
|
| 32 |
+
vector<float> _tlwh_tmp(4);
|
| 33 |
+
_tlwh_tmp[0] = this->_tlwh[0];
|
| 34 |
+
_tlwh_tmp[1] = this->_tlwh[1];
|
| 35 |
+
_tlwh_tmp[2] = this->_tlwh[2];
|
| 36 |
+
_tlwh_tmp[3] = this->_tlwh[3];
|
| 37 |
+
vector<float> xyah = tlwh_to_xyah(_tlwh_tmp);
|
| 38 |
+
DETECTBOX xyah_box;
|
| 39 |
+
xyah_box[0] = xyah[0];
|
| 40 |
+
xyah_box[1] = xyah[1];
|
| 41 |
+
xyah_box[2] = xyah[2];
|
| 42 |
+
xyah_box[3] = xyah[3];
|
| 43 |
+
auto mc = this->kalman_filter.initiate(xyah_box);
|
| 44 |
+
this->mean = mc.first;
|
| 45 |
+
this->covariance = mc.second;
|
| 46 |
+
|
| 47 |
+
static_tlwh();
|
| 48 |
+
static_tlbr();
|
| 49 |
+
|
| 50 |
+
this->tracklet_len = 0;
|
| 51 |
+
this->state = TrackState::Tracked;
|
| 52 |
+
if (frame_id == 1)
|
| 53 |
+
{
|
| 54 |
+
this->is_activated = true;
|
| 55 |
+
}
|
| 56 |
+
//this->is_activated = true;
|
| 57 |
+
this->frame_id = frame_id;
|
| 58 |
+
this->start_frame = frame_id;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
void STrack::re_activate(STrack &new_track, int frame_id, bool new_id)
|
| 62 |
+
{
|
| 63 |
+
vector<float> xyah = tlwh_to_xyah(new_track.tlwh);
|
| 64 |
+
DETECTBOX xyah_box;
|
| 65 |
+
xyah_box[0] = xyah[0];
|
| 66 |
+
xyah_box[1] = xyah[1];
|
| 67 |
+
xyah_box[2] = xyah[2];
|
| 68 |
+
xyah_box[3] = xyah[3];
|
| 69 |
+
auto mc = this->kalman_filter.update(this->mean, this->covariance, xyah_box);
|
| 70 |
+
this->mean = mc.first;
|
| 71 |
+
this->covariance = mc.second;
|
| 72 |
+
|
| 73 |
+
static_tlwh();
|
| 74 |
+
static_tlbr();
|
| 75 |
+
|
| 76 |
+
this->tracklet_len = 0;
|
| 77 |
+
this->state = TrackState::Tracked;
|
| 78 |
+
this->is_activated = true;
|
| 79 |
+
this->frame_id = frame_id;
|
| 80 |
+
this->score = new_track.score;
|
| 81 |
+
if (new_id)
|
| 82 |
+
this->track_id = next_id();
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
void STrack::update(STrack &new_track, int frame_id)
|
| 86 |
+
{
|
| 87 |
+
this->frame_id = frame_id;
|
| 88 |
+
this->tracklet_len++;
|
| 89 |
+
|
| 90 |
+
vector<float> xyah = tlwh_to_xyah(new_track.tlwh);
|
| 91 |
+
DETECTBOX xyah_box;
|
| 92 |
+
xyah_box[0] = xyah[0];
|
| 93 |
+
xyah_box[1] = xyah[1];
|
| 94 |
+
xyah_box[2] = xyah[2];
|
| 95 |
+
xyah_box[3] = xyah[3];
|
| 96 |
+
|
| 97 |
+
auto mc = this->kalman_filter.update(this->mean, this->covariance, xyah_box);
|
| 98 |
+
this->mean = mc.first;
|
| 99 |
+
this->covariance = mc.second;
|
| 100 |
+
|
| 101 |
+
static_tlwh();
|
| 102 |
+
static_tlbr();
|
| 103 |
+
|
| 104 |
+
this->state = TrackState::Tracked;
|
| 105 |
+
this->is_activated = true;
|
| 106 |
+
|
| 107 |
+
this->score = new_track.score;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
void STrack::static_tlwh()
|
| 111 |
+
{
|
| 112 |
+
if (this->state == TrackState::New)
|
| 113 |
+
{
|
| 114 |
+
tlwh[0] = _tlwh[0];
|
| 115 |
+
tlwh[1] = _tlwh[1];
|
| 116 |
+
tlwh[2] = _tlwh[2];
|
| 117 |
+
tlwh[3] = _tlwh[3];
|
| 118 |
+
return;
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
tlwh[0] = mean[0];
|
| 122 |
+
tlwh[1] = mean[1];
|
| 123 |
+
tlwh[2] = mean[2];
|
| 124 |
+
tlwh[3] = mean[3];
|
| 125 |
+
|
| 126 |
+
tlwh[2] *= tlwh[3];
|
| 127 |
+
tlwh[0] -= tlwh[2] / 2;
|
| 128 |
+
tlwh[1] -= tlwh[3] / 2;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
void STrack::static_tlbr()
|
| 132 |
+
{
|
| 133 |
+
tlbr.clear();
|
| 134 |
+
tlbr.assign(tlwh.begin(), tlwh.end());
|
| 135 |
+
tlbr[2] += tlbr[0];
|
| 136 |
+
tlbr[3] += tlbr[1];
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
vector<float> STrack::tlwh_to_xyah(vector<float> tlwh_tmp)
|
| 140 |
+
{
|
| 141 |
+
vector<float> tlwh_output = tlwh_tmp;
|
| 142 |
+
tlwh_output[0] += tlwh_output[2] / 2;
|
| 143 |
+
tlwh_output[1] += tlwh_output[3] / 2;
|
| 144 |
+
tlwh_output[2] /= tlwh_output[3];
|
| 145 |
+
return tlwh_output;
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
vector<float> STrack::to_xyah()
|
| 149 |
+
{
|
| 150 |
+
return tlwh_to_xyah(tlwh);
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
vector<float> STrack::tlbr_to_tlwh(vector<float> &tlbr)
|
| 154 |
+
{
|
| 155 |
+
tlbr[2] -= tlbr[0];
|
| 156 |
+
tlbr[3] -= tlbr[1];
|
| 157 |
+
return tlbr;
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
void STrack::mark_lost()
|
| 161 |
+
{
|
| 162 |
+
state = TrackState::Lost;
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
void STrack::mark_removed()
|
| 166 |
+
{
|
| 167 |
+
state = TrackState::Removed;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
int STrack::next_id()
|
| 171 |
+
{
|
| 172 |
+
static int _count = 0;
|
| 173 |
+
_count++;
|
| 174 |
+
return _count;
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
int STrack::end_frame()
|
| 178 |
+
{
|
| 179 |
+
return this->frame_id;
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
void STrack::multi_predict(vector<STrack*> &stracks, byte_kalman::KalmanFilter &kalman_filter)
|
| 183 |
+
{
|
| 184 |
+
for (int i = 0; i < stracks.size(); i++)
|
| 185 |
+
{
|
| 186 |
+
if (stracks[i]->state != TrackState::Tracked)
|
| 187 |
+
{
|
| 188 |
+
stracks[i]->mean[7] = 0;
|
| 189 |
+
}
|
| 190 |
+
kalman_filter.predict(stracks[i]->mean, stracks[i]->covariance);
|
| 191 |
+
}
|
| 192 |
+
}
|
deploy/ncnn/cpp/src/bytetrack.cpp
ADDED
|
@@ -0,0 +1,396 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "layer.h"
|
| 2 |
+
#include "net.h"
|
| 3 |
+
|
| 4 |
+
#if defined(USE_NCNN_SIMPLEOCV)
|
| 5 |
+
#include "simpleocv.h"
|
| 6 |
+
#include <opencv2/opencv.hpp>
|
| 7 |
+
#else
|
| 8 |
+
#include <opencv2/core/core.hpp>
|
| 9 |
+
#include <opencv2/highgui/highgui.hpp>
|
| 10 |
+
#include <opencv2/imgproc/imgproc.hpp>
|
| 11 |
+
#include <opencv2/opencv.hpp>
|
| 12 |
+
#endif
|
| 13 |
+
#include <float.h>
|
| 14 |
+
#include <stdio.h>
|
| 15 |
+
#include <vector>
|
| 16 |
+
#include <chrono>
|
| 17 |
+
#include "BYTETracker.h"
|
| 18 |
+
|
| 19 |
+
#define YOLOX_NMS_THRESH 0.7 // nms threshold
|
| 20 |
+
#define YOLOX_CONF_THRESH 0.1 // threshold of bounding box prob
|
| 21 |
+
#define INPUT_W 1088 // target image size w after resize
|
| 22 |
+
#define INPUT_H 608 // target image size h after resize
|
| 23 |
+
|
| 24 |
+
Mat static_resize(Mat& img) {
|
| 25 |
+
float r = min(INPUT_W / (img.cols*1.0), INPUT_H / (img.rows*1.0));
|
| 26 |
+
// r = std::min(r, 1.0f);
|
| 27 |
+
int unpad_w = r * img.cols;
|
| 28 |
+
int unpad_h = r * img.rows;
|
| 29 |
+
Mat re(unpad_h, unpad_w, CV_8UC3);
|
| 30 |
+
resize(img, re, re.size());
|
| 31 |
+
Mat out(INPUT_H, INPUT_W, CV_8UC3, Scalar(114, 114, 114));
|
| 32 |
+
re.copyTo(out(Rect(0, 0, re.cols, re.rows)));
|
| 33 |
+
return out;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
// YOLOX use the same focus in yolov5
|
| 37 |
+
class YoloV5Focus : public ncnn::Layer
|
| 38 |
+
{
|
| 39 |
+
public:
|
| 40 |
+
YoloV5Focus()
|
| 41 |
+
{
|
| 42 |
+
one_blob_only = true;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
virtual int forward(const ncnn::Mat& bottom_blob, ncnn::Mat& top_blob, const ncnn::Option& opt) const
|
| 46 |
+
{
|
| 47 |
+
int w = bottom_blob.w;
|
| 48 |
+
int h = bottom_blob.h;
|
| 49 |
+
int channels = bottom_blob.c;
|
| 50 |
+
|
| 51 |
+
int outw = w / 2;
|
| 52 |
+
int outh = h / 2;
|
| 53 |
+
int outc = channels * 4;
|
| 54 |
+
|
| 55 |
+
top_blob.create(outw, outh, outc, 4u, 1, opt.blob_allocator);
|
| 56 |
+
if (top_blob.empty())
|
| 57 |
+
return -100;
|
| 58 |
+
|
| 59 |
+
#pragma omp parallel for num_threads(opt.num_threads)
|
| 60 |
+
for (int p = 0; p < outc; p++)
|
| 61 |
+
{
|
| 62 |
+
const float* ptr = bottom_blob.channel(p % channels).row((p / channels) % 2) + ((p / channels) / 2);
|
| 63 |
+
float* outptr = top_blob.channel(p);
|
| 64 |
+
|
| 65 |
+
for (int i = 0; i < outh; i++)
|
| 66 |
+
{
|
| 67 |
+
for (int j = 0; j < outw; j++)
|
| 68 |
+
{
|
| 69 |
+
*outptr = *ptr;
|
| 70 |
+
|
| 71 |
+
outptr += 1;
|
| 72 |
+
ptr += 2;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
ptr += w;
|
| 76 |
+
}
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
return 0;
|
| 80 |
+
}
|
| 81 |
+
};
|
| 82 |
+
|
| 83 |
+
DEFINE_LAYER_CREATOR(YoloV5Focus)
|
| 84 |
+
|
| 85 |
+
struct GridAndStride
|
| 86 |
+
{
|
| 87 |
+
int grid0;
|
| 88 |
+
int grid1;
|
| 89 |
+
int stride;
|
| 90 |
+
};
|
| 91 |
+
|
| 92 |
+
static inline float intersection_area(const Object& a, const Object& b)
|
| 93 |
+
{
|
| 94 |
+
cv::Rect_<float> inter = a.rect & b.rect;
|
| 95 |
+
return inter.area();
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
static void qsort_descent_inplace(std::vector<Object>& faceobjects, int left, int right)
|
| 99 |
+
{
|
| 100 |
+
int i = left;
|
| 101 |
+
int j = right;
|
| 102 |
+
float p = faceobjects[(left + right) / 2].prob;
|
| 103 |
+
|
| 104 |
+
while (i <= j)
|
| 105 |
+
{
|
| 106 |
+
while (faceobjects[i].prob > p)
|
| 107 |
+
i++;
|
| 108 |
+
|
| 109 |
+
while (faceobjects[j].prob < p)
|
| 110 |
+
j--;
|
| 111 |
+
|
| 112 |
+
if (i <= j)
|
| 113 |
+
{
|
| 114 |
+
// swap
|
| 115 |
+
std::swap(faceobjects[i], faceobjects[j]);
|
| 116 |
+
|
| 117 |
+
i++;
|
| 118 |
+
j--;
|
| 119 |
+
}
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
#pragma omp parallel sections
|
| 123 |
+
{
|
| 124 |
+
#pragma omp section
|
| 125 |
+
{
|
| 126 |
+
if (left < j) qsort_descent_inplace(faceobjects, left, j);
|
| 127 |
+
}
|
| 128 |
+
#pragma omp section
|
| 129 |
+
{
|
| 130 |
+
if (i < right) qsort_descent_inplace(faceobjects, i, right);
|
| 131 |
+
}
|
| 132 |
+
}
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
static void qsort_descent_inplace(std::vector<Object>& objects)
|
| 136 |
+
{
|
| 137 |
+
if (objects.empty())
|
| 138 |
+
return;
|
| 139 |
+
|
| 140 |
+
qsort_descent_inplace(objects, 0, objects.size() - 1);
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
static void nms_sorted_bboxes(const std::vector<Object>& faceobjects, std::vector<int>& picked, float nms_threshold)
|
| 144 |
+
{
|
| 145 |
+
picked.clear();
|
| 146 |
+
|
| 147 |
+
const int n = faceobjects.size();
|
| 148 |
+
|
| 149 |
+
std::vector<float> areas(n);
|
| 150 |
+
for (int i = 0; i < n; i++)
|
| 151 |
+
{
|
| 152 |
+
areas[i] = faceobjects[i].rect.area();
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
for (int i = 0; i < n; i++)
|
| 156 |
+
{
|
| 157 |
+
const Object& a = faceobjects[i];
|
| 158 |
+
|
| 159 |
+
int keep = 1;
|
| 160 |
+
for (int j = 0; j < (int)picked.size(); j++)
|
| 161 |
+
{
|
| 162 |
+
const Object& b = faceobjects[picked[j]];
|
| 163 |
+
|
| 164 |
+
// intersection over union
|
| 165 |
+
float inter_area = intersection_area(a, b);
|
| 166 |
+
float union_area = areas[i] + areas[picked[j]] - inter_area;
|
| 167 |
+
// float IoU = inter_area / union_area
|
| 168 |
+
if (inter_area / union_area > nms_threshold)
|
| 169 |
+
keep = 0;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
if (keep)
|
| 173 |
+
picked.push_back(i);
|
| 174 |
+
}
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
static void generate_grids_and_stride(const int target_w, const int target_h, std::vector<int>& strides, std::vector<GridAndStride>& grid_strides)
|
| 178 |
+
{
|
| 179 |
+
for (int i = 0; i < (int)strides.size(); i++)
|
| 180 |
+
{
|
| 181 |
+
int stride = strides[i];
|
| 182 |
+
int num_grid_w = target_w / stride;
|
| 183 |
+
int num_grid_h = target_h / stride;
|
| 184 |
+
for (int g1 = 0; g1 < num_grid_h; g1++)
|
| 185 |
+
{
|
| 186 |
+
for (int g0 = 0; g0 < num_grid_w; g0++)
|
| 187 |
+
{
|
| 188 |
+
GridAndStride gs;
|
| 189 |
+
gs.grid0 = g0;
|
| 190 |
+
gs.grid1 = g1;
|
| 191 |
+
gs.stride = stride;
|
| 192 |
+
grid_strides.push_back(gs);
|
| 193 |
+
}
|
| 194 |
+
}
|
| 195 |
+
}
|
| 196 |
+
}
|
| 197 |
+
|
| 198 |
+
static void generate_yolox_proposals(std::vector<GridAndStride> grid_strides, const ncnn::Mat& feat_blob, float prob_threshold, std::vector<Object>& objects)
|
| 199 |
+
{
|
| 200 |
+
const int num_grid = feat_blob.h;
|
| 201 |
+
const int num_class = feat_blob.w - 5;
|
| 202 |
+
const int num_anchors = grid_strides.size();
|
| 203 |
+
|
| 204 |
+
const float* feat_ptr = feat_blob.channel(0);
|
| 205 |
+
for (int anchor_idx = 0; anchor_idx < num_anchors; anchor_idx++)
|
| 206 |
+
{
|
| 207 |
+
const int grid0 = grid_strides[anchor_idx].grid0;
|
| 208 |
+
const int grid1 = grid_strides[anchor_idx].grid1;
|
| 209 |
+
const int stride = grid_strides[anchor_idx].stride;
|
| 210 |
+
|
| 211 |
+
// yolox/models/yolo_head.py decode logic
|
| 212 |
+
// outputs[..., :2] = (outputs[..., :2] + grids) * strides
|
| 213 |
+
// outputs[..., 2:4] = torch.exp(outputs[..., 2:4]) * strides
|
| 214 |
+
float x_center = (feat_ptr[0] + grid0) * stride;
|
| 215 |
+
float y_center = (feat_ptr[1] + grid1) * stride;
|
| 216 |
+
float w = exp(feat_ptr[2]) * stride;
|
| 217 |
+
float h = exp(feat_ptr[3]) * stride;
|
| 218 |
+
float x0 = x_center - w * 0.5f;
|
| 219 |
+
float y0 = y_center - h * 0.5f;
|
| 220 |
+
|
| 221 |
+
float box_objectness = feat_ptr[4];
|
| 222 |
+
for (int class_idx = 0; class_idx < num_class; class_idx++)
|
| 223 |
+
{
|
| 224 |
+
float box_cls_score = feat_ptr[5 + class_idx];
|
| 225 |
+
float box_prob = box_objectness * box_cls_score;
|
| 226 |
+
if (box_prob > prob_threshold)
|
| 227 |
+
{
|
| 228 |
+
Object obj;
|
| 229 |
+
obj.rect.x = x0;
|
| 230 |
+
obj.rect.y = y0;
|
| 231 |
+
obj.rect.width = w;
|
| 232 |
+
obj.rect.height = h;
|
| 233 |
+
obj.label = class_idx;
|
| 234 |
+
obj.prob = box_prob;
|
| 235 |
+
|
| 236 |
+
objects.push_back(obj);
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
} // class loop
|
| 240 |
+
feat_ptr += feat_blob.w;
|
| 241 |
+
|
| 242 |
+
} // point anchor loop
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
static int detect_yolox(ncnn::Mat& in_pad, std::vector<Object>& objects, ncnn::Extractor ex, float scale)
|
| 246 |
+
{
|
| 247 |
+
|
| 248 |
+
ex.input("images", in_pad);
|
| 249 |
+
|
| 250 |
+
std::vector<Object> proposals;
|
| 251 |
+
|
| 252 |
+
{
|
| 253 |
+
ncnn::Mat out;
|
| 254 |
+
ex.extract("output", out);
|
| 255 |
+
|
| 256 |
+
static const int stride_arr[] = {8, 16, 32}; // might have stride=64 in YOLOX
|
| 257 |
+
std::vector<int> strides(stride_arr, stride_arr + sizeof(stride_arr) / sizeof(stride_arr[0]));
|
| 258 |
+
std::vector<GridAndStride> grid_strides;
|
| 259 |
+
generate_grids_and_stride(INPUT_W, INPUT_H, strides, grid_strides);
|
| 260 |
+
generate_yolox_proposals(grid_strides, out, YOLOX_CONF_THRESH, proposals);
|
| 261 |
+
}
|
| 262 |
+
// sort all proposals by score from highest to lowest
|
| 263 |
+
qsort_descent_inplace(proposals);
|
| 264 |
+
|
| 265 |
+
// apply nms with nms_threshold
|
| 266 |
+
std::vector<int> picked;
|
| 267 |
+
nms_sorted_bboxes(proposals, picked, YOLOX_NMS_THRESH);
|
| 268 |
+
|
| 269 |
+
int count = picked.size();
|
| 270 |
+
|
| 271 |
+
objects.resize(count);
|
| 272 |
+
for (int i = 0; i < count; i++)
|
| 273 |
+
{
|
| 274 |
+
objects[i] = proposals[picked[i]];
|
| 275 |
+
|
| 276 |
+
// adjust offset to original unpadded
|
| 277 |
+
float x0 = (objects[i].rect.x) / scale;
|
| 278 |
+
float y0 = (objects[i].rect.y) / scale;
|
| 279 |
+
float x1 = (objects[i].rect.x + objects[i].rect.width) / scale;
|
| 280 |
+
float y1 = (objects[i].rect.y + objects[i].rect.height) / scale;
|
| 281 |
+
|
| 282 |
+
// clip
|
| 283 |
+
// x0 = std::max(std::min(x0, (float)(img_w - 1)), 0.f);
|
| 284 |
+
// y0 = std::max(std::min(y0, (float)(img_h - 1)), 0.f);
|
| 285 |
+
// x1 = std::max(std::min(x1, (float)(img_w - 1)), 0.f);
|
| 286 |
+
// y1 = std::max(std::min(y1, (float)(img_h - 1)), 0.f);
|
| 287 |
+
|
| 288 |
+
objects[i].rect.x = x0;
|
| 289 |
+
objects[i].rect.y = y0;
|
| 290 |
+
objects[i].rect.width = x1 - x0;
|
| 291 |
+
objects[i].rect.height = y1 - y0;
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
return 0;
|
| 295 |
+
}
|
| 296 |
+
|
| 297 |
+
int main(int argc, char** argv)
|
| 298 |
+
{
|
| 299 |
+
if (argc != 2)
|
| 300 |
+
{
|
| 301 |
+
fprintf(stderr, "Usage: %s [videopath]\n", argv[0]);
|
| 302 |
+
return -1;
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
ncnn::Net yolox;
|
| 306 |
+
|
| 307 |
+
//yolox.opt.use_vulkan_compute = true;
|
| 308 |
+
//yolox.opt.use_bf16_storage = true;
|
| 309 |
+
yolox.opt.num_threads = 20;
|
| 310 |
+
//ncnn::set_cpu_powersave(0);
|
| 311 |
+
|
| 312 |
+
//ncnn::set_omp_dynamic(0);
|
| 313 |
+
//ncnn::set_omp_num_threads(20);
|
| 314 |
+
|
| 315 |
+
// Focus in yolov5
|
| 316 |
+
yolox.register_custom_layer("YoloV5Focus", YoloV5Focus_layer_creator);
|
| 317 |
+
|
| 318 |
+
yolox.load_param("bytetrack_s_op.param");
|
| 319 |
+
yolox.load_model("bytetrack_s_op.bin");
|
| 320 |
+
|
| 321 |
+
ncnn::Extractor ex = yolox.create_extractor();
|
| 322 |
+
|
| 323 |
+
const char* videopath = argv[1];
|
| 324 |
+
|
| 325 |
+
VideoCapture cap(videopath);
|
| 326 |
+
if (!cap.isOpened())
|
| 327 |
+
return 0;
|
| 328 |
+
|
| 329 |
+
int img_w = cap.get(CV_CAP_PROP_FRAME_WIDTH);
|
| 330 |
+
int img_h = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
|
| 331 |
+
int fps = cap.get(CV_CAP_PROP_FPS);
|
| 332 |
+
long nFrame = static_cast<long>(cap.get(CV_CAP_PROP_FRAME_COUNT));
|
| 333 |
+
cout << "Total frames: " << nFrame << endl;
|
| 334 |
+
|
| 335 |
+
VideoWriter writer("demo.mp4", CV_FOURCC('m', 'p', '4', 'v'), fps, Size(img_w, img_h));
|
| 336 |
+
|
| 337 |
+
Mat img;
|
| 338 |
+
BYTETracker tracker(fps, 30);
|
| 339 |
+
int num_frames = 0;
|
| 340 |
+
int total_ms = 1;
|
| 341 |
+
for (;;)
|
| 342 |
+
{
|
| 343 |
+
if(!cap.read(img))
|
| 344 |
+
break;
|
| 345 |
+
num_frames ++;
|
| 346 |
+
if (num_frames % 20 == 0)
|
| 347 |
+
{
|
| 348 |
+
cout << "Processing frame " << num_frames << " (" << num_frames * 1000000 / total_ms << " fps)" << endl;
|
| 349 |
+
}
|
| 350 |
+
if (img.empty())
|
| 351 |
+
break;
|
| 352 |
+
|
| 353 |
+
float scale = min(INPUT_W / (img.cols*1.0), INPUT_H / (img.rows*1.0));
|
| 354 |
+
Mat pr_img = static_resize(img);
|
| 355 |
+
ncnn::Mat in_pad = ncnn::Mat::from_pixels_resize(pr_img.data, ncnn::Mat::PIXEL_BGR2RGB, INPUT_W, INPUT_H, INPUT_W, INPUT_H);
|
| 356 |
+
|
| 357 |
+
// python 0-1 input tensor with rgb_means = (0.485, 0.456, 0.406), std = (0.229, 0.224, 0.225)
|
| 358 |
+
// so for 0-255 input image, rgb_mean should multiply 255 and norm should div by std.
|
| 359 |
+
const float mean_vals[3] = {255.f * 0.485f, 255.f * 0.456, 255.f * 0.406f};
|
| 360 |
+
const float norm_vals[3] = {1 / (255.f * 0.229f), 1 / (255.f * 0.224f), 1 / (255.f * 0.225f)};
|
| 361 |
+
|
| 362 |
+
in_pad.substract_mean_normalize(mean_vals, norm_vals);
|
| 363 |
+
|
| 364 |
+
std::vector<Object> objects;
|
| 365 |
+
auto start = chrono::system_clock::now();
|
| 366 |
+
//detect_yolox(img, objects);
|
| 367 |
+
detect_yolox(in_pad, objects, ex, scale);
|
| 368 |
+
vector<STrack> output_stracks = tracker.update(objects);
|
| 369 |
+
auto end = chrono::system_clock::now();
|
| 370 |
+
total_ms = total_ms + chrono::duration_cast<chrono::microseconds>(end - start).count();
|
| 371 |
+
for (int i = 0; i < output_stracks.size(); i++)
|
| 372 |
+
{
|
| 373 |
+
vector<float> tlwh = output_stracks[i].tlwh;
|
| 374 |
+
bool vertical = tlwh[2] / tlwh[3] > 1.6;
|
| 375 |
+
if (tlwh[2] * tlwh[3] > 20 && !vertical)
|
| 376 |
+
{
|
| 377 |
+
Scalar s = tracker.get_color(output_stracks[i].track_id);
|
| 378 |
+
putText(img, format("%d", output_stracks[i].track_id), Point(tlwh[0], tlwh[1] - 5),
|
| 379 |
+
0, 0.6, Scalar(0, 0, 255), 2, LINE_AA);
|
| 380 |
+
rectangle(img, Rect(tlwh[0], tlwh[1], tlwh[2], tlwh[3]), s, 2);
|
| 381 |
+
}
|
| 382 |
+
}
|
| 383 |
+
putText(img, format("frame: %d fps: %d num: %d", num_frames, num_frames * 1000000 / total_ms, output_stracks.size()),
|
| 384 |
+
Point(0, 30), 0, 0.6, Scalar(0, 0, 255), 2, LINE_AA);
|
| 385 |
+
writer.write(img);
|
| 386 |
+
char c = waitKey(1);
|
| 387 |
+
if (c > 0)
|
| 388 |
+
{
|
| 389 |
+
break;
|
| 390 |
+
}
|
| 391 |
+
}
|
| 392 |
+
cap.release();
|
| 393 |
+
cout << "FPS: " << num_frames * 1000000 / total_ms << endl;
|
| 394 |
+
|
| 395 |
+
return 0;
|
| 396 |
+
}
|
deploy/ncnn/cpp/src/kalmanFilter.cpp
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "kalmanFilter.h"
|
| 2 |
+
#include <Eigen/Cholesky>
|
| 3 |
+
|
| 4 |
+
namespace byte_kalman
|
| 5 |
+
{
|
| 6 |
+
const double KalmanFilter::chi2inv95[10] = {
|
| 7 |
+
0,
|
| 8 |
+
3.8415,
|
| 9 |
+
5.9915,
|
| 10 |
+
7.8147,
|
| 11 |
+
9.4877,
|
| 12 |
+
11.070,
|
| 13 |
+
12.592,
|
| 14 |
+
14.067,
|
| 15 |
+
15.507,
|
| 16 |
+
16.919
|
| 17 |
+
};
|
| 18 |
+
KalmanFilter::KalmanFilter()
|
| 19 |
+
{
|
| 20 |
+
int ndim = 4;
|
| 21 |
+
double dt = 1.;
|
| 22 |
+
|
| 23 |
+
_motion_mat = Eigen::MatrixXf::Identity(8, 8);
|
| 24 |
+
for (int i = 0; i < ndim; i++) {
|
| 25 |
+
_motion_mat(i, ndim + i) = dt;
|
| 26 |
+
}
|
| 27 |
+
_update_mat = Eigen::MatrixXf::Identity(4, 8);
|
| 28 |
+
|
| 29 |
+
this->_std_weight_position = 1. / 20;
|
| 30 |
+
this->_std_weight_velocity = 1. / 160;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
KAL_DATA KalmanFilter::initiate(const DETECTBOX &measurement)
|
| 34 |
+
{
|
| 35 |
+
DETECTBOX mean_pos = measurement;
|
| 36 |
+
DETECTBOX mean_vel;
|
| 37 |
+
for (int i = 0; i < 4; i++) mean_vel(i) = 0;
|
| 38 |
+
|
| 39 |
+
KAL_MEAN mean;
|
| 40 |
+
for (int i = 0; i < 8; i++) {
|
| 41 |
+
if (i < 4) mean(i) = mean_pos(i);
|
| 42 |
+
else mean(i) = mean_vel(i - 4);
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
KAL_MEAN std;
|
| 46 |
+
std(0) = 2 * _std_weight_position * measurement[3];
|
| 47 |
+
std(1) = 2 * _std_weight_position * measurement[3];
|
| 48 |
+
std(2) = 1e-2;
|
| 49 |
+
std(3) = 2 * _std_weight_position * measurement[3];
|
| 50 |
+
std(4) = 10 * _std_weight_velocity * measurement[3];
|
| 51 |
+
std(5) = 10 * _std_weight_velocity * measurement[3];
|
| 52 |
+
std(6) = 1e-5;
|
| 53 |
+
std(7) = 10 * _std_weight_velocity * measurement[3];
|
| 54 |
+
|
| 55 |
+
KAL_MEAN tmp = std.array().square();
|
| 56 |
+
KAL_COVA var = tmp.asDiagonal();
|
| 57 |
+
return std::make_pair(mean, var);
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
void KalmanFilter::predict(KAL_MEAN &mean, KAL_COVA &covariance)
|
| 61 |
+
{
|
| 62 |
+
//revise the data;
|
| 63 |
+
DETECTBOX std_pos;
|
| 64 |
+
std_pos << _std_weight_position * mean(3),
|
| 65 |
+
_std_weight_position * mean(3),
|
| 66 |
+
1e-2,
|
| 67 |
+
_std_weight_position * mean(3);
|
| 68 |
+
DETECTBOX std_vel;
|
| 69 |
+
std_vel << _std_weight_velocity * mean(3),
|
| 70 |
+
_std_weight_velocity * mean(3),
|
| 71 |
+
1e-5,
|
| 72 |
+
_std_weight_velocity * mean(3);
|
| 73 |
+
KAL_MEAN tmp;
|
| 74 |
+
tmp.block<1, 4>(0, 0) = std_pos;
|
| 75 |
+
tmp.block<1, 4>(0, 4) = std_vel;
|
| 76 |
+
tmp = tmp.array().square();
|
| 77 |
+
KAL_COVA motion_cov = tmp.asDiagonal();
|
| 78 |
+
KAL_MEAN mean1 = this->_motion_mat * mean.transpose();
|
| 79 |
+
KAL_COVA covariance1 = this->_motion_mat * covariance *(_motion_mat.transpose());
|
| 80 |
+
covariance1 += motion_cov;
|
| 81 |
+
|
| 82 |
+
mean = mean1;
|
| 83 |
+
covariance = covariance1;
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
KAL_HDATA KalmanFilter::project(const KAL_MEAN &mean, const KAL_COVA &covariance)
|
| 87 |
+
{
|
| 88 |
+
DETECTBOX std;
|
| 89 |
+
std << _std_weight_position * mean(3), _std_weight_position * mean(3),
|
| 90 |
+
1e-1, _std_weight_position * mean(3);
|
| 91 |
+
KAL_HMEAN mean1 = _update_mat * mean.transpose();
|
| 92 |
+
KAL_HCOVA covariance1 = _update_mat * covariance * (_update_mat.transpose());
|
| 93 |
+
Eigen::Matrix<float, 4, 4> diag = std.asDiagonal();
|
| 94 |
+
diag = diag.array().square().matrix();
|
| 95 |
+
covariance1 += diag;
|
| 96 |
+
// covariance1.diagonal() << diag;
|
| 97 |
+
return std::make_pair(mean1, covariance1);
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
KAL_DATA
|
| 101 |
+
KalmanFilter::update(
|
| 102 |
+
const KAL_MEAN &mean,
|
| 103 |
+
const KAL_COVA &covariance,
|
| 104 |
+
const DETECTBOX &measurement)
|
| 105 |
+
{
|
| 106 |
+
KAL_HDATA pa = project(mean, covariance);
|
| 107 |
+
KAL_HMEAN projected_mean = pa.first;
|
| 108 |
+
KAL_HCOVA projected_cov = pa.second;
|
| 109 |
+
|
| 110 |
+
//chol_factor, lower =
|
| 111 |
+
//scipy.linalg.cho_factor(projected_cov, lower=True, check_finite=False)
|
| 112 |
+
//kalmain_gain =
|
| 113 |
+
//scipy.linalg.cho_solve((cho_factor, lower),
|
| 114 |
+
//np.dot(covariance, self._upadte_mat.T).T,
|
| 115 |
+
//check_finite=False).T
|
| 116 |
+
Eigen::Matrix<float, 4, 8> B = (covariance * (_update_mat.transpose())).transpose();
|
| 117 |
+
Eigen::Matrix<float, 8, 4> kalman_gain = (projected_cov.llt().solve(B)).transpose(); // eg.8x4
|
| 118 |
+
Eigen::Matrix<float, 1, 4> innovation = measurement - projected_mean; //eg.1x4
|
| 119 |
+
auto tmp = innovation * (kalman_gain.transpose());
|
| 120 |
+
KAL_MEAN new_mean = (mean.array() + tmp.array()).matrix();
|
| 121 |
+
KAL_COVA new_covariance = covariance - kalman_gain * projected_cov*(kalman_gain.transpose());
|
| 122 |
+
return std::make_pair(new_mean, new_covariance);
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
Eigen::Matrix<float, 1, -1>
|
| 126 |
+
KalmanFilter::gating_distance(
|
| 127 |
+
const KAL_MEAN &mean,
|
| 128 |
+
const KAL_COVA &covariance,
|
| 129 |
+
const std::vector<DETECTBOX> &measurements,
|
| 130 |
+
bool only_position)
|
| 131 |
+
{
|
| 132 |
+
KAL_HDATA pa = this->project(mean, covariance);
|
| 133 |
+
if (only_position) {
|
| 134 |
+
printf("not implement!");
|
| 135 |
+
exit(0);
|
| 136 |
+
}
|
| 137 |
+
KAL_HMEAN mean1 = pa.first;
|
| 138 |
+
KAL_HCOVA covariance1 = pa.second;
|
| 139 |
+
|
| 140 |
+
// Eigen::Matrix<float, -1, 4, Eigen::RowMajor> d(size, 4);
|
| 141 |
+
DETECTBOXSS d(measurements.size(), 4);
|
| 142 |
+
int pos = 0;
|
| 143 |
+
for (DETECTBOX box : measurements) {
|
| 144 |
+
d.row(pos++) = box - mean1;
|
| 145 |
+
}
|
| 146 |
+
Eigen::Matrix<float, -1, -1, Eigen::RowMajor> factor = covariance1.llt().matrixL();
|
| 147 |
+
Eigen::Matrix<float, -1, -1> z = factor.triangularView<Eigen::Lower>().solve<Eigen::OnTheRight>(d).transpose();
|
| 148 |
+
auto zz = ((z.array())*(z.array())).matrix();
|
| 149 |
+
auto square_maha = zz.colwise().sum();
|
| 150 |
+
return square_maha;
|
| 151 |
+
}
|
| 152 |
+
}
|
deploy/ncnn/cpp/src/lapjv.cpp
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <stdio.h>
|
| 2 |
+
#include <stdlib.h>
|
| 3 |
+
#include <string.h>
|
| 4 |
+
|
| 5 |
+
#include "lapjv.h"
|
| 6 |
+
|
| 7 |
+
/** Column-reduction and reduction transfer for a dense cost matrix.
|
| 8 |
+
*/
|
| 9 |
+
int_t _ccrrt_dense(const uint_t n, cost_t *cost[],
|
| 10 |
+
int_t *free_rows, int_t *x, int_t *y, cost_t *v)
|
| 11 |
+
{
|
| 12 |
+
int_t n_free_rows;
|
| 13 |
+
boolean *unique;
|
| 14 |
+
|
| 15 |
+
for (uint_t i = 0; i < n; i++) {
|
| 16 |
+
x[i] = -1;
|
| 17 |
+
v[i] = LARGE;
|
| 18 |
+
y[i] = 0;
|
| 19 |
+
}
|
| 20 |
+
for (uint_t i = 0; i < n; i++) {
|
| 21 |
+
for (uint_t j = 0; j < n; j++) {
|
| 22 |
+
const cost_t c = cost[i][j];
|
| 23 |
+
if (c < v[j]) {
|
| 24 |
+
v[j] = c;
|
| 25 |
+
y[j] = i;
|
| 26 |
+
}
|
| 27 |
+
PRINTF("i=%d, j=%d, c[i,j]=%f, v[j]=%f y[j]=%d\n", i, j, c, v[j], y[j]);
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
PRINT_COST_ARRAY(v, n);
|
| 31 |
+
PRINT_INDEX_ARRAY(y, n);
|
| 32 |
+
NEW(unique, boolean, n);
|
| 33 |
+
memset(unique, TRUE, n);
|
| 34 |
+
{
|
| 35 |
+
int_t j = n;
|
| 36 |
+
do {
|
| 37 |
+
j--;
|
| 38 |
+
const int_t i = y[j];
|
| 39 |
+
if (x[i] < 0) {
|
| 40 |
+
x[i] = j;
|
| 41 |
+
}
|
| 42 |
+
else {
|
| 43 |
+
unique[i] = FALSE;
|
| 44 |
+
y[j] = -1;
|
| 45 |
+
}
|
| 46 |
+
} while (j > 0);
|
| 47 |
+
}
|
| 48 |
+
n_free_rows = 0;
|
| 49 |
+
for (uint_t i = 0; i < n; i++) {
|
| 50 |
+
if (x[i] < 0) {
|
| 51 |
+
free_rows[n_free_rows++] = i;
|
| 52 |
+
}
|
| 53 |
+
else if (unique[i]) {
|
| 54 |
+
const int_t j = x[i];
|
| 55 |
+
cost_t min = LARGE;
|
| 56 |
+
for (uint_t j2 = 0; j2 < n; j2++) {
|
| 57 |
+
if (j2 == (uint_t)j) {
|
| 58 |
+
continue;
|
| 59 |
+
}
|
| 60 |
+
const cost_t c = cost[i][j2] - v[j2];
|
| 61 |
+
if (c < min) {
|
| 62 |
+
min = c;
|
| 63 |
+
}
|
| 64 |
+
}
|
| 65 |
+
PRINTF("v[%d] = %f - %f\n", j, v[j], min);
|
| 66 |
+
v[j] -= min;
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
FREE(unique);
|
| 70 |
+
return n_free_rows;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
/** Augmenting row reduction for a dense cost matrix.
|
| 75 |
+
*/
|
| 76 |
+
int_t _carr_dense(
|
| 77 |
+
const uint_t n, cost_t *cost[],
|
| 78 |
+
const uint_t n_free_rows,
|
| 79 |
+
int_t *free_rows, int_t *x, int_t *y, cost_t *v)
|
| 80 |
+
{
|
| 81 |
+
uint_t current = 0;
|
| 82 |
+
int_t new_free_rows = 0;
|
| 83 |
+
uint_t rr_cnt = 0;
|
| 84 |
+
PRINT_INDEX_ARRAY(x, n);
|
| 85 |
+
PRINT_INDEX_ARRAY(y, n);
|
| 86 |
+
PRINT_COST_ARRAY(v, n);
|
| 87 |
+
PRINT_INDEX_ARRAY(free_rows, n_free_rows);
|
| 88 |
+
while (current < n_free_rows) {
|
| 89 |
+
int_t i0;
|
| 90 |
+
int_t j1, j2;
|
| 91 |
+
cost_t v1, v2, v1_new;
|
| 92 |
+
boolean v1_lowers;
|
| 93 |
+
|
| 94 |
+
rr_cnt++;
|
| 95 |
+
PRINTF("current = %d rr_cnt = %d\n", current, rr_cnt);
|
| 96 |
+
const int_t free_i = free_rows[current++];
|
| 97 |
+
j1 = 0;
|
| 98 |
+
v1 = cost[free_i][0] - v[0];
|
| 99 |
+
j2 = -1;
|
| 100 |
+
v2 = LARGE;
|
| 101 |
+
for (uint_t j = 1; j < n; j++) {
|
| 102 |
+
PRINTF("%d = %f %d = %f\n", j1, v1, j2, v2);
|
| 103 |
+
const cost_t c = cost[free_i][j] - v[j];
|
| 104 |
+
if (c < v2) {
|
| 105 |
+
if (c >= v1) {
|
| 106 |
+
v2 = c;
|
| 107 |
+
j2 = j;
|
| 108 |
+
}
|
| 109 |
+
else {
|
| 110 |
+
v2 = v1;
|
| 111 |
+
v1 = c;
|
| 112 |
+
j2 = j1;
|
| 113 |
+
j1 = j;
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
}
|
| 117 |
+
i0 = y[j1];
|
| 118 |
+
v1_new = v[j1] - (v2 - v1);
|
| 119 |
+
v1_lowers = v1_new < v[j1];
|
| 120 |
+
PRINTF("%d %d 1=%d,%f 2=%d,%f v1'=%f(%d,%g) \n", free_i, i0, j1, v1, j2, v2, v1_new, v1_lowers, v[j1] - v1_new);
|
| 121 |
+
if (rr_cnt < current * n) {
|
| 122 |
+
if (v1_lowers) {
|
| 123 |
+
v[j1] = v1_new;
|
| 124 |
+
}
|
| 125 |
+
else if (i0 >= 0 && j2 >= 0) {
|
| 126 |
+
j1 = j2;
|
| 127 |
+
i0 = y[j2];
|
| 128 |
+
}
|
| 129 |
+
if (i0 >= 0) {
|
| 130 |
+
if (v1_lowers) {
|
| 131 |
+
free_rows[--current] = i0;
|
| 132 |
+
}
|
| 133 |
+
else {
|
| 134 |
+
free_rows[new_free_rows++] = i0;
|
| 135 |
+
}
|
| 136 |
+
}
|
| 137 |
+
}
|
| 138 |
+
else {
|
| 139 |
+
PRINTF("rr_cnt=%d >= %d (current=%d * n=%d)\n", rr_cnt, current * n, current, n);
|
| 140 |
+
if (i0 >= 0) {
|
| 141 |
+
free_rows[new_free_rows++] = i0;
|
| 142 |
+
}
|
| 143 |
+
}
|
| 144 |
+
x[free_i] = j1;
|
| 145 |
+
y[j1] = free_i;
|
| 146 |
+
}
|
| 147 |
+
return new_free_rows;
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
/** Find columns with minimum d[j] and put them on the SCAN list.
|
| 152 |
+
*/
|
| 153 |
+
uint_t _find_dense(const uint_t n, uint_t lo, cost_t *d, int_t *cols, int_t *y)
|
| 154 |
+
{
|
| 155 |
+
uint_t hi = lo + 1;
|
| 156 |
+
cost_t mind = d[cols[lo]];
|
| 157 |
+
for (uint_t k = hi; k < n; k++) {
|
| 158 |
+
int_t j = cols[k];
|
| 159 |
+
if (d[j] <= mind) {
|
| 160 |
+
if (d[j] < mind) {
|
| 161 |
+
hi = lo;
|
| 162 |
+
mind = d[j];
|
| 163 |
+
}
|
| 164 |
+
cols[k] = cols[hi];
|
| 165 |
+
cols[hi++] = j;
|
| 166 |
+
}
|
| 167 |
+
}
|
| 168 |
+
return hi;
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
// Scan all columns in TODO starting from arbitrary column in SCAN
|
| 173 |
+
// and try to decrease d of the TODO columns using the SCAN column.
|
| 174 |
+
int_t _scan_dense(const uint_t n, cost_t *cost[],
|
| 175 |
+
uint_t *plo, uint_t*phi,
|
| 176 |
+
cost_t *d, int_t *cols, int_t *pred,
|
| 177 |
+
int_t *y, cost_t *v)
|
| 178 |
+
{
|
| 179 |
+
uint_t lo = *plo;
|
| 180 |
+
uint_t hi = *phi;
|
| 181 |
+
cost_t h, cred_ij;
|
| 182 |
+
|
| 183 |
+
while (lo != hi) {
|
| 184 |
+
int_t j = cols[lo++];
|
| 185 |
+
const int_t i = y[j];
|
| 186 |
+
const cost_t mind = d[j];
|
| 187 |
+
h = cost[i][j] - v[j] - mind;
|
| 188 |
+
PRINTF("i=%d j=%d h=%f\n", i, j, h);
|
| 189 |
+
// For all columns in TODO
|
| 190 |
+
for (uint_t k = hi; k < n; k++) {
|
| 191 |
+
j = cols[k];
|
| 192 |
+
cred_ij = cost[i][j] - v[j] - h;
|
| 193 |
+
if (cred_ij < d[j]) {
|
| 194 |
+
d[j] = cred_ij;
|
| 195 |
+
pred[j] = i;
|
| 196 |
+
if (cred_ij == mind) {
|
| 197 |
+
if (y[j] < 0) {
|
| 198 |
+
return j;
|
| 199 |
+
}
|
| 200 |
+
cols[k] = cols[hi];
|
| 201 |
+
cols[hi++] = j;
|
| 202 |
+
}
|
| 203 |
+
}
|
| 204 |
+
}
|
| 205 |
+
}
|
| 206 |
+
*plo = lo;
|
| 207 |
+
*phi = hi;
|
| 208 |
+
return -1;
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
/** Single iteration of modified Dijkstra shortest path algorithm as explained in the JV paper.
|
| 213 |
+
*
|
| 214 |
+
* This is a dense matrix version.
|
| 215 |
+
*
|
| 216 |
+
* \return The closest free column index.
|
| 217 |
+
*/
|
| 218 |
+
int_t find_path_dense(
|
| 219 |
+
const uint_t n, cost_t *cost[],
|
| 220 |
+
const int_t start_i,
|
| 221 |
+
int_t *y, cost_t *v,
|
| 222 |
+
int_t *pred)
|
| 223 |
+
{
|
| 224 |
+
uint_t lo = 0, hi = 0;
|
| 225 |
+
int_t final_j = -1;
|
| 226 |
+
uint_t n_ready = 0;
|
| 227 |
+
int_t *cols;
|
| 228 |
+
cost_t *d;
|
| 229 |
+
|
| 230 |
+
NEW(cols, int_t, n);
|
| 231 |
+
NEW(d, cost_t, n);
|
| 232 |
+
|
| 233 |
+
for (uint_t i = 0; i < n; i++) {
|
| 234 |
+
cols[i] = i;
|
| 235 |
+
pred[i] = start_i;
|
| 236 |
+
d[i] = cost[start_i][i] - v[i];
|
| 237 |
+
}
|
| 238 |
+
PRINT_COST_ARRAY(d, n);
|
| 239 |
+
while (final_j == -1) {
|
| 240 |
+
// No columns left on the SCAN list.
|
| 241 |
+
if (lo == hi) {
|
| 242 |
+
PRINTF("%d..%d -> find\n", lo, hi);
|
| 243 |
+
n_ready = lo;
|
| 244 |
+
hi = _find_dense(n, lo, d, cols, y);
|
| 245 |
+
PRINTF("check %d..%d\n", lo, hi);
|
| 246 |
+
PRINT_INDEX_ARRAY(cols, n);
|
| 247 |
+
for (uint_t k = lo; k < hi; k++) {
|
| 248 |
+
const int_t j = cols[k];
|
| 249 |
+
if (y[j] < 0) {
|
| 250 |
+
final_j = j;
|
| 251 |
+
}
|
| 252 |
+
}
|
| 253 |
+
}
|
| 254 |
+
if (final_j == -1) {
|
| 255 |
+
PRINTF("%d..%d -> scan\n", lo, hi);
|
| 256 |
+
final_j = _scan_dense(
|
| 257 |
+
n, cost, &lo, &hi, d, cols, pred, y, v);
|
| 258 |
+
PRINT_COST_ARRAY(d, n);
|
| 259 |
+
PRINT_INDEX_ARRAY(cols, n);
|
| 260 |
+
PRINT_INDEX_ARRAY(pred, n);
|
| 261 |
+
}
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
PRINTF("found final_j=%d\n", final_j);
|
| 265 |
+
PRINT_INDEX_ARRAY(cols, n);
|
| 266 |
+
{
|
| 267 |
+
const cost_t mind = d[cols[lo]];
|
| 268 |
+
for (uint_t k = 0; k < n_ready; k++) {
|
| 269 |
+
const int_t j = cols[k];
|
| 270 |
+
v[j] += d[j] - mind;
|
| 271 |
+
}
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
FREE(cols);
|
| 275 |
+
FREE(d);
|
| 276 |
+
|
| 277 |
+
return final_j;
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
|
| 281 |
+
/** Augment for a dense cost matrix.
|
| 282 |
+
*/
|
| 283 |
+
int_t _ca_dense(
|
| 284 |
+
const uint_t n, cost_t *cost[],
|
| 285 |
+
const uint_t n_free_rows,
|
| 286 |
+
int_t *free_rows, int_t *x, int_t *y, cost_t *v)
|
| 287 |
+
{
|
| 288 |
+
int_t *pred;
|
| 289 |
+
|
| 290 |
+
NEW(pred, int_t, n);
|
| 291 |
+
|
| 292 |
+
for (int_t *pfree_i = free_rows; pfree_i < free_rows + n_free_rows; pfree_i++) {
|
| 293 |
+
int_t i = -1, j;
|
| 294 |
+
uint_t k = 0;
|
| 295 |
+
|
| 296 |
+
PRINTF("looking at free_i=%d\n", *pfree_i);
|
| 297 |
+
j = find_path_dense(n, cost, *pfree_i, y, v, pred);
|
| 298 |
+
ASSERT(j >= 0);
|
| 299 |
+
ASSERT(j < n);
|
| 300 |
+
while (i != *pfree_i) {
|
| 301 |
+
PRINTF("augment %d\n", j);
|
| 302 |
+
PRINT_INDEX_ARRAY(pred, n);
|
| 303 |
+
i = pred[j];
|
| 304 |
+
PRINTF("y[%d]=%d -> %d\n", j, y[j], i);
|
| 305 |
+
y[j] = i;
|
| 306 |
+
PRINT_INDEX_ARRAY(x, n);
|
| 307 |
+
SWAP_INDICES(j, x[i]);
|
| 308 |
+
k++;
|
| 309 |
+
if (k >= n) {
|
| 310 |
+
ASSERT(FALSE);
|
| 311 |
+
}
|
| 312 |
+
}
|
| 313 |
+
}
|
| 314 |
+
FREE(pred);
|
| 315 |
+
return 0;
|
| 316 |
+
}
|
| 317 |
+
|
| 318 |
+
|
| 319 |
+
/** Solve dense sparse LAP.
|
| 320 |
+
*/
|
| 321 |
+
int lapjv_internal(
|
| 322 |
+
const uint_t n, cost_t *cost[],
|
| 323 |
+
int_t *x, int_t *y)
|
| 324 |
+
{
|
| 325 |
+
int ret;
|
| 326 |
+
int_t *free_rows;
|
| 327 |
+
cost_t *v;
|
| 328 |
+
|
| 329 |
+
NEW(free_rows, int_t, n);
|
| 330 |
+
NEW(v, cost_t, n);
|
| 331 |
+
ret = _ccrrt_dense(n, cost, free_rows, x, y, v);
|
| 332 |
+
int i = 0;
|
| 333 |
+
while (ret > 0 && i < 2) {
|
| 334 |
+
ret = _carr_dense(n, cost, ret, free_rows, x, y, v);
|
| 335 |
+
i++;
|
| 336 |
+
}
|
| 337 |
+
if (ret > 0) {
|
| 338 |
+
ret = _ca_dense(n, cost, ret, free_rows, x, y, v);
|
| 339 |
+
}
|
| 340 |
+
FREE(v);
|
| 341 |
+
FREE(free_rows);
|
| 342 |
+
return ret;
|
| 343 |
+
}
|
deploy/ncnn/cpp/src/utils.cpp
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "BYTETracker.h"
|
| 2 |
+
#include "lapjv.h"
|
| 3 |
+
|
| 4 |
+
vector<STrack*> BYTETracker::joint_stracks(vector<STrack*> &tlista, vector<STrack> &tlistb)
|
| 5 |
+
{
|
| 6 |
+
map<int, int> exists;
|
| 7 |
+
vector<STrack*> res;
|
| 8 |
+
for (int i = 0; i < tlista.size(); i++)
|
| 9 |
+
{
|
| 10 |
+
exists.insert(pair<int, int>(tlista[i]->track_id, 1));
|
| 11 |
+
res.push_back(tlista[i]);
|
| 12 |
+
}
|
| 13 |
+
for (int i = 0; i < tlistb.size(); i++)
|
| 14 |
+
{
|
| 15 |
+
int tid = tlistb[i].track_id;
|
| 16 |
+
if (!exists[tid] || exists.count(tid) == 0)
|
| 17 |
+
{
|
| 18 |
+
exists[tid] = 1;
|
| 19 |
+
res.push_back(&tlistb[i]);
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
return res;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
vector<STrack> BYTETracker::joint_stracks(vector<STrack> &tlista, vector<STrack> &tlistb)
|
| 26 |
+
{
|
| 27 |
+
map<int, int> exists;
|
| 28 |
+
vector<STrack> res;
|
| 29 |
+
for (int i = 0; i < tlista.size(); i++)
|
| 30 |
+
{
|
| 31 |
+
exists.insert(pair<int, int>(tlista[i].track_id, 1));
|
| 32 |
+
res.push_back(tlista[i]);
|
| 33 |
+
}
|
| 34 |
+
for (int i = 0; i < tlistb.size(); i++)
|
| 35 |
+
{
|
| 36 |
+
int tid = tlistb[i].track_id;
|
| 37 |
+
if (!exists[tid] || exists.count(tid) == 0)
|
| 38 |
+
{
|
| 39 |
+
exists[tid] = 1;
|
| 40 |
+
res.push_back(tlistb[i]);
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
return res;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
vector<STrack> BYTETracker::sub_stracks(vector<STrack> &tlista, vector<STrack> &tlistb)
|
| 47 |
+
{
|
| 48 |
+
map<int, STrack> stracks;
|
| 49 |
+
for (int i = 0; i < tlista.size(); i++)
|
| 50 |
+
{
|
| 51 |
+
stracks.insert(pair<int, STrack>(tlista[i].track_id, tlista[i]));
|
| 52 |
+
}
|
| 53 |
+
for (int i = 0; i < tlistb.size(); i++)
|
| 54 |
+
{
|
| 55 |
+
int tid = tlistb[i].track_id;
|
| 56 |
+
if (stracks.count(tid) != 0)
|
| 57 |
+
{
|
| 58 |
+
stracks.erase(tid);
|
| 59 |
+
}
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
vector<STrack> res;
|
| 63 |
+
std::map<int, STrack>::iterator it;
|
| 64 |
+
for (it = stracks.begin(); it != stracks.end(); ++it)
|
| 65 |
+
{
|
| 66 |
+
res.push_back(it->second);
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
return res;
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
void BYTETracker::remove_duplicate_stracks(vector<STrack> &resa, vector<STrack> &resb, vector<STrack> &stracksa, vector<STrack> &stracksb)
|
| 73 |
+
{
|
| 74 |
+
vector<vector<float> > pdist = iou_distance(stracksa, stracksb);
|
| 75 |
+
vector<pair<int, int> > pairs;
|
| 76 |
+
for (int i = 0; i < pdist.size(); i++)
|
| 77 |
+
{
|
| 78 |
+
for (int j = 0; j < pdist[i].size(); j++)
|
| 79 |
+
{
|
| 80 |
+
if (pdist[i][j] < 0.15)
|
| 81 |
+
{
|
| 82 |
+
pairs.push_back(pair<int, int>(i, j));
|
| 83 |
+
}
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
vector<int> dupa, dupb;
|
| 88 |
+
for (int i = 0; i < pairs.size(); i++)
|
| 89 |
+
{
|
| 90 |
+
int timep = stracksa[pairs[i].first].frame_id - stracksa[pairs[i].first].start_frame;
|
| 91 |
+
int timeq = stracksb[pairs[i].second].frame_id - stracksb[pairs[i].second].start_frame;
|
| 92 |
+
if (timep > timeq)
|
| 93 |
+
dupb.push_back(pairs[i].second);
|
| 94 |
+
else
|
| 95 |
+
dupa.push_back(pairs[i].first);
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
for (int i = 0; i < stracksa.size(); i++)
|
| 99 |
+
{
|
| 100 |
+
vector<int>::iterator iter = find(dupa.begin(), dupa.end(), i);
|
| 101 |
+
if (iter == dupa.end())
|
| 102 |
+
{
|
| 103 |
+
resa.push_back(stracksa[i]);
|
| 104 |
+
}
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
for (int i = 0; i < stracksb.size(); i++)
|
| 108 |
+
{
|
| 109 |
+
vector<int>::iterator iter = find(dupb.begin(), dupb.end(), i);
|
| 110 |
+
if (iter == dupb.end())
|
| 111 |
+
{
|
| 112 |
+
resb.push_back(stracksb[i]);
|
| 113 |
+
}
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
void BYTETracker::linear_assignment(vector<vector<float> > &cost_matrix, int cost_matrix_size, int cost_matrix_size_size, float thresh,
|
| 118 |
+
vector<vector<int> > &matches, vector<int> &unmatched_a, vector<int> &unmatched_b)
|
| 119 |
+
{
|
| 120 |
+
if (cost_matrix.size() == 0)
|
| 121 |
+
{
|
| 122 |
+
for (int i = 0; i < cost_matrix_size; i++)
|
| 123 |
+
{
|
| 124 |
+
unmatched_a.push_back(i);
|
| 125 |
+
}
|
| 126 |
+
for (int i = 0; i < cost_matrix_size_size; i++)
|
| 127 |
+
{
|
| 128 |
+
unmatched_b.push_back(i);
|
| 129 |
+
}
|
| 130 |
+
return;
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
vector<int> rowsol; vector<int> colsol;
|
| 134 |
+
float c = lapjv(cost_matrix, rowsol, colsol, true, thresh);
|
| 135 |
+
for (int i = 0; i < rowsol.size(); i++)
|
| 136 |
+
{
|
| 137 |
+
if (rowsol[i] >= 0)
|
| 138 |
+
{
|
| 139 |
+
vector<int> match;
|
| 140 |
+
match.push_back(i);
|
| 141 |
+
match.push_back(rowsol[i]);
|
| 142 |
+
matches.push_back(match);
|
| 143 |
+
}
|
| 144 |
+
else
|
| 145 |
+
{
|
| 146 |
+
unmatched_a.push_back(i);
|
| 147 |
+
}
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
for (int i = 0; i < colsol.size(); i++)
|
| 151 |
+
{
|
| 152 |
+
if (colsol[i] < 0)
|
| 153 |
+
{
|
| 154 |
+
unmatched_b.push_back(i);
|
| 155 |
+
}
|
| 156 |
+
}
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
vector<vector<float> > BYTETracker::ious(vector<vector<float> > &atlbrs, vector<vector<float> > &btlbrs)
|
| 160 |
+
{
|
| 161 |
+
vector<vector<float> > ious;
|
| 162 |
+
if (atlbrs.size()*btlbrs.size() == 0)
|
| 163 |
+
return ious;
|
| 164 |
+
|
| 165 |
+
ious.resize(atlbrs.size());
|
| 166 |
+
for (int i = 0; i < ious.size(); i++)
|
| 167 |
+
{
|
| 168 |
+
ious[i].resize(btlbrs.size());
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
//bbox_ious
|
| 172 |
+
for (int k = 0; k < btlbrs.size(); k++)
|
| 173 |
+
{
|
| 174 |
+
vector<float> ious_tmp;
|
| 175 |
+
float box_area = (btlbrs[k][2] - btlbrs[k][0] + 1)*(btlbrs[k][3] - btlbrs[k][1] + 1);
|
| 176 |
+
for (int n = 0; n < atlbrs.size(); n++)
|
| 177 |
+
{
|
| 178 |
+
float iw = min(atlbrs[n][2], btlbrs[k][2]) - max(atlbrs[n][0], btlbrs[k][0]) + 1;
|
| 179 |
+
if (iw > 0)
|
| 180 |
+
{
|
| 181 |
+
float ih = min(atlbrs[n][3], btlbrs[k][3]) - max(atlbrs[n][1], btlbrs[k][1]) + 1;
|
| 182 |
+
if(ih > 0)
|
| 183 |
+
{
|
| 184 |
+
float ua = (atlbrs[n][2] - atlbrs[n][0] + 1)*(atlbrs[n][3] - atlbrs[n][1] + 1) + box_area - iw * ih;
|
| 185 |
+
ious[n][k] = iw * ih / ua;
|
| 186 |
+
}
|
| 187 |
+
else
|
| 188 |
+
{
|
| 189 |
+
ious[n][k] = 0.0;
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
else
|
| 193 |
+
{
|
| 194 |
+
ious[n][k] = 0.0;
|
| 195 |
+
}
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
return ious;
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
vector<vector<float> > BYTETracker::iou_distance(vector<STrack*> &atracks, vector<STrack> &btracks, int &dist_size, int &dist_size_size)
|
| 203 |
+
{
|
| 204 |
+
vector<vector<float> > cost_matrix;
|
| 205 |
+
if (atracks.size() * btracks.size() == 0)
|
| 206 |
+
{
|
| 207 |
+
dist_size = atracks.size();
|
| 208 |
+
dist_size_size = btracks.size();
|
| 209 |
+
return cost_matrix;
|
| 210 |
+
}
|
| 211 |
+
vector<vector<float> > atlbrs, btlbrs;
|
| 212 |
+
for (int i = 0; i < atracks.size(); i++)
|
| 213 |
+
{
|
| 214 |
+
atlbrs.push_back(atracks[i]->tlbr);
|
| 215 |
+
}
|
| 216 |
+
for (int i = 0; i < btracks.size(); i++)
|
| 217 |
+
{
|
| 218 |
+
btlbrs.push_back(btracks[i].tlbr);
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
dist_size = atracks.size();
|
| 222 |
+
dist_size_size = btracks.size();
|
| 223 |
+
|
| 224 |
+
vector<vector<float> > _ious = ious(atlbrs, btlbrs);
|
| 225 |
+
|
| 226 |
+
for (int i = 0; i < _ious.size();i++)
|
| 227 |
+
{
|
| 228 |
+
vector<float> _iou;
|
| 229 |
+
for (int j = 0; j < _ious[i].size(); j++)
|
| 230 |
+
{
|
| 231 |
+
_iou.push_back(1 - _ious[i][j]);
|
| 232 |
+
}
|
| 233 |
+
cost_matrix.push_back(_iou);
|
| 234 |
+
}
|
| 235 |
+
|
| 236 |
+
return cost_matrix;
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
vector<vector<float> > BYTETracker::iou_distance(vector<STrack> &atracks, vector<STrack> &btracks)
|
| 240 |
+
{
|
| 241 |
+
vector<vector<float> > atlbrs, btlbrs;
|
| 242 |
+
for (int i = 0; i < atracks.size(); i++)
|
| 243 |
+
{
|
| 244 |
+
atlbrs.push_back(atracks[i].tlbr);
|
| 245 |
+
}
|
| 246 |
+
for (int i = 0; i < btracks.size(); i++)
|
| 247 |
+
{
|
| 248 |
+
btlbrs.push_back(btracks[i].tlbr);
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
vector<vector<float> > _ious = ious(atlbrs, btlbrs);
|
| 252 |
+
vector<vector<float> > cost_matrix;
|
| 253 |
+
for (int i = 0; i < _ious.size(); i++)
|
| 254 |
+
{
|
| 255 |
+
vector<float> _iou;
|
| 256 |
+
for (int j = 0; j < _ious[i].size(); j++)
|
| 257 |
+
{
|
| 258 |
+
_iou.push_back(1 - _ious[i][j]);
|
| 259 |
+
}
|
| 260 |
+
cost_matrix.push_back(_iou);
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
return cost_matrix;
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
double BYTETracker::lapjv(const vector<vector<float> > &cost, vector<int> &rowsol, vector<int> &colsol,
|
| 267 |
+
bool extend_cost, float cost_limit, bool return_cost)
|
| 268 |
+
{
|
| 269 |
+
vector<vector<float> > cost_c;
|
| 270 |
+
cost_c.assign(cost.begin(), cost.end());
|
| 271 |
+
|
| 272 |
+
vector<vector<float> > cost_c_extended;
|
| 273 |
+
|
| 274 |
+
int n_rows = cost.size();
|
| 275 |
+
int n_cols = cost[0].size();
|
| 276 |
+
rowsol.resize(n_rows);
|
| 277 |
+
colsol.resize(n_cols);
|
| 278 |
+
|
| 279 |
+
int n = 0;
|
| 280 |
+
if (n_rows == n_cols)
|
| 281 |
+
{
|
| 282 |
+
n = n_rows;
|
| 283 |
+
}
|
| 284 |
+
else
|
| 285 |
+
{
|
| 286 |
+
if (!extend_cost)
|
| 287 |
+
{
|
| 288 |
+
cout << "set extend_cost=True" << endl;
|
| 289 |
+
system("pause");
|
| 290 |
+
exit(0);
|
| 291 |
+
}
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
if (extend_cost || cost_limit < LONG_MAX)
|
| 295 |
+
{
|
| 296 |
+
n = n_rows + n_cols;
|
| 297 |
+
cost_c_extended.resize(n);
|
| 298 |
+
for (int i = 0; i < cost_c_extended.size(); i++)
|
| 299 |
+
cost_c_extended[i].resize(n);
|
| 300 |
+
|
| 301 |
+
if (cost_limit < LONG_MAX)
|
| 302 |
+
{
|
| 303 |
+
for (int i = 0; i < cost_c_extended.size(); i++)
|
| 304 |
+
{
|
| 305 |
+
for (int j = 0; j < cost_c_extended[i].size(); j++)
|
| 306 |
+
{
|
| 307 |
+
cost_c_extended[i][j] = cost_limit / 2.0;
|
| 308 |
+
}
|
| 309 |
+
}
|
| 310 |
+
}
|
| 311 |
+
else
|
| 312 |
+
{
|
| 313 |
+
float cost_max = -1;
|
| 314 |
+
for (int i = 0; i < cost_c.size(); i++)
|
| 315 |
+
{
|
| 316 |
+
for (int j = 0; j < cost_c[i].size(); j++)
|
| 317 |
+
{
|
| 318 |
+
if (cost_c[i][j] > cost_max)
|
| 319 |
+
cost_max = cost_c[i][j];
|
| 320 |
+
}
|
| 321 |
+
}
|
| 322 |
+
for (int i = 0; i < cost_c_extended.size(); i++)
|
| 323 |
+
{
|
| 324 |
+
for (int j = 0; j < cost_c_extended[i].size(); j++)
|
| 325 |
+
{
|
| 326 |
+
cost_c_extended[i][j] = cost_max + 1;
|
| 327 |
+
}
|
| 328 |
+
}
|
| 329 |
+
}
|
| 330 |
+
|
| 331 |
+
for (int i = n_rows; i < cost_c_extended.size(); i++)
|
| 332 |
+
{
|
| 333 |
+
for (int j = n_cols; j < cost_c_extended[i].size(); j++)
|
| 334 |
+
{
|
| 335 |
+
cost_c_extended[i][j] = 0;
|
| 336 |
+
}
|
| 337 |
+
}
|
| 338 |
+
for (int i = 0; i < n_rows; i++)
|
| 339 |
+
{
|
| 340 |
+
for (int j = 0; j < n_cols; j++)
|
| 341 |
+
{
|
| 342 |
+
cost_c_extended[i][j] = cost_c[i][j];
|
| 343 |
+
}
|
| 344 |
+
}
|
| 345 |
+
|
| 346 |
+
cost_c.clear();
|
| 347 |
+
cost_c.assign(cost_c_extended.begin(), cost_c_extended.end());
|
| 348 |
+
}
|
| 349 |
+
|
| 350 |
+
double **cost_ptr;
|
| 351 |
+
cost_ptr = new double *[sizeof(double *) * n];
|
| 352 |
+
for (int i = 0; i < n; i++)
|
| 353 |
+
cost_ptr[i] = new double[sizeof(double) * n];
|
| 354 |
+
|
| 355 |
+
for (int i = 0; i < n; i++)
|
| 356 |
+
{
|
| 357 |
+
for (int j = 0; j < n; j++)
|
| 358 |
+
{
|
| 359 |
+
cost_ptr[i][j] = cost_c[i][j];
|
| 360 |
+
}
|
| 361 |
+
}
|
| 362 |
+
|
| 363 |
+
int* x_c = new int[sizeof(int) * n];
|
| 364 |
+
int *y_c = new int[sizeof(int) * n];
|
| 365 |
+
|
| 366 |
+
int ret = lapjv_internal(n, cost_ptr, x_c, y_c);
|
| 367 |
+
if (ret != 0)
|
| 368 |
+
{
|
| 369 |
+
cout << "Calculate Wrong!" << endl;
|
| 370 |
+
system("pause");
|
| 371 |
+
exit(0);
|
| 372 |
+
}
|
| 373 |
+
|
| 374 |
+
double opt = 0.0;
|
| 375 |
+
|
| 376 |
+
if (n != n_rows)
|
| 377 |
+
{
|
| 378 |
+
for (int i = 0; i < n; i++)
|
| 379 |
+
{
|
| 380 |
+
if (x_c[i] >= n_cols)
|
| 381 |
+
x_c[i] = -1;
|
| 382 |
+
if (y_c[i] >= n_rows)
|
| 383 |
+
y_c[i] = -1;
|
| 384 |
+
}
|
| 385 |
+
for (int i = 0; i < n_rows; i++)
|
| 386 |
+
{
|
| 387 |
+
rowsol[i] = x_c[i];
|
| 388 |
+
}
|
| 389 |
+
for (int i = 0; i < n_cols; i++)
|
| 390 |
+
{
|
| 391 |
+
colsol[i] = y_c[i];
|
| 392 |
+
}
|
| 393 |
+
|
| 394 |
+
if (return_cost)
|
| 395 |
+
{
|
| 396 |
+
for (int i = 0; i < rowsol.size(); i++)
|
| 397 |
+
{
|
| 398 |
+
if (rowsol[i] != -1)
|
| 399 |
+
{
|
| 400 |
+
//cout << i << "\t" << rowsol[i] << "\t" << cost_ptr[i][rowsol[i]] << endl;
|
| 401 |
+
opt += cost_ptr[i][rowsol[i]];
|
| 402 |
+
}
|
| 403 |
+
}
|
| 404 |
+
}
|
| 405 |
+
}
|
| 406 |
+
else if (return_cost)
|
| 407 |
+
{
|
| 408 |
+
for (int i = 0; i < rowsol.size(); i++)
|
| 409 |
+
{
|
| 410 |
+
opt += cost_ptr[i][rowsol[i]];
|
| 411 |
+
}
|
| 412 |
+
}
|
| 413 |
+
|
| 414 |
+
for (int i = 0; i < n; i++)
|
| 415 |
+
{
|
| 416 |
+
delete[]cost_ptr[i];
|
| 417 |
+
}
|
| 418 |
+
delete[]cost_ptr;
|
| 419 |
+
delete[]x_c;
|
| 420 |
+
delete[]y_c;
|
| 421 |
+
|
| 422 |
+
return opt;
|
| 423 |
+
}
|
| 424 |
+
|
| 425 |
+
Scalar BYTETracker::get_color(int idx)
|
| 426 |
+
{
|
| 427 |
+
idx += 3;
|
| 428 |
+
return Scalar(37 * idx % 255, 17 * idx % 255, 29 * idx % 255);
|
| 429 |
+
}
|
exps/default/nano.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# -*- coding:utf-8 -*-
|
| 3 |
+
# Copyright (c) Megvii, Inc. and its affiliates.
|
| 4 |
+
|
| 5 |
+
import os
|
| 6 |
+
import torch.nn as nn
|
| 7 |
+
|
| 8 |
+
from yolox.exp import Exp as MyExp
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
class Exp(MyExp):
|
| 12 |
+
def __init__(self):
|
| 13 |
+
super(Exp, self).__init__()
|
| 14 |
+
self.depth = 0.33
|
| 15 |
+
self.width = 0.25
|
| 16 |
+
self.scale = (0.5, 1.5)
|
| 17 |
+
self.random_size = (10, 20)
|
| 18 |
+
self.test_size = (416, 416)
|
| 19 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
| 20 |
+
self.enable_mixup = False
|
| 21 |
+
|
| 22 |
+
def get_model(self, sublinear=False):
|
| 23 |
+
|
| 24 |
+
def init_yolo(M):
|
| 25 |
+
for m in M.modules():
|
| 26 |
+
if isinstance(m, nn.BatchNorm2d):
|
| 27 |
+
m.eps = 1e-3
|
| 28 |
+
m.momentum = 0.03
|
| 29 |
+
if "model" not in self.__dict__:
|
| 30 |
+
from yolox.models import YOLOX, YOLOPAFPN, YOLOXHead
|
| 31 |
+
in_channels = [256, 512, 1024]
|
| 32 |
+
# NANO model use depthwise = True, which is main difference.
|
| 33 |
+
backbone = YOLOPAFPN(self.depth, self.width, in_channels=in_channels, depthwise=True)
|
| 34 |
+
head = YOLOXHead(self.num_classes, self.width, in_channels=in_channels, depthwise=True)
|
| 35 |
+
self.model = YOLOX(backbone, head)
|
| 36 |
+
|
| 37 |
+
self.model.apply(init_yolo)
|
| 38 |
+
self.model.head.initialize_biases(1e-2)
|
| 39 |
+
return self.model
|
exps/default/yolov3.py
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# -*- coding:utf-8 -*-
|
| 3 |
+
# Copyright (c) Megvii, Inc. and its affiliates.
|
| 4 |
+
|
| 5 |
+
import os
|
| 6 |
+
import torch
|
| 7 |
+
import torch.nn as nn
|
| 8 |
+
|
| 9 |
+
from yolox.exp import Exp as MyExp
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
class Exp(MyExp):
|
| 13 |
+
def __init__(self):
|
| 14 |
+
super(Exp, self).__init__()
|
| 15 |
+
self.depth = 1.0
|
| 16 |
+
self.width = 1.0
|
| 17 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
| 18 |
+
|
| 19 |
+
def get_model(self, sublinear=False):
|
| 20 |
+
def init_yolo(M):
|
| 21 |
+
for m in M.modules():
|
| 22 |
+
if isinstance(m, nn.BatchNorm2d):
|
| 23 |
+
m.eps = 1e-3
|
| 24 |
+
m.momentum = 0.03
|
| 25 |
+
if "model" not in self.__dict__:
|
| 26 |
+
from yolox.models import YOLOX, YOLOFPN, YOLOXHead
|
| 27 |
+
backbone = YOLOFPN()
|
| 28 |
+
head = YOLOXHead(self.num_classes, self.width, in_channels=[128, 256, 512], act="lrelu")
|
| 29 |
+
self.model = YOLOX(backbone, head)
|
| 30 |
+
self.model.apply(init_yolo)
|
| 31 |
+
self.model.head.initialize_biases(1e-2)
|
| 32 |
+
|
| 33 |
+
return self.model
|
| 34 |
+
|
| 35 |
+
def get_data_loader(self, batch_size, is_distributed, no_aug=False):
|
| 36 |
+
from data.datasets.cocodataset import COCODataset
|
| 37 |
+
from data.datasets.mosaicdetection import MosaicDetection
|
| 38 |
+
from data.datasets.data_augment import TrainTransform
|
| 39 |
+
from data.datasets.dataloading import YoloBatchSampler, DataLoader, InfiniteSampler
|
| 40 |
+
import torch.distributed as dist
|
| 41 |
+
|
| 42 |
+
dataset = COCODataset(
|
| 43 |
+
data_dir='data/COCO/',
|
| 44 |
+
json_file=self.train_ann,
|
| 45 |
+
img_size=self.input_size,
|
| 46 |
+
preproc=TrainTransform(
|
| 47 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 48 |
+
std=(0.229, 0.224, 0.225),
|
| 49 |
+
max_labels=50
|
| 50 |
+
),
|
| 51 |
+
)
|
| 52 |
+
|
| 53 |
+
dataset = MosaicDetection(
|
| 54 |
+
dataset,
|
| 55 |
+
mosaic=not no_aug,
|
| 56 |
+
img_size=self.input_size,
|
| 57 |
+
preproc=TrainTransform(
|
| 58 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 59 |
+
std=(0.229, 0.224, 0.225),
|
| 60 |
+
max_labels=120
|
| 61 |
+
),
|
| 62 |
+
degrees=self.degrees,
|
| 63 |
+
translate=self.translate,
|
| 64 |
+
scale=self.scale,
|
| 65 |
+
shear=self.shear,
|
| 66 |
+
perspective=self.perspective,
|
| 67 |
+
)
|
| 68 |
+
|
| 69 |
+
self.dataset = dataset
|
| 70 |
+
|
| 71 |
+
if is_distributed:
|
| 72 |
+
batch_size = batch_size // dist.get_world_size()
|
| 73 |
+
sampler = InfiniteSampler(len(self.dataset), seed=self.seed if self.seed else 0)
|
| 74 |
+
else:
|
| 75 |
+
sampler = torch.utils.data.RandomSampler(self.dataset)
|
| 76 |
+
|
| 77 |
+
batch_sampler = YoloBatchSampler(
|
| 78 |
+
sampler=sampler,
|
| 79 |
+
batch_size=batch_size,
|
| 80 |
+
drop_last=False,
|
| 81 |
+
input_dimension=self.input_size,
|
| 82 |
+
mosaic=not no_aug
|
| 83 |
+
)
|
| 84 |
+
|
| 85 |
+
dataloader_kwargs = {"num_workers": self.data_num_workers, "pin_memory": True}
|
| 86 |
+
dataloader_kwargs["batch_sampler"] = batch_sampler
|
| 87 |
+
train_loader = DataLoader(self.dataset, **dataloader_kwargs)
|
| 88 |
+
|
| 89 |
+
return train_loader
|
exps/default/yolox_l.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# -*- coding:utf-8 -*-
|
| 3 |
+
# Copyright (c) Megvii, Inc. and its affiliates.
|
| 4 |
+
|
| 5 |
+
import os
|
| 6 |
+
|
| 7 |
+
from yolox.exp import Exp as MyExp
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
class Exp(MyExp):
|
| 11 |
+
def __init__(self):
|
| 12 |
+
super(Exp, self).__init__()
|
| 13 |
+
self.depth = 1.0
|
| 14 |
+
self.width = 1.0
|
| 15 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
exps/default/yolox_m.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# -*- coding:utf-8 -*-
|
| 3 |
+
# Copyright (c) Megvii, Inc. and its affiliates.
|
| 4 |
+
|
| 5 |
+
import os
|
| 6 |
+
|
| 7 |
+
from yolox.exp import Exp as MyExp
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
class Exp(MyExp):
|
| 11 |
+
def __init__(self):
|
| 12 |
+
super(Exp, self).__init__()
|
| 13 |
+
self.depth = 0.67
|
| 14 |
+
self.width = 0.75
|
| 15 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
exps/default/yolox_s.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# -*- coding:utf-8 -*-
|
| 3 |
+
# Copyright (c) Megvii, Inc. and its affiliates.
|
| 4 |
+
|
| 5 |
+
import os
|
| 6 |
+
|
| 7 |
+
from yolox.exp import Exp as MyExp
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
class Exp(MyExp):
|
| 11 |
+
def __init__(self):
|
| 12 |
+
super(Exp, self).__init__()
|
| 13 |
+
self.depth = 0.33
|
| 14 |
+
self.width = 0.50
|
| 15 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
exps/default/yolox_tiny.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# -*- coding:utf-8 -*-
|
| 3 |
+
# Copyright (c) Megvii, Inc. and its affiliates.
|
| 4 |
+
|
| 5 |
+
import os
|
| 6 |
+
|
| 7 |
+
from yolox.exp import Exp as MyExp
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
class Exp(MyExp):
|
| 11 |
+
def __init__(self):
|
| 12 |
+
super(Exp, self).__init__()
|
| 13 |
+
self.depth = 0.33
|
| 14 |
+
self.width = 0.375
|
| 15 |
+
self.scale = (0.5, 1.5)
|
| 16 |
+
self.random_size = (10, 20)
|
| 17 |
+
self.test_size = (416, 416)
|
| 18 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
| 19 |
+
self.enable_mixup = False
|
exps/default/yolox_x.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# -*- coding:utf-8 -*-
|
| 3 |
+
# Copyright (c) Megvii, Inc. and its affiliates.
|
| 4 |
+
|
| 5 |
+
import os
|
| 6 |
+
|
| 7 |
+
from yolox.exp import Exp as MyExp
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
class Exp(MyExp):
|
| 11 |
+
def __init__(self):
|
| 12 |
+
super(Exp, self).__init__()
|
| 13 |
+
self.depth = 1.33
|
| 14 |
+
self.width = 1.25
|
| 15 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
exps/example/mot/yolox_l_mix_det.py
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# encoding: utf-8
|
| 2 |
+
import os
|
| 3 |
+
import random
|
| 4 |
+
import torch
|
| 5 |
+
import torch.nn as nn
|
| 6 |
+
import torch.distributed as dist
|
| 7 |
+
|
| 8 |
+
from yolox.exp import Exp as MyExp
|
| 9 |
+
from yolox.data import get_yolox_datadir
|
| 10 |
+
|
| 11 |
+
class Exp(MyExp):
|
| 12 |
+
def __init__(self):
|
| 13 |
+
super(Exp, self).__init__()
|
| 14 |
+
self.num_classes = 1
|
| 15 |
+
self.depth = 1.0
|
| 16 |
+
self.width = 1.0
|
| 17 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
| 18 |
+
self.train_ann = "train.json"
|
| 19 |
+
self.val_ann = "train.json"
|
| 20 |
+
self.input_size = (800, 1440)
|
| 21 |
+
self.test_size = (800, 1440)
|
| 22 |
+
self.random_size = (18, 32)
|
| 23 |
+
self.max_epoch = 80
|
| 24 |
+
self.print_interval = 20
|
| 25 |
+
self.eval_interval = 5
|
| 26 |
+
self.test_conf = 0.001
|
| 27 |
+
self.nmsthre = 0.7
|
| 28 |
+
self.no_aug_epochs = 10
|
| 29 |
+
self.basic_lr_per_img = 0.001 / 64.0
|
| 30 |
+
self.warmup_epochs = 1
|
| 31 |
+
|
| 32 |
+
def get_data_loader(self, batch_size, is_distributed, no_aug=False):
|
| 33 |
+
from yolox.data import (
|
| 34 |
+
MOTDataset,
|
| 35 |
+
TrainTransform,
|
| 36 |
+
YoloBatchSampler,
|
| 37 |
+
DataLoader,
|
| 38 |
+
InfiniteSampler,
|
| 39 |
+
MosaicDetection,
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
dataset = MOTDataset(
|
| 43 |
+
data_dir=os.path.join(get_yolox_datadir(), "mix_det"),
|
| 44 |
+
json_file=self.train_ann,
|
| 45 |
+
name='',
|
| 46 |
+
img_size=self.input_size,
|
| 47 |
+
preproc=TrainTransform(
|
| 48 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 49 |
+
std=(0.229, 0.224, 0.225),
|
| 50 |
+
max_labels=500,
|
| 51 |
+
),
|
| 52 |
+
)
|
| 53 |
+
|
| 54 |
+
dataset = MosaicDetection(
|
| 55 |
+
dataset,
|
| 56 |
+
mosaic=not no_aug,
|
| 57 |
+
img_size=self.input_size,
|
| 58 |
+
preproc=TrainTransform(
|
| 59 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 60 |
+
std=(0.229, 0.224, 0.225),
|
| 61 |
+
max_labels=1000,
|
| 62 |
+
),
|
| 63 |
+
degrees=self.degrees,
|
| 64 |
+
translate=self.translate,
|
| 65 |
+
scale=self.scale,
|
| 66 |
+
shear=self.shear,
|
| 67 |
+
perspective=self.perspective,
|
| 68 |
+
enable_mixup=self.enable_mixup,
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
self.dataset = dataset
|
| 72 |
+
|
| 73 |
+
if is_distributed:
|
| 74 |
+
batch_size = batch_size // dist.get_world_size()
|
| 75 |
+
|
| 76 |
+
sampler = InfiniteSampler(
|
| 77 |
+
len(self.dataset), seed=self.seed if self.seed else 0
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
batch_sampler = YoloBatchSampler(
|
| 81 |
+
sampler=sampler,
|
| 82 |
+
batch_size=batch_size,
|
| 83 |
+
drop_last=False,
|
| 84 |
+
input_dimension=self.input_size,
|
| 85 |
+
mosaic=not no_aug,
|
| 86 |
+
)
|
| 87 |
+
|
| 88 |
+
dataloader_kwargs = {"num_workers": self.data_num_workers, "pin_memory": True}
|
| 89 |
+
dataloader_kwargs["batch_sampler"] = batch_sampler
|
| 90 |
+
train_loader = DataLoader(self.dataset, **dataloader_kwargs)
|
| 91 |
+
|
| 92 |
+
return train_loader
|
| 93 |
+
|
| 94 |
+
def get_eval_loader(self, batch_size, is_distributed, testdev=False):
|
| 95 |
+
from yolox.data import MOTDataset, ValTransform
|
| 96 |
+
|
| 97 |
+
valdataset = MOTDataset(
|
| 98 |
+
data_dir=os.path.join(get_yolox_datadir(), "mot"),
|
| 99 |
+
json_file=self.val_ann,
|
| 100 |
+
img_size=self.test_size,
|
| 101 |
+
name='train',
|
| 102 |
+
preproc=ValTransform(
|
| 103 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 104 |
+
std=(0.229, 0.224, 0.225),
|
| 105 |
+
),
|
| 106 |
+
)
|
| 107 |
+
|
| 108 |
+
if is_distributed:
|
| 109 |
+
batch_size = batch_size // dist.get_world_size()
|
| 110 |
+
sampler = torch.utils.data.distributed.DistributedSampler(
|
| 111 |
+
valdataset, shuffle=False
|
| 112 |
+
)
|
| 113 |
+
else:
|
| 114 |
+
sampler = torch.utils.data.SequentialSampler(valdataset)
|
| 115 |
+
|
| 116 |
+
dataloader_kwargs = {
|
| 117 |
+
"num_workers": self.data_num_workers,
|
| 118 |
+
"pin_memory": True,
|
| 119 |
+
"sampler": sampler,
|
| 120 |
+
}
|
| 121 |
+
dataloader_kwargs["batch_size"] = batch_size
|
| 122 |
+
val_loader = torch.utils.data.DataLoader(valdataset, **dataloader_kwargs)
|
| 123 |
+
|
| 124 |
+
return val_loader
|
| 125 |
+
|
| 126 |
+
def get_evaluator(self, batch_size, is_distributed, testdev=False):
|
| 127 |
+
from yolox.evaluators import COCOEvaluator
|
| 128 |
+
|
| 129 |
+
val_loader = self.get_eval_loader(batch_size, is_distributed, testdev=testdev)
|
| 130 |
+
evaluator = COCOEvaluator(
|
| 131 |
+
dataloader=val_loader,
|
| 132 |
+
img_size=self.test_size,
|
| 133 |
+
confthre=self.test_conf,
|
| 134 |
+
nmsthre=self.nmsthre,
|
| 135 |
+
num_classes=self.num_classes,
|
| 136 |
+
testdev=testdev,
|
| 137 |
+
)
|
| 138 |
+
return evaluator
|
exps/example/mot/yolox_m_mix_det.py
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# encoding: utf-8
|
| 2 |
+
import os
|
| 3 |
+
import random
|
| 4 |
+
import torch
|
| 5 |
+
import torch.nn as nn
|
| 6 |
+
import torch.distributed as dist
|
| 7 |
+
|
| 8 |
+
from yolox.exp import Exp as MyExp
|
| 9 |
+
from yolox.data import get_yolox_datadir
|
| 10 |
+
|
| 11 |
+
class Exp(MyExp):
|
| 12 |
+
def __init__(self):
|
| 13 |
+
super(Exp, self).__init__()
|
| 14 |
+
self.num_classes = 1
|
| 15 |
+
self.depth = 0.67
|
| 16 |
+
self.width = 0.75
|
| 17 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
| 18 |
+
self.train_ann = "train.json"
|
| 19 |
+
self.val_ann = "train.json"
|
| 20 |
+
self.input_size = (800, 1440)
|
| 21 |
+
self.test_size = (800, 1440)
|
| 22 |
+
self.random_size = (18, 32)
|
| 23 |
+
self.max_epoch = 80
|
| 24 |
+
self.print_interval = 20
|
| 25 |
+
self.eval_interval = 5
|
| 26 |
+
self.test_conf = 0.001
|
| 27 |
+
self.nmsthre = 0.7
|
| 28 |
+
self.no_aug_epochs = 10
|
| 29 |
+
self.basic_lr_per_img = 0.001 / 64.0
|
| 30 |
+
self.warmup_epochs = 1
|
| 31 |
+
|
| 32 |
+
def get_data_loader(self, batch_size, is_distributed, no_aug=False):
|
| 33 |
+
from yolox.data import (
|
| 34 |
+
MOTDataset,
|
| 35 |
+
TrainTransform,
|
| 36 |
+
YoloBatchSampler,
|
| 37 |
+
DataLoader,
|
| 38 |
+
InfiniteSampler,
|
| 39 |
+
MosaicDetection,
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
dataset = MOTDataset(
|
| 43 |
+
data_dir=os.path.join(get_yolox_datadir(), "mix_det"),
|
| 44 |
+
json_file=self.train_ann,
|
| 45 |
+
name='',
|
| 46 |
+
img_size=self.input_size,
|
| 47 |
+
preproc=TrainTransform(
|
| 48 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 49 |
+
std=(0.229, 0.224, 0.225),
|
| 50 |
+
max_labels=500,
|
| 51 |
+
),
|
| 52 |
+
)
|
| 53 |
+
|
| 54 |
+
dataset = MosaicDetection(
|
| 55 |
+
dataset,
|
| 56 |
+
mosaic=not no_aug,
|
| 57 |
+
img_size=self.input_size,
|
| 58 |
+
preproc=TrainTransform(
|
| 59 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 60 |
+
std=(0.229, 0.224, 0.225),
|
| 61 |
+
max_labels=1000,
|
| 62 |
+
),
|
| 63 |
+
degrees=self.degrees,
|
| 64 |
+
translate=self.translate,
|
| 65 |
+
scale=self.scale,
|
| 66 |
+
shear=self.shear,
|
| 67 |
+
perspective=self.perspective,
|
| 68 |
+
enable_mixup=self.enable_mixup,
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
self.dataset = dataset
|
| 72 |
+
|
| 73 |
+
if is_distributed:
|
| 74 |
+
batch_size = batch_size // dist.get_world_size()
|
| 75 |
+
|
| 76 |
+
sampler = InfiniteSampler(
|
| 77 |
+
len(self.dataset), seed=self.seed if self.seed else 0
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
batch_sampler = YoloBatchSampler(
|
| 81 |
+
sampler=sampler,
|
| 82 |
+
batch_size=batch_size,
|
| 83 |
+
drop_last=False,
|
| 84 |
+
input_dimension=self.input_size,
|
| 85 |
+
mosaic=not no_aug,
|
| 86 |
+
)
|
| 87 |
+
|
| 88 |
+
dataloader_kwargs = {"num_workers": self.data_num_workers, "pin_memory": True}
|
| 89 |
+
dataloader_kwargs["batch_sampler"] = batch_sampler
|
| 90 |
+
train_loader = DataLoader(self.dataset, **dataloader_kwargs)
|
| 91 |
+
|
| 92 |
+
return train_loader
|
| 93 |
+
|
| 94 |
+
def get_eval_loader(self, batch_size, is_distributed, testdev=False):
|
| 95 |
+
from yolox.data import MOTDataset, ValTransform
|
| 96 |
+
|
| 97 |
+
valdataset = MOTDataset(
|
| 98 |
+
data_dir=os.path.join(get_yolox_datadir(), "mot"),
|
| 99 |
+
json_file=self.val_ann,
|
| 100 |
+
img_size=self.test_size,
|
| 101 |
+
name='train',
|
| 102 |
+
preproc=ValTransform(
|
| 103 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 104 |
+
std=(0.229, 0.224, 0.225),
|
| 105 |
+
),
|
| 106 |
+
)
|
| 107 |
+
|
| 108 |
+
if is_distributed:
|
| 109 |
+
batch_size = batch_size // dist.get_world_size()
|
| 110 |
+
sampler = torch.utils.data.distributed.DistributedSampler(
|
| 111 |
+
valdataset, shuffle=False
|
| 112 |
+
)
|
| 113 |
+
else:
|
| 114 |
+
sampler = torch.utils.data.SequentialSampler(valdataset)
|
| 115 |
+
|
| 116 |
+
dataloader_kwargs = {
|
| 117 |
+
"num_workers": self.data_num_workers,
|
| 118 |
+
"pin_memory": True,
|
| 119 |
+
"sampler": sampler,
|
| 120 |
+
}
|
| 121 |
+
dataloader_kwargs["batch_size"] = batch_size
|
| 122 |
+
val_loader = torch.utils.data.DataLoader(valdataset, **dataloader_kwargs)
|
| 123 |
+
|
| 124 |
+
return val_loader
|
| 125 |
+
|
| 126 |
+
def get_evaluator(self, batch_size, is_distributed, testdev=False):
|
| 127 |
+
from yolox.evaluators import COCOEvaluator
|
| 128 |
+
|
| 129 |
+
val_loader = self.get_eval_loader(batch_size, is_distributed, testdev=testdev)
|
| 130 |
+
evaluator = COCOEvaluator(
|
| 131 |
+
dataloader=val_loader,
|
| 132 |
+
img_size=self.test_size,
|
| 133 |
+
confthre=self.test_conf,
|
| 134 |
+
nmsthre=self.nmsthre,
|
| 135 |
+
num_classes=self.num_classes,
|
| 136 |
+
testdev=testdev,
|
| 137 |
+
)
|
| 138 |
+
return evaluator
|
exps/example/mot/yolox_s_mix_det.py
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# encoding: utf-8
|
| 2 |
+
import os
|
| 3 |
+
import random
|
| 4 |
+
import torch
|
| 5 |
+
import torch.nn as nn
|
| 6 |
+
import torch.distributed as dist
|
| 7 |
+
|
| 8 |
+
from yolox.exp import Exp as MyExp
|
| 9 |
+
from yolox.data import get_yolox_datadir
|
| 10 |
+
|
| 11 |
+
class Exp(MyExp):
|
| 12 |
+
def __init__(self):
|
| 13 |
+
super(Exp, self).__init__()
|
| 14 |
+
self.num_classes = 1
|
| 15 |
+
self.depth = 0.33
|
| 16 |
+
self.width = 0.50
|
| 17 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
| 18 |
+
self.train_ann = "train.json"
|
| 19 |
+
self.val_ann = "train.json"
|
| 20 |
+
self.input_size = (608, 1088)
|
| 21 |
+
self.test_size = (608, 1088)
|
| 22 |
+
self.random_size = (12, 26)
|
| 23 |
+
self.max_epoch = 80
|
| 24 |
+
self.print_interval = 20
|
| 25 |
+
self.eval_interval = 5
|
| 26 |
+
self.test_conf = 0.001
|
| 27 |
+
self.nmsthre = 0.7
|
| 28 |
+
self.no_aug_epochs = 10
|
| 29 |
+
self.basic_lr_per_img = 0.001 / 64.0
|
| 30 |
+
self.warmup_epochs = 1
|
| 31 |
+
|
| 32 |
+
def get_data_loader(self, batch_size, is_distributed, no_aug=False):
|
| 33 |
+
from yolox.data import (
|
| 34 |
+
MOTDataset,
|
| 35 |
+
TrainTransform,
|
| 36 |
+
YoloBatchSampler,
|
| 37 |
+
DataLoader,
|
| 38 |
+
InfiniteSampler,
|
| 39 |
+
MosaicDetection,
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
dataset = MOTDataset(
|
| 43 |
+
data_dir=os.path.join(get_yolox_datadir(), "mix_det"),
|
| 44 |
+
json_file=self.train_ann,
|
| 45 |
+
name='',
|
| 46 |
+
img_size=self.input_size,
|
| 47 |
+
preproc=TrainTransform(
|
| 48 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 49 |
+
std=(0.229, 0.224, 0.225),
|
| 50 |
+
max_labels=500,
|
| 51 |
+
),
|
| 52 |
+
)
|
| 53 |
+
|
| 54 |
+
dataset = MosaicDetection(
|
| 55 |
+
dataset,
|
| 56 |
+
mosaic=not no_aug,
|
| 57 |
+
img_size=self.input_size,
|
| 58 |
+
preproc=TrainTransform(
|
| 59 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 60 |
+
std=(0.229, 0.224, 0.225),
|
| 61 |
+
max_labels=1000,
|
| 62 |
+
),
|
| 63 |
+
degrees=self.degrees,
|
| 64 |
+
translate=self.translate,
|
| 65 |
+
scale=self.scale,
|
| 66 |
+
shear=self.shear,
|
| 67 |
+
perspective=self.perspective,
|
| 68 |
+
enable_mixup=self.enable_mixup,
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
self.dataset = dataset
|
| 72 |
+
|
| 73 |
+
if is_distributed:
|
| 74 |
+
batch_size = batch_size // dist.get_world_size()
|
| 75 |
+
|
| 76 |
+
sampler = InfiniteSampler(
|
| 77 |
+
len(self.dataset), seed=self.seed if self.seed else 0
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
batch_sampler = YoloBatchSampler(
|
| 81 |
+
sampler=sampler,
|
| 82 |
+
batch_size=batch_size,
|
| 83 |
+
drop_last=False,
|
| 84 |
+
input_dimension=self.input_size,
|
| 85 |
+
mosaic=not no_aug,
|
| 86 |
+
)
|
| 87 |
+
|
| 88 |
+
dataloader_kwargs = {"num_workers": self.data_num_workers, "pin_memory": True}
|
| 89 |
+
dataloader_kwargs["batch_sampler"] = batch_sampler
|
| 90 |
+
train_loader = DataLoader(self.dataset, **dataloader_kwargs)
|
| 91 |
+
|
| 92 |
+
return train_loader
|
| 93 |
+
|
| 94 |
+
def get_eval_loader(self, batch_size, is_distributed, testdev=False):
|
| 95 |
+
from yolox.data import MOTDataset, ValTransform
|
| 96 |
+
|
| 97 |
+
valdataset = MOTDataset(
|
| 98 |
+
data_dir=os.path.join(get_yolox_datadir(), "mot"),
|
| 99 |
+
json_file=self.val_ann,
|
| 100 |
+
img_size=self.test_size,
|
| 101 |
+
name='train',
|
| 102 |
+
preproc=ValTransform(
|
| 103 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 104 |
+
std=(0.229, 0.224, 0.225),
|
| 105 |
+
),
|
| 106 |
+
)
|
| 107 |
+
|
| 108 |
+
if is_distributed:
|
| 109 |
+
batch_size = batch_size // dist.get_world_size()
|
| 110 |
+
sampler = torch.utils.data.distributed.DistributedSampler(
|
| 111 |
+
valdataset, shuffle=False
|
| 112 |
+
)
|
| 113 |
+
else:
|
| 114 |
+
sampler = torch.utils.data.SequentialSampler(valdataset)
|
| 115 |
+
|
| 116 |
+
dataloader_kwargs = {
|
| 117 |
+
"num_workers": self.data_num_workers,
|
| 118 |
+
"pin_memory": True,
|
| 119 |
+
"sampler": sampler,
|
| 120 |
+
}
|
| 121 |
+
dataloader_kwargs["batch_size"] = batch_size
|
| 122 |
+
val_loader = torch.utils.data.DataLoader(valdataset, **dataloader_kwargs)
|
| 123 |
+
|
| 124 |
+
return val_loader
|
| 125 |
+
|
| 126 |
+
def get_evaluator(self, batch_size, is_distributed, testdev=False):
|
| 127 |
+
from yolox.evaluators import COCOEvaluator
|
| 128 |
+
|
| 129 |
+
val_loader = self.get_eval_loader(batch_size, is_distributed, testdev=testdev)
|
| 130 |
+
evaluator = COCOEvaluator(
|
| 131 |
+
dataloader=val_loader,
|
| 132 |
+
img_size=self.test_size,
|
| 133 |
+
confthre=self.test_conf,
|
| 134 |
+
nmsthre=self.nmsthre,
|
| 135 |
+
num_classes=self.num_classes,
|
| 136 |
+
testdev=testdev,
|
| 137 |
+
)
|
| 138 |
+
return evaluator
|
exps/example/mot/yolox_x_ablation.py
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# encoding: utf-8
|
| 2 |
+
import os
|
| 3 |
+
import random
|
| 4 |
+
import torch
|
| 5 |
+
import torch.nn as nn
|
| 6 |
+
import torch.distributed as dist
|
| 7 |
+
|
| 8 |
+
from yolox.exp import Exp as MyExp
|
| 9 |
+
from yolox.data import get_yolox_datadir
|
| 10 |
+
|
| 11 |
+
class Exp(MyExp):
|
| 12 |
+
def __init__(self):
|
| 13 |
+
super(Exp, self).__init__()
|
| 14 |
+
self.num_classes = 1
|
| 15 |
+
self.depth = 1.33
|
| 16 |
+
self.width = 1.25
|
| 17 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
| 18 |
+
self.train_ann = "train.json"
|
| 19 |
+
self.val_ann = "val_half.json"
|
| 20 |
+
self.input_size = (800, 1440)
|
| 21 |
+
self.test_size = (800, 1440)
|
| 22 |
+
self.random_size = (18, 32)
|
| 23 |
+
self.max_epoch = 80
|
| 24 |
+
self.print_interval = 20
|
| 25 |
+
self.eval_interval = 5
|
| 26 |
+
self.test_conf = 0.1
|
| 27 |
+
self.nmsthre = 0.7
|
| 28 |
+
self.no_aug_epochs = 10
|
| 29 |
+
self.basic_lr_per_img = 0.001 / 64.0
|
| 30 |
+
self.warmup_epochs = 1
|
| 31 |
+
|
| 32 |
+
def get_data_loader(self, batch_size, is_distributed, no_aug=False):
|
| 33 |
+
from yolox.data import (
|
| 34 |
+
MOTDataset,
|
| 35 |
+
TrainTransform,
|
| 36 |
+
YoloBatchSampler,
|
| 37 |
+
DataLoader,
|
| 38 |
+
InfiniteSampler,
|
| 39 |
+
MosaicDetection,
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
dataset = MOTDataset(
|
| 43 |
+
data_dir=os.path.join(get_yolox_datadir(), "mix_mot_ch"),
|
| 44 |
+
json_file=self.train_ann,
|
| 45 |
+
name='',
|
| 46 |
+
img_size=self.input_size,
|
| 47 |
+
preproc=TrainTransform(
|
| 48 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 49 |
+
std=(0.229, 0.224, 0.225),
|
| 50 |
+
max_labels=500,
|
| 51 |
+
),
|
| 52 |
+
)
|
| 53 |
+
|
| 54 |
+
dataset = MosaicDetection(
|
| 55 |
+
dataset,
|
| 56 |
+
mosaic=not no_aug,
|
| 57 |
+
img_size=self.input_size,
|
| 58 |
+
preproc=TrainTransform(
|
| 59 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 60 |
+
std=(0.229, 0.224, 0.225),
|
| 61 |
+
max_labels=1000,
|
| 62 |
+
),
|
| 63 |
+
degrees=self.degrees,
|
| 64 |
+
translate=self.translate,
|
| 65 |
+
scale=self.scale,
|
| 66 |
+
shear=self.shear,
|
| 67 |
+
perspective=self.perspective,
|
| 68 |
+
enable_mixup=self.enable_mixup,
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
self.dataset = dataset
|
| 72 |
+
|
| 73 |
+
if is_distributed:
|
| 74 |
+
batch_size = batch_size // dist.get_world_size()
|
| 75 |
+
|
| 76 |
+
sampler = InfiniteSampler(
|
| 77 |
+
len(self.dataset), seed=self.seed if self.seed else 0
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
batch_sampler = YoloBatchSampler(
|
| 81 |
+
sampler=sampler,
|
| 82 |
+
batch_size=batch_size,
|
| 83 |
+
drop_last=False,
|
| 84 |
+
input_dimension=self.input_size,
|
| 85 |
+
mosaic=not no_aug,
|
| 86 |
+
)
|
| 87 |
+
|
| 88 |
+
dataloader_kwargs = {"num_workers": self.data_num_workers, "pin_memory": True}
|
| 89 |
+
dataloader_kwargs["batch_sampler"] = batch_sampler
|
| 90 |
+
train_loader = DataLoader(self.dataset, **dataloader_kwargs)
|
| 91 |
+
|
| 92 |
+
return train_loader
|
| 93 |
+
|
| 94 |
+
def get_eval_loader(self, batch_size, is_distributed, testdev=False):
|
| 95 |
+
from yolox.data import MOTDataset, ValTransform
|
| 96 |
+
|
| 97 |
+
valdataset = MOTDataset(
|
| 98 |
+
data_dir=os.path.join(get_yolox_datadir(), "mot"),
|
| 99 |
+
json_file=self.val_ann,
|
| 100 |
+
img_size=self.test_size,
|
| 101 |
+
name='train',
|
| 102 |
+
preproc=ValTransform(
|
| 103 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 104 |
+
std=(0.229, 0.224, 0.225),
|
| 105 |
+
),
|
| 106 |
+
)
|
| 107 |
+
|
| 108 |
+
if is_distributed:
|
| 109 |
+
batch_size = batch_size // dist.get_world_size()
|
| 110 |
+
sampler = torch.utils.data.distributed.DistributedSampler(
|
| 111 |
+
valdataset, shuffle=False
|
| 112 |
+
)
|
| 113 |
+
else:
|
| 114 |
+
sampler = torch.utils.data.SequentialSampler(valdataset)
|
| 115 |
+
|
| 116 |
+
dataloader_kwargs = {
|
| 117 |
+
"num_workers": self.data_num_workers,
|
| 118 |
+
"pin_memory": True,
|
| 119 |
+
"sampler": sampler,
|
| 120 |
+
}
|
| 121 |
+
dataloader_kwargs["batch_size"] = batch_size
|
| 122 |
+
val_loader = torch.utils.data.DataLoader(valdataset, **dataloader_kwargs)
|
| 123 |
+
|
| 124 |
+
return val_loader
|
| 125 |
+
|
| 126 |
+
def get_evaluator(self, batch_size, is_distributed, testdev=False):
|
| 127 |
+
from yolox.evaluators import COCOEvaluator
|
| 128 |
+
|
| 129 |
+
val_loader = self.get_eval_loader(batch_size, is_distributed, testdev=testdev)
|
| 130 |
+
evaluator = COCOEvaluator(
|
| 131 |
+
dataloader=val_loader,
|
| 132 |
+
img_size=self.test_size,
|
| 133 |
+
confthre=self.test_conf,
|
| 134 |
+
nmsthre=self.nmsthre,
|
| 135 |
+
num_classes=self.num_classes,
|
| 136 |
+
testdev=testdev,
|
| 137 |
+
)
|
| 138 |
+
return evaluator
|
exps/example/mot/yolox_x_ch.py
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# encoding: utf-8
|
| 2 |
+
import os
|
| 3 |
+
import random
|
| 4 |
+
import torch
|
| 5 |
+
import torch.nn as nn
|
| 6 |
+
import torch.distributed as dist
|
| 7 |
+
|
| 8 |
+
from yolox.exp import Exp as MyExp
|
| 9 |
+
from yolox.data import get_yolox_datadir
|
| 10 |
+
|
| 11 |
+
class Exp(MyExp):
|
| 12 |
+
def __init__(self):
|
| 13 |
+
super(Exp, self).__init__()
|
| 14 |
+
self.num_classes = 1
|
| 15 |
+
self.depth = 1.33
|
| 16 |
+
self.width = 1.25
|
| 17 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
| 18 |
+
self.train_ann = "train.json"
|
| 19 |
+
self.val_ann = "val_half.json"
|
| 20 |
+
self.input_size = (800, 1440)
|
| 21 |
+
self.test_size = (800, 1440)
|
| 22 |
+
self.random_size = (18, 32)
|
| 23 |
+
self.max_epoch = 80
|
| 24 |
+
self.print_interval = 20
|
| 25 |
+
self.eval_interval = 5
|
| 26 |
+
self.test_conf = 0.1
|
| 27 |
+
self.nmsthre = 0.7
|
| 28 |
+
self.no_aug_epochs = 10
|
| 29 |
+
self.basic_lr_per_img = 0.001 / 64.0
|
| 30 |
+
self.warmup_epochs = 1
|
| 31 |
+
|
| 32 |
+
def get_data_loader(self, batch_size, is_distributed, no_aug=False):
|
| 33 |
+
from yolox.data import (
|
| 34 |
+
MOTDataset,
|
| 35 |
+
TrainTransform,
|
| 36 |
+
YoloBatchSampler,
|
| 37 |
+
DataLoader,
|
| 38 |
+
InfiniteSampler,
|
| 39 |
+
MosaicDetection,
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
dataset = MOTDataset(
|
| 43 |
+
data_dir=os.path.join(get_yolox_datadir(), "ch_all"),
|
| 44 |
+
json_file=self.train_ann,
|
| 45 |
+
name='',
|
| 46 |
+
img_size=self.input_size,
|
| 47 |
+
preproc=TrainTransform(
|
| 48 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 49 |
+
std=(0.229, 0.224, 0.225),
|
| 50 |
+
max_labels=500,
|
| 51 |
+
),
|
| 52 |
+
)
|
| 53 |
+
|
| 54 |
+
dataset = MosaicDetection(
|
| 55 |
+
dataset,
|
| 56 |
+
mosaic=not no_aug,
|
| 57 |
+
img_size=self.input_size,
|
| 58 |
+
preproc=TrainTransform(
|
| 59 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 60 |
+
std=(0.229, 0.224, 0.225),
|
| 61 |
+
max_labels=1000,
|
| 62 |
+
),
|
| 63 |
+
degrees=self.degrees,
|
| 64 |
+
translate=self.translate,
|
| 65 |
+
scale=self.scale,
|
| 66 |
+
shear=self.shear,
|
| 67 |
+
perspective=self.perspective,
|
| 68 |
+
enable_mixup=self.enable_mixup,
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
self.dataset = dataset
|
| 72 |
+
|
| 73 |
+
if is_distributed:
|
| 74 |
+
batch_size = batch_size // dist.get_world_size()
|
| 75 |
+
|
| 76 |
+
sampler = InfiniteSampler(
|
| 77 |
+
len(self.dataset), seed=self.seed if self.seed else 0
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
batch_sampler = YoloBatchSampler(
|
| 81 |
+
sampler=sampler,
|
| 82 |
+
batch_size=batch_size,
|
| 83 |
+
drop_last=False,
|
| 84 |
+
input_dimension=self.input_size,
|
| 85 |
+
mosaic=not no_aug,
|
| 86 |
+
)
|
| 87 |
+
|
| 88 |
+
dataloader_kwargs = {"num_workers": self.data_num_workers, "pin_memory": True}
|
| 89 |
+
dataloader_kwargs["batch_sampler"] = batch_sampler
|
| 90 |
+
train_loader = DataLoader(self.dataset, **dataloader_kwargs)
|
| 91 |
+
|
| 92 |
+
return train_loader
|
| 93 |
+
|
| 94 |
+
def get_eval_loader(self, batch_size, is_distributed, testdev=False):
|
| 95 |
+
from yolox.data import MOTDataset, ValTransform
|
| 96 |
+
|
| 97 |
+
valdataset = MOTDataset(
|
| 98 |
+
data_dir=os.path.join(get_yolox_datadir(), "mot"),
|
| 99 |
+
json_file=self.val_ann,
|
| 100 |
+
img_size=self.test_size,
|
| 101 |
+
name='train',
|
| 102 |
+
preproc=ValTransform(
|
| 103 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 104 |
+
std=(0.229, 0.224, 0.225),
|
| 105 |
+
),
|
| 106 |
+
)
|
| 107 |
+
|
| 108 |
+
if is_distributed:
|
| 109 |
+
batch_size = batch_size // dist.get_world_size()
|
| 110 |
+
sampler = torch.utils.data.distributed.DistributedSampler(
|
| 111 |
+
valdataset, shuffle=False
|
| 112 |
+
)
|
| 113 |
+
else:
|
| 114 |
+
sampler = torch.utils.data.SequentialSampler(valdataset)
|
| 115 |
+
|
| 116 |
+
dataloader_kwargs = {
|
| 117 |
+
"num_workers": self.data_num_workers,
|
| 118 |
+
"pin_memory": True,
|
| 119 |
+
"sampler": sampler,
|
| 120 |
+
}
|
| 121 |
+
dataloader_kwargs["batch_size"] = batch_size
|
| 122 |
+
val_loader = torch.utils.data.DataLoader(valdataset, **dataloader_kwargs)
|
| 123 |
+
|
| 124 |
+
return val_loader
|
| 125 |
+
|
| 126 |
+
def get_evaluator(self, batch_size, is_distributed, testdev=False):
|
| 127 |
+
from yolox.evaluators import COCOEvaluator
|
| 128 |
+
|
| 129 |
+
val_loader = self.get_eval_loader(batch_size, is_distributed, testdev=testdev)
|
| 130 |
+
evaluator = COCOEvaluator(
|
| 131 |
+
dataloader=val_loader,
|
| 132 |
+
img_size=self.test_size,
|
| 133 |
+
confthre=self.test_conf,
|
| 134 |
+
nmsthre=self.nmsthre,
|
| 135 |
+
num_classes=self.num_classes,
|
| 136 |
+
testdev=testdev,
|
| 137 |
+
)
|
| 138 |
+
return evaluator
|
exps/example/mot/yolox_x_mix_det.py
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# encoding: utf-8
|
| 2 |
+
import os
|
| 3 |
+
import random
|
| 4 |
+
import torch
|
| 5 |
+
import torch.nn as nn
|
| 6 |
+
import torch.distributed as dist
|
| 7 |
+
|
| 8 |
+
from yolox.exp import Exp as MyExp
|
| 9 |
+
from yolox.data import get_yolox_datadir
|
| 10 |
+
|
| 11 |
+
class Exp(MyExp):
|
| 12 |
+
def __init__(self):
|
| 13 |
+
super(Exp, self).__init__()
|
| 14 |
+
self.num_classes = 1
|
| 15 |
+
self.depth = 1.33
|
| 16 |
+
self.width = 1.25
|
| 17 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
| 18 |
+
self.train_ann = "train.json"
|
| 19 |
+
self.val_ann = "test.json" # change to train.json when running on training set
|
| 20 |
+
self.input_size = (800, 1440)
|
| 21 |
+
self.test_size = (800, 1440)
|
| 22 |
+
self.random_size = (18, 32)
|
| 23 |
+
self.max_epoch = 80
|
| 24 |
+
self.print_interval = 20
|
| 25 |
+
self.eval_interval = 5
|
| 26 |
+
self.test_conf = 0.001
|
| 27 |
+
self.nmsthre = 0.7
|
| 28 |
+
self.no_aug_epochs = 10
|
| 29 |
+
self.basic_lr_per_img = 0.001 / 64.0
|
| 30 |
+
self.warmup_epochs = 1
|
| 31 |
+
|
| 32 |
+
def get_data_loader(self, batch_size, is_distributed, no_aug=False):
|
| 33 |
+
from yolox.data import (
|
| 34 |
+
MOTDataset,
|
| 35 |
+
TrainTransform,
|
| 36 |
+
YoloBatchSampler,
|
| 37 |
+
DataLoader,
|
| 38 |
+
InfiniteSampler,
|
| 39 |
+
MosaicDetection,
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
dataset = MOTDataset(
|
| 43 |
+
data_dir=os.path.join(get_yolox_datadir(), "mix_det"),
|
| 44 |
+
json_file=self.train_ann,
|
| 45 |
+
name='',
|
| 46 |
+
img_size=self.input_size,
|
| 47 |
+
preproc=TrainTransform(
|
| 48 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 49 |
+
std=(0.229, 0.224, 0.225),
|
| 50 |
+
max_labels=500,
|
| 51 |
+
),
|
| 52 |
+
)
|
| 53 |
+
|
| 54 |
+
dataset = MosaicDetection(
|
| 55 |
+
dataset,
|
| 56 |
+
mosaic=not no_aug,
|
| 57 |
+
img_size=self.input_size,
|
| 58 |
+
preproc=TrainTransform(
|
| 59 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 60 |
+
std=(0.229, 0.224, 0.225),
|
| 61 |
+
max_labels=1000,
|
| 62 |
+
),
|
| 63 |
+
degrees=self.degrees,
|
| 64 |
+
translate=self.translate,
|
| 65 |
+
scale=self.scale,
|
| 66 |
+
shear=self.shear,
|
| 67 |
+
perspective=self.perspective,
|
| 68 |
+
enable_mixup=self.enable_mixup,
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
self.dataset = dataset
|
| 72 |
+
|
| 73 |
+
if is_distributed:
|
| 74 |
+
batch_size = batch_size // dist.get_world_size()
|
| 75 |
+
|
| 76 |
+
sampler = InfiniteSampler(
|
| 77 |
+
len(self.dataset), seed=self.seed if self.seed else 0
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
batch_sampler = YoloBatchSampler(
|
| 81 |
+
sampler=sampler,
|
| 82 |
+
batch_size=batch_size,
|
| 83 |
+
drop_last=False,
|
| 84 |
+
input_dimension=self.input_size,
|
| 85 |
+
mosaic=not no_aug,
|
| 86 |
+
)
|
| 87 |
+
|
| 88 |
+
dataloader_kwargs = {"num_workers": self.data_num_workers, "pin_memory": True}
|
| 89 |
+
dataloader_kwargs["batch_sampler"] = batch_sampler
|
| 90 |
+
train_loader = DataLoader(self.dataset, **dataloader_kwargs)
|
| 91 |
+
|
| 92 |
+
return train_loader
|
| 93 |
+
|
| 94 |
+
def get_eval_loader(self, batch_size, is_distributed, testdev=False):
|
| 95 |
+
from yolox.data import MOTDataset, ValTransform
|
| 96 |
+
|
| 97 |
+
valdataset = MOTDataset(
|
| 98 |
+
data_dir=os.path.join(get_yolox_datadir(), "mot"),
|
| 99 |
+
json_file=self.val_ann,
|
| 100 |
+
img_size=self.test_size,
|
| 101 |
+
name='test', # change to train when running on training set
|
| 102 |
+
preproc=ValTransform(
|
| 103 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 104 |
+
std=(0.229, 0.224, 0.225),
|
| 105 |
+
),
|
| 106 |
+
)
|
| 107 |
+
|
| 108 |
+
if is_distributed:
|
| 109 |
+
batch_size = batch_size // dist.get_world_size()
|
| 110 |
+
sampler = torch.utils.data.distributed.DistributedSampler(
|
| 111 |
+
valdataset, shuffle=False
|
| 112 |
+
)
|
| 113 |
+
else:
|
| 114 |
+
sampler = torch.utils.data.SequentialSampler(valdataset)
|
| 115 |
+
|
| 116 |
+
dataloader_kwargs = {
|
| 117 |
+
"num_workers": self.data_num_workers,
|
| 118 |
+
"pin_memory": True,
|
| 119 |
+
"sampler": sampler,
|
| 120 |
+
}
|
| 121 |
+
dataloader_kwargs["batch_size"] = batch_size
|
| 122 |
+
val_loader = torch.utils.data.DataLoader(valdataset, **dataloader_kwargs)
|
| 123 |
+
|
| 124 |
+
return val_loader
|
| 125 |
+
|
| 126 |
+
def get_evaluator(self, batch_size, is_distributed, testdev=False):
|
| 127 |
+
from yolox.evaluators import COCOEvaluator
|
| 128 |
+
|
| 129 |
+
val_loader = self.get_eval_loader(batch_size, is_distributed, testdev=testdev)
|
| 130 |
+
evaluator = COCOEvaluator(
|
| 131 |
+
dataloader=val_loader,
|
| 132 |
+
img_size=self.test_size,
|
| 133 |
+
confthre=self.test_conf,
|
| 134 |
+
nmsthre=self.nmsthre,
|
| 135 |
+
num_classes=self.num_classes,
|
| 136 |
+
testdev=testdev,
|
| 137 |
+
)
|
| 138 |
+
return evaluator
|
exps/example/mot/yolox_x_mix_mot20_ch.py
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# encoding: utf-8
|
| 2 |
+
import os
|
| 3 |
+
import random
|
| 4 |
+
import torch
|
| 5 |
+
import torch.nn as nn
|
| 6 |
+
import torch.distributed as dist
|
| 7 |
+
|
| 8 |
+
from yolox.exp import Exp as MyExp
|
| 9 |
+
from yolox.data import get_yolox_datadir
|
| 10 |
+
|
| 11 |
+
class Exp(MyExp):
|
| 12 |
+
def __init__(self):
|
| 13 |
+
super(Exp, self).__init__()
|
| 14 |
+
self.num_classes = 1
|
| 15 |
+
self.depth = 1.33
|
| 16 |
+
self.width = 1.25
|
| 17 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
| 18 |
+
self.train_ann = "train.json"
|
| 19 |
+
self.val_ann = "test.json" # change to train.json when running on training set
|
| 20 |
+
self.input_size = (896, 1600)
|
| 21 |
+
self.test_size = (896, 1600)
|
| 22 |
+
#self.test_size = (736, 1920)
|
| 23 |
+
self.random_size = (20, 36)
|
| 24 |
+
self.max_epoch = 80
|
| 25 |
+
self.print_interval = 20
|
| 26 |
+
self.eval_interval = 5
|
| 27 |
+
self.test_conf = 0.001
|
| 28 |
+
self.nmsthre = 0.7
|
| 29 |
+
self.no_aug_epochs = 10
|
| 30 |
+
self.basic_lr_per_img = 0.001 / 64.0
|
| 31 |
+
self.warmup_epochs = 1
|
| 32 |
+
|
| 33 |
+
def get_data_loader(self, batch_size, is_distributed, no_aug=False):
|
| 34 |
+
from yolox.data import (
|
| 35 |
+
MOTDataset,
|
| 36 |
+
TrainTransform,
|
| 37 |
+
YoloBatchSampler,
|
| 38 |
+
DataLoader,
|
| 39 |
+
InfiniteSampler,
|
| 40 |
+
MosaicDetection,
|
| 41 |
+
)
|
| 42 |
+
|
| 43 |
+
dataset = MOTDataset(
|
| 44 |
+
data_dir=os.path.join(get_yolox_datadir(), "mix_mot20_ch"),
|
| 45 |
+
json_file=self.train_ann,
|
| 46 |
+
name='',
|
| 47 |
+
img_size=self.input_size,
|
| 48 |
+
preproc=TrainTransform(
|
| 49 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 50 |
+
std=(0.229, 0.224, 0.225),
|
| 51 |
+
max_labels=600,
|
| 52 |
+
),
|
| 53 |
+
)
|
| 54 |
+
|
| 55 |
+
dataset = MosaicDetection(
|
| 56 |
+
dataset,
|
| 57 |
+
mosaic=not no_aug,
|
| 58 |
+
img_size=self.input_size,
|
| 59 |
+
preproc=TrainTransform(
|
| 60 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 61 |
+
std=(0.229, 0.224, 0.225),
|
| 62 |
+
max_labels=1200,
|
| 63 |
+
),
|
| 64 |
+
degrees=self.degrees,
|
| 65 |
+
translate=self.translate,
|
| 66 |
+
scale=self.scale,
|
| 67 |
+
shear=self.shear,
|
| 68 |
+
perspective=self.perspective,
|
| 69 |
+
enable_mixup=self.enable_mixup,
|
| 70 |
+
)
|
| 71 |
+
|
| 72 |
+
self.dataset = dataset
|
| 73 |
+
|
| 74 |
+
if is_distributed:
|
| 75 |
+
batch_size = batch_size // dist.get_world_size()
|
| 76 |
+
|
| 77 |
+
sampler = InfiniteSampler(
|
| 78 |
+
len(self.dataset), seed=self.seed if self.seed else 0
|
| 79 |
+
)
|
| 80 |
+
|
| 81 |
+
batch_sampler = YoloBatchSampler(
|
| 82 |
+
sampler=sampler,
|
| 83 |
+
batch_size=batch_size,
|
| 84 |
+
drop_last=False,
|
| 85 |
+
input_dimension=self.input_size,
|
| 86 |
+
mosaic=not no_aug,
|
| 87 |
+
)
|
| 88 |
+
|
| 89 |
+
dataloader_kwargs = {"num_workers": self.data_num_workers, "pin_memory": True}
|
| 90 |
+
dataloader_kwargs["batch_sampler"] = batch_sampler
|
| 91 |
+
train_loader = DataLoader(self.dataset, **dataloader_kwargs)
|
| 92 |
+
|
| 93 |
+
return train_loader
|
| 94 |
+
|
| 95 |
+
def get_eval_loader(self, batch_size, is_distributed, testdev=False):
|
| 96 |
+
from yolox.data import MOTDataset, ValTransform
|
| 97 |
+
|
| 98 |
+
valdataset = MOTDataset(
|
| 99 |
+
data_dir=os.path.join(get_yolox_datadir(), "MOT20"),
|
| 100 |
+
json_file=self.val_ann,
|
| 101 |
+
img_size=self.test_size,
|
| 102 |
+
name='test', # change to train when running on training set
|
| 103 |
+
preproc=ValTransform(
|
| 104 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 105 |
+
std=(0.229, 0.224, 0.225),
|
| 106 |
+
),
|
| 107 |
+
)
|
| 108 |
+
|
| 109 |
+
if is_distributed:
|
| 110 |
+
batch_size = batch_size // dist.get_world_size()
|
| 111 |
+
sampler = torch.utils.data.distributed.DistributedSampler(
|
| 112 |
+
valdataset, shuffle=False
|
| 113 |
+
)
|
| 114 |
+
else:
|
| 115 |
+
sampler = torch.utils.data.SequentialSampler(valdataset)
|
| 116 |
+
|
| 117 |
+
dataloader_kwargs = {
|
| 118 |
+
"num_workers": self.data_num_workers,
|
| 119 |
+
"pin_memory": True,
|
| 120 |
+
"sampler": sampler,
|
| 121 |
+
}
|
| 122 |
+
dataloader_kwargs["batch_size"] = batch_size
|
| 123 |
+
val_loader = torch.utils.data.DataLoader(valdataset, **dataloader_kwargs)
|
| 124 |
+
|
| 125 |
+
return val_loader
|
| 126 |
+
|
| 127 |
+
def get_evaluator(self, batch_size, is_distributed, testdev=False):
|
| 128 |
+
from yolox.evaluators import COCOEvaluator
|
| 129 |
+
|
| 130 |
+
val_loader = self.get_eval_loader(batch_size, is_distributed, testdev=testdev)
|
| 131 |
+
evaluator = COCOEvaluator(
|
| 132 |
+
dataloader=val_loader,
|
| 133 |
+
img_size=self.test_size,
|
| 134 |
+
confthre=self.test_conf,
|
| 135 |
+
nmsthre=self.nmsthre,
|
| 136 |
+
num_classes=self.num_classes,
|
| 137 |
+
testdev=testdev,
|
| 138 |
+
)
|
| 139 |
+
return evaluator
|
exps/example/mot/yolox_x_mot17_half.py
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# encoding: utf-8
|
| 2 |
+
import os
|
| 3 |
+
import random
|
| 4 |
+
import torch
|
| 5 |
+
import torch.nn as nn
|
| 6 |
+
import torch.distributed as dist
|
| 7 |
+
|
| 8 |
+
from yolox.exp import Exp as MyExp
|
| 9 |
+
from yolox.data import get_yolox_datadir
|
| 10 |
+
|
| 11 |
+
class Exp(MyExp):
|
| 12 |
+
def __init__(self):
|
| 13 |
+
super(Exp, self).__init__()
|
| 14 |
+
self.num_classes = 1
|
| 15 |
+
self.depth = 1.33
|
| 16 |
+
self.width = 1.25
|
| 17 |
+
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
|
| 18 |
+
self.train_ann = "train.json"
|
| 19 |
+
self.val_ann = "val_half.json"
|
| 20 |
+
self.input_size = (800, 1440)
|
| 21 |
+
self.test_size = (800, 1440)
|
| 22 |
+
self.random_size = (18, 32)
|
| 23 |
+
self.max_epoch = 80
|
| 24 |
+
self.print_interval = 20
|
| 25 |
+
self.eval_interval = 5
|
| 26 |
+
self.test_conf = 0.1
|
| 27 |
+
self.nmsthre = 0.7
|
| 28 |
+
self.no_aug_epochs = 10
|
| 29 |
+
self.basic_lr_per_img = 0.001 / 64.0
|
| 30 |
+
self.warmup_epochs = 1
|
| 31 |
+
|
| 32 |
+
def get_data_loader(self, batch_size, is_distributed, no_aug=False):
|
| 33 |
+
from yolox.data import (
|
| 34 |
+
MOTDataset,
|
| 35 |
+
TrainTransform,
|
| 36 |
+
YoloBatchSampler,
|
| 37 |
+
DataLoader,
|
| 38 |
+
InfiniteSampler,
|
| 39 |
+
MosaicDetection,
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
dataset = MOTDataset(
|
| 43 |
+
data_dir=os.path.join(get_yolox_datadir(), "mot"),
|
| 44 |
+
json_file=self.train_ann,
|
| 45 |
+
name='train',
|
| 46 |
+
img_size=self.input_size,
|
| 47 |
+
preproc=TrainTransform(
|
| 48 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 49 |
+
std=(0.229, 0.224, 0.225),
|
| 50 |
+
max_labels=500,
|
| 51 |
+
),
|
| 52 |
+
)
|
| 53 |
+
|
| 54 |
+
dataset = MosaicDetection(
|
| 55 |
+
dataset,
|
| 56 |
+
mosaic=not no_aug,
|
| 57 |
+
img_size=self.input_size,
|
| 58 |
+
preproc=TrainTransform(
|
| 59 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 60 |
+
std=(0.229, 0.224, 0.225),
|
| 61 |
+
max_labels=1000,
|
| 62 |
+
),
|
| 63 |
+
degrees=self.degrees,
|
| 64 |
+
translate=self.translate,
|
| 65 |
+
scale=self.scale,
|
| 66 |
+
shear=self.shear,
|
| 67 |
+
perspective=self.perspective,
|
| 68 |
+
enable_mixup=self.enable_mixup,
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
self.dataset = dataset
|
| 72 |
+
|
| 73 |
+
if is_distributed:
|
| 74 |
+
batch_size = batch_size // dist.get_world_size()
|
| 75 |
+
|
| 76 |
+
sampler = InfiniteSampler(
|
| 77 |
+
len(self.dataset), seed=self.seed if self.seed else 0
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
batch_sampler = YoloBatchSampler(
|
| 81 |
+
sampler=sampler,
|
| 82 |
+
batch_size=batch_size,
|
| 83 |
+
drop_last=False,
|
| 84 |
+
input_dimension=self.input_size,
|
| 85 |
+
mosaic=not no_aug,
|
| 86 |
+
)
|
| 87 |
+
|
| 88 |
+
dataloader_kwargs = {"num_workers": self.data_num_workers, "pin_memory": True}
|
| 89 |
+
dataloader_kwargs["batch_sampler"] = batch_sampler
|
| 90 |
+
train_loader = DataLoader(self.dataset, **dataloader_kwargs)
|
| 91 |
+
|
| 92 |
+
return train_loader
|
| 93 |
+
|
| 94 |
+
def get_eval_loader(self, batch_size, is_distributed, testdev=False):
|
| 95 |
+
from yolox.data import MOTDataset, ValTransform
|
| 96 |
+
|
| 97 |
+
valdataset = MOTDataset(
|
| 98 |
+
data_dir=os.path.join(get_yolox_datadir(), "mot"),
|
| 99 |
+
json_file=self.val_ann,
|
| 100 |
+
img_size=self.test_size,
|
| 101 |
+
name='train',
|
| 102 |
+
preproc=ValTransform(
|
| 103 |
+
rgb_means=(0.485, 0.456, 0.406),
|
| 104 |
+
std=(0.229, 0.224, 0.225),
|
| 105 |
+
),
|
| 106 |
+
)
|
| 107 |
+
|
| 108 |
+
if is_distributed:
|
| 109 |
+
batch_size = batch_size // dist.get_world_size()
|
| 110 |
+
sampler = torch.utils.data.distributed.DistributedSampler(
|
| 111 |
+
valdataset, shuffle=False
|
| 112 |
+
)
|
| 113 |
+
else:
|
| 114 |
+
sampler = torch.utils.data.SequentialSampler(valdataset)
|
| 115 |
+
|
| 116 |
+
dataloader_kwargs = {
|
| 117 |
+
"num_workers": self.data_num_workers,
|
| 118 |
+
"pin_memory": True,
|
| 119 |
+
"sampler": sampler,
|
| 120 |
+
}
|
| 121 |
+
dataloader_kwargs["batch_size"] = batch_size
|
| 122 |
+
val_loader = torch.utils.data.DataLoader(valdataset, **dataloader_kwargs)
|
| 123 |
+
|
| 124 |
+
return val_loader
|
| 125 |
+
|
| 126 |
+
def get_evaluator(self, batch_size, is_distributed, testdev=False):
|
| 127 |
+
from yolox.evaluators import COCOEvaluator
|
| 128 |
+
|
| 129 |
+
val_loader = self.get_eval_loader(batch_size, is_distributed, testdev=testdev)
|
| 130 |
+
evaluator = COCOEvaluator(
|
| 131 |
+
dataloader=val_loader,
|
| 132 |
+
img_size=self.test_size,
|
| 133 |
+
confthre=self.test_conf,
|
| 134 |
+
nmsthre=self.nmsthre,
|
| 135 |
+
num_classes=self.num_classes,
|
| 136 |
+
testdev=testdev,
|
| 137 |
+
)
|
| 138 |
+
return evaluator
|
requirements.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TODO: Update with exact module version
|
| 2 |
+
numpy
|
| 3 |
+
torch>=1.7
|
| 4 |
+
opencv_python
|
| 5 |
+
loguru
|
| 6 |
+
scikit-image
|
| 7 |
+
tqdm
|
| 8 |
+
torchvision==0.10.0
|
| 9 |
+
Pillow
|
| 10 |
+
thop
|
| 11 |
+
ninja
|
| 12 |
+
tabulate
|
| 13 |
+
tensorboard
|
| 14 |
+
lap
|
| 15 |
+
motmetrics
|
| 16 |
+
filterpy
|
| 17 |
+
h5py
|
| 18 |
+
|
| 19 |
+
# verified versions
|
| 20 |
+
onnx==1.8.1
|
| 21 |
+
onnxruntime==1.8.0
|
| 22 |
+
onnx-simplifier==0.3.5
|
setup.cfg
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[isort]
|
| 2 |
+
line_length = 100
|
| 3 |
+
multi_line_output = 3
|
| 4 |
+
balanced_wrapping = True
|
| 5 |
+
known_standard_library = setuptools
|
| 6 |
+
known_third_party = tqdm,loguru
|
| 7 |
+
known_data_processing = cv2,numpy,scipy,PIL,matplotlib,scikit_image
|
| 8 |
+
known_datasets = pycocotools
|
| 9 |
+
known_deeplearning = torch,torchvision,caffe2,onnx,apex,timm,thop,torch2trt,tensorrt,openvino,onnxruntime
|
| 10 |
+
known_myself = yolox
|
| 11 |
+
sections = FUTURE,STDLIB,THIRDPARTY,data_processing,datasets,deeplearning,myself,FIRSTPARTY,LOCALFOLDER
|
| 12 |
+
no_lines_before=STDLIB,THIRDPARTY,datasets
|
| 13 |
+
default_section = FIRSTPARTY
|
| 14 |
+
|
| 15 |
+
[flake8]
|
| 16 |
+
max-line-length = 100
|
| 17 |
+
max-complexity = 18
|
| 18 |
+
exclude = __init__.py
|