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
|