Upload 5 files
Browse files- .gitattributes +1 -0
- environment.yml +35 -0
- requirements.txt +21 -0
- t1.mp4 +3 -0
- yolo_v7.py +612 -0
- yolov7-tiny-demo.py +121 -0
.gitattributes
CHANGED
|
@@ -32,3 +32,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 32 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 33 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 32 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 33 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
t1.mp4 filter=lfs diff=lfs merge=lfs -text
|
environment.yml
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: yolov7_bytetrack
|
| 2 |
+
channels:
|
| 3 |
+
- pytorch
|
| 4 |
+
- defaults
|
| 5 |
+
dependencies:
|
| 6 |
+
- cudatoolkit=11.3.1
|
| 7 |
+
- cython=0.29.30
|
| 8 |
+
- ffmpeg=4.2.2
|
| 9 |
+
- numpy=1.23.1
|
| 10 |
+
- numpy-base=1.23.1
|
| 11 |
+
- pytorch=1.12.1
|
| 12 |
+
- pytorch-mutex=1.0
|
| 13 |
+
- setuptools=63.4.1
|
| 14 |
+
- streamlit=1.11.0
|
| 15 |
+
- torchvision=0.13.1
|
| 16 |
+
- tqdm=4.64.0
|
| 17 |
+
- wheel=0.37.1
|
| 18 |
+
- yaml=0.2.5
|
| 19 |
+
- pip:
|
| 20 |
+
- click==8.1.3
|
| 21 |
+
- coloredlogs==15.0.1
|
| 22 |
+
- easydict==1.9
|
| 23 |
+
- gdown==4.5.1
|
| 24 |
+
- lap==0.4.0
|
| 25 |
+
- matplotlib==3.5.3
|
| 26 |
+
- onnxruntime-gpu==1.12.1
|
| 27 |
+
- opencv-python==4.6.0.66
|
| 28 |
+
- pycocotools==2.0.4
|
| 29 |
+
- pytz==2022.2.1
|
| 30 |
+
- pyyaml==6.0
|
| 31 |
+
- scipy==1.9.1
|
| 32 |
+
- tensorboard==2.10.0
|
| 33 |
+
- tensorboard-data-server==0.6.1
|
| 34 |
+
- tensorboard-plugin-wit==1.8.1
|
| 35 |
+
- urllib3==1.26.12
|
requirements.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
pycocotools
|
| 2 |
+
click
|
| 3 |
+
easydict
|
| 4 |
+
gdown
|
| 5 |
+
lap
|
| 6 |
+
matplotlib
|
| 7 |
+
onnxruntime-gpu
|
| 8 |
+
opencv-python
|
| 9 |
+
Pillow
|
| 10 |
+
PyYAML
|
| 11 |
+
scipy
|
| 12 |
+
streamlit
|
| 13 |
+
tensorboard
|
| 14 |
+
--extra-index-url https://download.pytorch.org/whl/cu113
|
| 15 |
+
torch
|
| 16 |
+
torchaudio
|
| 17 |
+
torchvision
|
| 18 |
+
tqdm
|
| 19 |
+
zipp
|
| 20 |
+
-e git+https://github.com/samson-wang/cython_bbox.git#egg=cython-bbox
|
| 21 |
+
numpy<1.24
|
t1.mp4
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2889085278e9562c68a10d44788b61ee7132372782486ec4f29c5d7c6e747200
|
| 3 |
+
size 1387289
|
yolo_v7.py
ADDED
|
@@ -0,0 +1,612 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import cv2
|
| 2 |
+
from numpy import random
|
| 3 |
+
from collections import deque
|
| 4 |
+
import numpy as np
|
| 5 |
+
import math
|
| 6 |
+
import torch
|
| 7 |
+
import torch.backends.cudnn as cudnn
|
| 8 |
+
|
| 9 |
+
from utils.google_utils import attempt_load
|
| 10 |
+
from utils.datasets import LoadStreams, LoadImages
|
| 11 |
+
from utils.general import (
|
| 12 |
+
check_img_size, non_max_suppression, apply_classifier, scale_coords, xyxy2xywh, strip_optimizer)
|
| 13 |
+
from utils.plots import plot_one_box
|
| 14 |
+
from utils.torch_utils import select_device, load_classifier, time_synchronized
|
| 15 |
+
|
| 16 |
+
from models.models import *
|
| 17 |
+
from utils.datasets import *
|
| 18 |
+
from utils.general import *
|
| 19 |
+
|
| 20 |
+
from deep_sort_pytorch.utils.parser import get_config
|
| 21 |
+
from deep_sort_pytorch.deep_sort import DeepSort
|
| 22 |
+
|
| 23 |
+
from byte_track.bytetracker import ByteTrack
|
| 24 |
+
from yolov7.yolov7_detector import YOLOv7Detector
|
| 25 |
+
|
| 26 |
+
def load_classes(path):
|
| 27 |
+
# Loads *.names file at 'path'
|
| 28 |
+
with open(path, 'r') as f:
|
| 29 |
+
names = f.read().split('\n')
|
| 30 |
+
return list(filter(None, names)) # filter removes empty strings (such as last line)
|
| 31 |
+
|
| 32 |
+
global names
|
| 33 |
+
names = load_classes('data/coco.names')
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
colors = [[random.randint(0, 255) for _ in range(3)] for _ in range(len(names))]
|
| 37 |
+
palette = (2 ** 11 - 1, 2 ** 15 - 1, 2 ** 20 - 1)
|
| 38 |
+
data_deque = {}
|
| 39 |
+
speed_four_line_queue = {}
|
| 40 |
+
object_counter = {}
|
| 41 |
+
|
| 42 |
+
# line1 = [(250,450), (1000, 450)]
|
| 43 |
+
|
| 44 |
+
line2 = [(200,500), (1050, 500)]
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def xyxy_to_xywh(*xyxy):
|
| 48 |
+
"""" Calculates the relative bounding box from absolute pixel values. """
|
| 49 |
+
bbox_left = min([xyxy[0].item(), xyxy[2].item()])
|
| 50 |
+
bbox_top = min([xyxy[1].item(), xyxy[3].item()])
|
| 51 |
+
bbox_w = abs(xyxy[0].item() - xyxy[2].item())
|
| 52 |
+
bbox_h = abs(xyxy[1].item() - xyxy[3].item())
|
| 53 |
+
x_c = (bbox_left + bbox_w / 2)
|
| 54 |
+
y_c = (bbox_top + bbox_h / 2)
|
| 55 |
+
w = bbox_w
|
| 56 |
+
h = bbox_h
|
| 57 |
+
return x_c, y_c, w, h
|
| 58 |
+
|
| 59 |
+
def xyxy_to_tlwh(bbox_xyxy):
|
| 60 |
+
tlwh_bboxs = []
|
| 61 |
+
for i, box in enumerate(bbox_xyxy):
|
| 62 |
+
x1, y1, x2, y2 = [int(i) for i in box]
|
| 63 |
+
top = x1
|
| 64 |
+
left = y1
|
| 65 |
+
w = int(x2 - x1)
|
| 66 |
+
h = int(y2 - y1)
|
| 67 |
+
tlwh_obj = [top, left, w, h]
|
| 68 |
+
tlwh_bboxs.append(tlwh_obj)
|
| 69 |
+
return tlwh_bboxs
|
| 70 |
+
|
| 71 |
+
def compute_color_for_labels(label):
|
| 72 |
+
"""
|
| 73 |
+
Simple function that adds fixed color depending on the class
|
| 74 |
+
"""
|
| 75 |
+
if label == 0: #person #BGR
|
| 76 |
+
color = (85,45,255)
|
| 77 |
+
elif label == 2: # Car
|
| 78 |
+
color = (222,82,175)
|
| 79 |
+
elif label == 3: # Motobike
|
| 80 |
+
color = (0, 204, 255)
|
| 81 |
+
elif label == 5: # Bus
|
| 82 |
+
color = (0, 149, 255)
|
| 83 |
+
else:
|
| 84 |
+
color = [int((p * (label ** 2 - label + 1)) % 255) for p in palette]
|
| 85 |
+
return tuple(color)
|
| 86 |
+
|
| 87 |
+
def draw_border(img, pt1, pt2, color, thickness, r, d):
|
| 88 |
+
x1,y1 = pt1
|
| 89 |
+
x2,y2 = pt2
|
| 90 |
+
# Top left
|
| 91 |
+
cv2.line(img, (x1 + r, y1), (x1 + r + d, y1), color, thickness)
|
| 92 |
+
cv2.line(img, (x1, y1 + r), (x1, y1 + r + d), color, thickness)
|
| 93 |
+
cv2.ellipse(img, (x1 + r, y1 + r), (r, r), 180, 0, 90, color, thickness)
|
| 94 |
+
|
| 95 |
+
# Top right
|
| 96 |
+
cv2.line(img, (x2 - r, y1), (x2 - r - d, y1), color, thickness)
|
| 97 |
+
cv2.line(img, (x2, y1 + r), (x2, y1 + r + d), color, thickness)
|
| 98 |
+
cv2.ellipse(img, (x2 - r, y1 + r), (r, r), 270, 0, 90, color, thickness)
|
| 99 |
+
# Bottom left
|
| 100 |
+
cv2.line(img, (x1 + r, y2), (x1 + r + d, y2), color, thickness)
|
| 101 |
+
cv2.line(img, (x1, y2 - r), (x1, y2 - r - d), color, thickness)
|
| 102 |
+
cv2.ellipse(img, (x1 + r, y2 - r), (r, r), 90, 0, 90, color, thickness)
|
| 103 |
+
# Bottom right
|
| 104 |
+
cv2.line(img, (x2 - r, y2), (x2 - r - d, y2), color, thickness)
|
| 105 |
+
cv2.line(img, (x2, y2 - r), (x2, y2 - r - d), color, thickness)
|
| 106 |
+
cv2.ellipse(img, (x2 - r, y2 - r), (r, r), 0, 0, 90, color, thickness)
|
| 107 |
+
|
| 108 |
+
cv2.rectangle(img, (x1 + r, y1), (x2 - r, y2), color, -1, cv2.LINE_AA)
|
| 109 |
+
cv2.rectangle(img, (x1, y1 + r), (x2, y2 - r - d), color, -1, cv2.LINE_AA)
|
| 110 |
+
|
| 111 |
+
cv2.circle(img, (x1 +r, y1+r), 2, color, 12)
|
| 112 |
+
cv2.circle(img, (x2 -r, y1+r), 2, color, 12)
|
| 113 |
+
cv2.circle(img, (x1 +r, y2-r), 2, color, 12)
|
| 114 |
+
cv2.circle(img, (x2 -r, y2-r), 2, color, 12)
|
| 115 |
+
|
| 116 |
+
return img
|
| 117 |
+
|
| 118 |
+
def UI_box(x, img, color=None, label=None, line_thickness=None):
|
| 119 |
+
# Plots one bounding box on image img
|
| 120 |
+
tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1 # line/font thickness
|
| 121 |
+
color = color or [random.randint(0, 255) for _ in range(3)]
|
| 122 |
+
c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
|
| 123 |
+
# cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
|
| 124 |
+
if label:
|
| 125 |
+
tf = max(tl - 1, 1) # font thickness
|
| 126 |
+
t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
|
| 127 |
+
# c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
|
| 128 |
+
|
| 129 |
+
img = draw_border(img, (c1[0], c1[1] - t_size[1] -3), (c1[0] + t_size[0], c1[1]+3), color, 1, 8, 2)
|
| 130 |
+
|
| 131 |
+
# cv2.line(img, c1, c2, color, 30)
|
| 132 |
+
# cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA) # filled
|
| 133 |
+
cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)
|
| 134 |
+
|
| 135 |
+
def estimateSpeed(location1, location2):
|
| 136 |
+
|
| 137 |
+
d_pixels = math.sqrt(math.pow(location2[0] - location1[0], 2) + math.pow(location2[1] - location1[1], 2))
|
| 138 |
+
ppm = 8 #Pixels per Meter
|
| 139 |
+
d_meters = d_pixels / ppm
|
| 140 |
+
time_constant = 15 * 3.6
|
| 141 |
+
speed = d_meters * time_constant
|
| 142 |
+
return speed
|
| 143 |
+
|
| 144 |
+
# Return true if line segments AB and CD intersect
|
| 145 |
+
def intersect(A,B,C,D):
|
| 146 |
+
return ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D)
|
| 147 |
+
|
| 148 |
+
def ccw(A,B,C):
|
| 149 |
+
return (C[1]-A[1]) * (B[0]-A[0]) > (B[1]-A[1]) * (C[0]-A[0])
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
def draw_boxes(img, bbox, object_id, identities=None, offset=(0, 0)):
|
| 157 |
+
# cv2.line(img, line2[0], line2[1], (0,200,0), 3)
|
| 158 |
+
|
| 159 |
+
height, width, _ = img.shape
|
| 160 |
+
# remove tracked point from buffer if object is lost
|
| 161 |
+
for key in list(data_deque):
|
| 162 |
+
if key not in identities:
|
| 163 |
+
data_deque.pop(key)
|
| 164 |
+
|
| 165 |
+
for i, box in enumerate(bbox):
|
| 166 |
+
x1, y1 = int(box[0]), int(box[1])
|
| 167 |
+
x2, y2 = x1 + int(box[2]), y1 + int(box[3])
|
| 168 |
+
box=[x1, y1, x2, y2]
|
| 169 |
+
|
| 170 |
+
# x1, y1, x2, y2 = [int(i) for i in box]
|
| 171 |
+
x1 += offset[0]
|
| 172 |
+
x2 += offset[0]
|
| 173 |
+
y1 += offset[1]
|
| 174 |
+
y2 += offset[1]
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
# box_area = (x2-x1) * (y2-y1)
|
| 178 |
+
box_height = (y2-y1)
|
| 179 |
+
|
| 180 |
+
# code to find center of bottom edge
|
| 181 |
+
center = (int((x2+x1)/ 2), int((y2+y2)/2))
|
| 182 |
+
|
| 183 |
+
# get ID of object
|
| 184 |
+
id = int(identities[i]) if identities is not None else 0
|
| 185 |
+
|
| 186 |
+
# create new buffer for new object
|
| 187 |
+
if id not in data_deque:
|
| 188 |
+
data_deque[id] = deque(maxlen= 64)
|
| 189 |
+
speed_four_line_queue[id] = []
|
| 190 |
+
|
| 191 |
+
color = compute_color_for_labels(int(object_id[i]))
|
| 192 |
+
obj_name = names[int(object_id[i])]
|
| 193 |
+
label = '%s' % (obj_name)
|
| 194 |
+
|
| 195 |
+
# add center to buffer
|
| 196 |
+
data_deque[id].appendleft(center)
|
| 197 |
+
|
| 198 |
+
# print("id ", id)
|
| 199 |
+
# print("data_deque[id] ", data_deque[id])
|
| 200 |
+
|
| 201 |
+
if len(data_deque[id]) >= 2:
|
| 202 |
+
# print("data_deque[id][i-1]", data_deque[id][1], data_deque[id][0])
|
| 203 |
+
|
| 204 |
+
if intersect(data_deque[id][0], data_deque[id][1], line2[0], line2[1]):# or intersect(data_deque[id][0], data_deque[id][1], line1[0], line1[1]) or intersect(data_deque[id][0], data_deque[id][1], line3[0], line3[1]) or intersect(data_deque[id][0], data_deque[id][1], line4[0], line4[1]) :
|
| 205 |
+
|
| 206 |
+
# cv2.line(img, line2[0], line2[1], (0,100,0), 3)
|
| 207 |
+
|
| 208 |
+
obj_speed = estimateSpeed(data_deque[id][1], data_deque[id][0])
|
| 209 |
+
|
| 210 |
+
speed_four_line_queue[id].append(obj_speed)
|
| 211 |
+
|
| 212 |
+
if obj_name not in object_counter:
|
| 213 |
+
object_counter[obj_name] = 1
|
| 214 |
+
else:
|
| 215 |
+
object_counter[obj_name] += 1
|
| 216 |
+
|
| 217 |
+
try:
|
| 218 |
+
label = label + " " + str(sum(speed_four_line_queue[id])//len(speed_four_line_queue[id]))
|
| 219 |
+
except :
|
| 220 |
+
pass
|
| 221 |
+
|
| 222 |
+
UI_box(box, img, label=label, color=color, line_thickness=2)
|
| 223 |
+
|
| 224 |
+
# draw trail
|
| 225 |
+
for i in range(1, len(data_deque[id])):
|
| 226 |
+
# check if on buffer value is none
|
| 227 |
+
if data_deque[id][i - 1] is None or data_deque[id][i] is None:
|
| 228 |
+
continue
|
| 229 |
+
|
| 230 |
+
# generate dynamic thickness of trails
|
| 231 |
+
thickness = int(np.sqrt(64 / float(i + i)) * 1.5)
|
| 232 |
+
|
| 233 |
+
# draw trails
|
| 234 |
+
cv2.line(img, data_deque[id][i - 1], data_deque[id][i], color, thickness)
|
| 235 |
+
|
| 236 |
+
|
| 237 |
+
count = 0
|
| 238 |
+
for idx, (key, value) in enumerate(object_counter.items()):
|
| 239 |
+
# print(idx, key, value)
|
| 240 |
+
cnt_str = str(key) + ": " + str(value)
|
| 241 |
+
|
| 242 |
+
cv2.line(img, (width - 150 ,25+ (idx*40)), (width,25 + (idx*40)), [85,45,255], 30)
|
| 243 |
+
cv2.putText(img, cnt_str, (width - 150, 35 + (idx*40)), 0, 1, [225, 255, 255], thickness=2, lineType=cv2.LINE_AA)
|
| 244 |
+
|
| 245 |
+
count += value
|
| 246 |
+
|
| 247 |
+
return img, count
|
| 248 |
+
|
| 249 |
+
def load_yolov7_and_process_each_frame(model, vid_name, enable_GPU, save_video, confidence, assigned_class_id, kpi1_text, kpi2_text, kpi3_text, stframe):
|
| 250 |
+
data_deque.clear()
|
| 251 |
+
speed_four_line_queue.clear()
|
| 252 |
+
object_counter.clear()
|
| 253 |
+
|
| 254 |
+
if model == 'yolov7':
|
| 255 |
+
weights = 'yolov7/weights/yolov7.onnx'
|
| 256 |
+
elif model == 'yolov7-tiny':
|
| 257 |
+
weights = 'yolov7/weights/yolov7-tiny.onnx'
|
| 258 |
+
else:
|
| 259 |
+
print('Model Not Found!')
|
| 260 |
+
exit()
|
| 261 |
+
|
| 262 |
+
detector = YOLOv7Detector(weights=weights, use_cuda=enable_GPU, use_onnx=True)
|
| 263 |
+
tracker = ByteTrack(detector)
|
| 264 |
+
# dataset = LoadImages(vid_name, img_size=1280, auto_size=64)
|
| 265 |
+
|
| 266 |
+
vdo = cv2.VideoCapture(vid_name)
|
| 267 |
+
results = []
|
| 268 |
+
start = time.time()
|
| 269 |
+
count = 0
|
| 270 |
+
frame_id = 0
|
| 271 |
+
prevTime = 0
|
| 272 |
+
|
| 273 |
+
fourcc = 'mp4v' # output video codec
|
| 274 |
+
fps = vdo.get(cv2.CAP_PROP_FPS)
|
| 275 |
+
w = int(vdo.get(cv2.CAP_PROP_FRAME_WIDTH))
|
| 276 |
+
h = int(vdo.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
| 277 |
+
vid_writer = cv2.VideoWriter('inference/output/results.mp4', cv2.VideoWriter_fourcc(*fourcc), fps, (w, h))
|
| 278 |
+
|
| 279 |
+
while vdo.isOpened():
|
| 280 |
+
# for path, img, im0s, vid_cap in dataset:
|
| 281 |
+
curr_time = time.time()
|
| 282 |
+
frame_id +=1
|
| 283 |
+
_, img = vdo.read()
|
| 284 |
+
|
| 285 |
+
if _ == False:
|
| 286 |
+
break
|
| 287 |
+
|
| 288 |
+
# img = cv2.cvtColor(ori_im, cv2.COLOR_BGR2RGB)
|
| 289 |
+
# img, count, obj_ids = tracker.inference(img, conf_thresh=confidence, classes=assigned_class_id)
|
| 290 |
+
bboxes, ids, scores, obj_ids = tracker.inference(img, conf_thresh=confidence, classes=assigned_class_id)
|
| 291 |
+
# print(bboxes[0].shape if len(bboxes)>0 else None)
|
| 292 |
+
img, count = draw_boxes(img, bboxes, obj_ids, identities=ids)
|
| 293 |
+
currTime = time.time()
|
| 294 |
+
fps = 1 / (currTime - prevTime)
|
| 295 |
+
prevTime = currTime
|
| 296 |
+
|
| 297 |
+
# Save results (image with detections)
|
| 298 |
+
cv2.line(img, (20,25), (127,25), [85,45,255], 30)
|
| 299 |
+
cv2.putText(img, f'FPS: {int(fps)}', (11, 35), 0, 1, [225, 255, 255], thickness=2, lineType=cv2.LINE_AA)
|
| 300 |
+
|
| 301 |
+
if save_video:
|
| 302 |
+
vid_writer.write(img)
|
| 303 |
+
|
| 304 |
+
kpi1_text.write(f"<h1 style='text-align: center; color: red;'>{fps:.1f}</h1>", unsafe_allow_html=True)
|
| 305 |
+
kpi2_text.write(f"<h1 style='text-align: center; color: red;'>{len(data_deque)}</h1>", unsafe_allow_html=True)
|
| 306 |
+
kpi3_text.write(f"<h1 style='text-align: center; color: red;'>{count}</h1>", unsafe_allow_html=True)
|
| 307 |
+
# if frame_id%3==0:
|
| 308 |
+
# stframe.image(img, channels = 'BGR',use_column_width=True)
|
| 309 |
+
stframe.image(img, channels = 'BGR',use_column_width=True)
|
| 310 |
+
|
| 311 |
+
|
| 312 |
+
end = time.time()
|
| 313 |
+
print('Done. (%.3fs)' % (end - start))
|
| 314 |
+
cv2.destroyAllWindows()
|
| 315 |
+
vdo.release()
|
| 316 |
+
vid_writer.release()
|
| 317 |
+
|
| 318 |
+
|
| 319 |
+
def load_yolor_and_process_each_frame(vid_name, enable_GPU, confidence, assigned_class_id, kpi1_text, kpi2_text, kpi3_text, stframe):
|
| 320 |
+
data_deque.clear()
|
| 321 |
+
speed_four_line_queue.clear()
|
| 322 |
+
object_counter.clear()
|
| 323 |
+
|
| 324 |
+
out, source, weights, save_txt, imgsz, cfg = \
|
| 325 |
+
'inference/output', vid_name, 'yolor_p6.pt', False, 1280, 'cfg/yolor_p6.cfg'
|
| 326 |
+
|
| 327 |
+
#webcam = source == '0' or source.startswith('rtsp') or source.startswith('http') or source.endswith('.txt')
|
| 328 |
+
webcam = source == 0 or source.startswith('rtsp') or source.startswith('http') or source.endswith('.txt')
|
| 329 |
+
|
| 330 |
+
# initialize deepsort
|
| 331 |
+
cfg_deep = get_config()
|
| 332 |
+
cfg_deep.merge_from_file("deep_sort_pytorch/configs/deep_sort.yaml")
|
| 333 |
+
# attempt_download("deep_sort_pytorch/deep_sort/deep/checkpoint/ckpt.t7", repo='mikel-brostrom/Yolov5_DeepSort_Pytorch')
|
| 334 |
+
deepsort = DeepSort(cfg_deep.DEEPSORT.REID_CKPT,
|
| 335 |
+
max_dist=cfg_deep.DEEPSORT.MAX_DIST, min_confidence=cfg_deep.DEEPSORT.MIN_CONFIDENCE,
|
| 336 |
+
nms_max_overlap=cfg_deep.DEEPSORT.NMS_MAX_OVERLAP, max_iou_distance=cfg_deep.DEEPSORT.MAX_IOU_DISTANCE,
|
| 337 |
+
max_age=cfg_deep.DEEPSORT.MAX_AGE, n_init=cfg_deep.DEEPSORT.N_INIT, nn_budget=cfg_deep.DEEPSORT.NN_BUDGET,
|
| 338 |
+
use_cuda=True)
|
| 339 |
+
|
| 340 |
+
# Initialize GPU
|
| 341 |
+
if enable_GPU:
|
| 342 |
+
device = select_device('gpu')
|
| 343 |
+
else:
|
| 344 |
+
device = select_device('cpu')
|
| 345 |
+
|
| 346 |
+
if os.path.exists(out):
|
| 347 |
+
shutil.rmtree(out) # delete output folder
|
| 348 |
+
os.makedirs(out) # make new output folder
|
| 349 |
+
half = device.type != 'cpu' # half precision only supported on CUDA
|
| 350 |
+
|
| 351 |
+
# Load model
|
| 352 |
+
model = Darknet(cfg, imgsz)#.cuda()
|
| 353 |
+
model.load_state_dict(torch.load(weights, map_location=device)['model'])
|
| 354 |
+
model.to(device).eval()
|
| 355 |
+
if half:
|
| 356 |
+
model.half() # to FP16
|
| 357 |
+
|
| 358 |
+
# Second-stage classifier
|
| 359 |
+
classify = False
|
| 360 |
+
if classify:
|
| 361 |
+
modelc = load_classifier(name='resnet101', n=2) # initialize
|
| 362 |
+
modelc.load_state_dict(torch.load('weights/resnet101.pt', map_location=device)['model']) # load weights
|
| 363 |
+
modelc.to(device).eval()
|
| 364 |
+
|
| 365 |
+
# Set Dataloader
|
| 366 |
+
vid_path, vid_writer = None, None
|
| 367 |
+
if webcam:
|
| 368 |
+
save_img = True
|
| 369 |
+
print("HEREHERER")
|
| 370 |
+
# cudnn.benchmark = True # set True to speed up constant image size inference
|
| 371 |
+
# dataset = LoadStreams(source, img_size=imgsz)
|
| 372 |
+
else:
|
| 373 |
+
save_img = True
|
| 374 |
+
dataset = LoadImages(source, img_size=imgsz, auto_size=64)
|
| 375 |
+
|
| 376 |
+
|
| 377 |
+
# Run inference
|
| 378 |
+
t0 = time.time()
|
| 379 |
+
img = torch.zeros((1, 3, imgsz, imgsz), device=device) # init img
|
| 380 |
+
_ = model(img.half() if half else img) if device.type != 'cpu' else None # run once
|
| 381 |
+
prevTime = 0
|
| 382 |
+
count = 0
|
| 383 |
+
|
| 384 |
+
if webcam: # code for only webcam
|
| 385 |
+
|
| 386 |
+
vid = cv2.VideoCapture(0)
|
| 387 |
+
|
| 388 |
+
while vid.isOpened():
|
| 389 |
+
ret, img = vid.read()
|
| 390 |
+
if not ret:
|
| 391 |
+
continue
|
| 392 |
+
|
| 393 |
+
im0s = img.copy()
|
| 394 |
+
print(im0s.shape)
|
| 395 |
+
img = img[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB, to bsx3x416x416
|
| 396 |
+
print(img.shape)
|
| 397 |
+
|
| 398 |
+
img = torch.from_numpy(img.copy()).to(device)
|
| 399 |
+
img = img.half() if half else img.float() # uint8 to fp16/32
|
| 400 |
+
img /= 255.0 # 0 - 255 to 0.0 - 1.0
|
| 401 |
+
if img.ndimension() == 3:
|
| 402 |
+
img = img.unsqueeze(0)
|
| 403 |
+
|
| 404 |
+
print(img.shape)
|
| 405 |
+
|
| 406 |
+
# Inference
|
| 407 |
+
t1 = time_synchronized()
|
| 408 |
+
pred = model(img)[0]
|
| 409 |
+
|
| 410 |
+
# Apply NMS
|
| 411 |
+
pred = non_max_suppression(pred, confidence, 0.5, classes=assigned_class_id, agnostic=False)
|
| 412 |
+
t2 = time_synchronized()
|
| 413 |
+
|
| 414 |
+
# Apply Classifier
|
| 415 |
+
if classify:
|
| 416 |
+
pred = apply_classifier(pred, modelc, img, im0s)
|
| 417 |
+
|
| 418 |
+
print("HERE")
|
| 419 |
+
# Process detections
|
| 420 |
+
for i, det in enumerate(pred): # detections per image
|
| 421 |
+
p, s, im0 = "webcam_out.mp4", '', im0s
|
| 422 |
+
|
| 423 |
+
# save_path = str(Path(out) / Path(p).name)
|
| 424 |
+
# txt_path = str(Path(out) / Path(p).stem) + ('_%g' % dataset.frame if dataset.mode == 'video' else '')
|
| 425 |
+
s += '%gx%g ' % img.shape[2:] # print string
|
| 426 |
+
gn = torch.tensor(im0.shape)[[1, 0, 1, 0]] # normalization gain whwh
|
| 427 |
+
if det is not None and len(det):
|
| 428 |
+
# Rescale boxes from img_size to im0 size
|
| 429 |
+
det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()
|
| 430 |
+
|
| 431 |
+
# Print results
|
| 432 |
+
for c in det[:, -1].unique():
|
| 433 |
+
n = (det[:, -1] == c).sum() # detections per class
|
| 434 |
+
s += '%g %ss, ' % (n, names[int(c)]) # add to string
|
| 435 |
+
|
| 436 |
+
xywh_bboxs = []
|
| 437 |
+
confs = []
|
| 438 |
+
oids = []
|
| 439 |
+
# Write results
|
| 440 |
+
for *xyxy, conf, cls in det:
|
| 441 |
+
# to deep sort format
|
| 442 |
+
x_c, y_c, bbox_w, bbox_h = xyxy_to_xywh(*xyxy)
|
| 443 |
+
xywh_obj = [x_c, y_c, bbox_w, bbox_h]
|
| 444 |
+
xywh_bboxs.append(xywh_obj)
|
| 445 |
+
confs.append([conf.item()])
|
| 446 |
+
oids.append(int(cls))
|
| 447 |
+
|
| 448 |
+
# if save_txt: # Write to file
|
| 449 |
+
# xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh
|
| 450 |
+
# with open(txt_path + '.txt', 'a') as f:
|
| 451 |
+
# f.write(('%g ' * 5 + '\n') % (cls, *xywh)) # label format
|
| 452 |
+
|
| 453 |
+
xywhs = torch.Tensor(xywh_bboxs)
|
| 454 |
+
confss = torch.Tensor(confs)
|
| 455 |
+
|
| 456 |
+
outputs = deepsort.update(xywhs, confss, oids, im0)
|
| 457 |
+
if len(outputs) > 0:
|
| 458 |
+
bbox_xyxy = outputs[:, :4]
|
| 459 |
+
identities = outputs[:, -2]
|
| 460 |
+
object_id = outputs[:, -1]
|
| 461 |
+
im0, count = draw_boxes(im0, bbox_xyxy, object_id,identities)
|
| 462 |
+
|
| 463 |
+
# Print time (inference + NMS)
|
| 464 |
+
print('%sDone. (%.3fs)' % (s, t2 - t1))
|
| 465 |
+
|
| 466 |
+
currTime = time.time()
|
| 467 |
+
fps = 1 / (currTime - prevTime)
|
| 468 |
+
prevTime = currTime
|
| 469 |
+
cv2.line(im0, (20,25), (127,25), [85,45,255], 30)
|
| 470 |
+
cv2.putText(im0, f'FPS: {int(fps)}', (11, 35), 0, 1, [225, 255, 255], thickness=2, lineType=cv2.LINE_AA)
|
| 471 |
+
kpi1_text.write(f"<h1 style='text-align: center; color: red;'>{'{:.1f}'.format(fps)}</h1>", unsafe_allow_html=True)
|
| 472 |
+
|
| 473 |
+
# # Save results (image with detections)
|
| 474 |
+
# if save_img:
|
| 475 |
+
# if dataset.mode == 'images':
|
| 476 |
+
# cv2.imwrite(save_path, im0)
|
| 477 |
+
# else:
|
| 478 |
+
# if vid_path != save_path: # new video
|
| 479 |
+
# vid_path = save_path
|
| 480 |
+
# if isinstance(vid_writer, cv2.VideoWriter):
|
| 481 |
+
# vid_writer.release() # release previous video writer
|
| 482 |
+
|
| 483 |
+
# fourcc = 'mp4v' # output video codec
|
| 484 |
+
# fps = vid_cap.get(cv2.CAP_PROP_FPS)
|
| 485 |
+
# w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
| 486 |
+
# h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
| 487 |
+
# vid_writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*fourcc), fps, (w, h))
|
| 488 |
+
# vid_writer.write(im0)
|
| 489 |
+
|
| 490 |
+
# data_deque assign inside yolor.py
|
| 491 |
+
|
| 492 |
+
kpi2_text.write(f"<h1 style='text-align: center; color: red;'>{len(data_deque)}</h1>", unsafe_allow_html=True)
|
| 493 |
+
kpi3_text.write(f"<h1 style='text-align: center; color: red;'>{count}</h1>", unsafe_allow_html=True)
|
| 494 |
+
stframe.image(im0,channels = 'BGR',use_column_width=True)
|
| 495 |
+
|
| 496 |
+
else: # without webcam
|
| 497 |
+
for path, img, im0s, vid_cap in dataset:
|
| 498 |
+
# print(path)
|
| 499 |
+
# print(img.shape)
|
| 500 |
+
# print(im0s.shape)
|
| 501 |
+
# print(vid_cap)
|
| 502 |
+
|
| 503 |
+
|
| 504 |
+
img = torch.from_numpy(img).to(device)
|
| 505 |
+
img = img.half() if half else img.float() # uint8 to fp16/32
|
| 506 |
+
img /= 255.0 # 0 - 255 to 0.0 - 1.0
|
| 507 |
+
if img.ndimension() == 3:
|
| 508 |
+
img = img.unsqueeze(0)
|
| 509 |
+
|
| 510 |
+
# Inference
|
| 511 |
+
t1 = time_synchronized()
|
| 512 |
+
print(img.shape)
|
| 513 |
+
|
| 514 |
+
pred = model(img)[0]
|
| 515 |
+
|
| 516 |
+
# Apply NMS
|
| 517 |
+
pred = non_max_suppression(pred, confidence, 0.5, classes=assigned_class_id, agnostic=False)
|
| 518 |
+
t2 = time_synchronized()
|
| 519 |
+
|
| 520 |
+
# Apply Classifier
|
| 521 |
+
if classify:
|
| 522 |
+
pred = apply_classifier(pred, modelc, img, im0s)
|
| 523 |
+
|
| 524 |
+
# Process detections
|
| 525 |
+
for i, det in enumerate(pred): # detections per image
|
| 526 |
+
if webcam: # batch_size >= 1
|
| 527 |
+
p, s, im0 = path[i], '%g: ' % i, im0s[i].copy()
|
| 528 |
+
else:
|
| 529 |
+
p, s, im0 = path, '', im0s
|
| 530 |
+
|
| 531 |
+
save_path = str(Path(out) / Path(p).name)
|
| 532 |
+
txt_path = str(Path(out) / Path(p).stem) + ('_%g' % dataset.frame if dataset.mode == 'video' else '')
|
| 533 |
+
s += '%gx%g ' % img.shape[2:] # print string
|
| 534 |
+
gn = torch.tensor(im0.shape)[[1, 0, 1, 0]] # normalization gain whwh
|
| 535 |
+
if det is not None and len(det):
|
| 536 |
+
# Rescale boxes from img_size to im0 size
|
| 537 |
+
det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()
|
| 538 |
+
|
| 539 |
+
# Print results
|
| 540 |
+
for c in det[:, -1].unique():
|
| 541 |
+
n = (det[:, -1] == c).sum() # detections per class
|
| 542 |
+
s += '%g %ss, ' % (n, names[int(c)]) # add to string
|
| 543 |
+
|
| 544 |
+
xywh_bboxs = []
|
| 545 |
+
confs = []
|
| 546 |
+
oids = []
|
| 547 |
+
# Write results
|
| 548 |
+
for *xyxy, conf, cls in det:
|
| 549 |
+
# to deep sort format
|
| 550 |
+
x_c, y_c, bbox_w, bbox_h = xyxy_to_xywh(*xyxy)
|
| 551 |
+
xywh_obj = [x_c, y_c, bbox_w, bbox_h]
|
| 552 |
+
xywh_bboxs.append(xywh_obj)
|
| 553 |
+
confs.append([conf.item()])
|
| 554 |
+
oids.append(int(cls))
|
| 555 |
+
|
| 556 |
+
if save_txt: # Write to file
|
| 557 |
+
xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh
|
| 558 |
+
with open(txt_path + '.txt', 'a') as f:
|
| 559 |
+
f.write(('%g ' * 5 + '\n') % (cls, *xywh)) # label format
|
| 560 |
+
|
| 561 |
+
xywhs = torch.Tensor(xywh_bboxs)
|
| 562 |
+
confss = torch.Tensor(confs)
|
| 563 |
+
|
| 564 |
+
outputs = deepsort.update(xywhs, confss, oids, im0)
|
| 565 |
+
if len(outputs) > 0:
|
| 566 |
+
bbox_xyxy = outputs[:, :4]
|
| 567 |
+
identities = outputs[:, -2]
|
| 568 |
+
object_id = outputs[:, -1]
|
| 569 |
+
im0, count = draw_boxes(im0, bbox_xyxy, object_id,identities)
|
| 570 |
+
|
| 571 |
+
# Print time (inference + NMS)
|
| 572 |
+
print('%sDone. (%.3fs)' % (s, t2 - t1))
|
| 573 |
+
|
| 574 |
+
currTime = time.time()
|
| 575 |
+
fps = 1 / (currTime - prevTime)
|
| 576 |
+
prevTime = currTime
|
| 577 |
+
cv2.line(im0, (20,25), (127,25), [85,45,255], 30)
|
| 578 |
+
cv2.putText(im0, f'FPS: {int(fps)}', (11, 35), 0, 1, [225, 255, 255], thickness=2, lineType=cv2.LINE_AA)
|
| 579 |
+
kpi1_text.write(f"<h1 style='text-align: center; color: red;'>{'{:.1f}'.format(fps)}</h1>", unsafe_allow_html=True)
|
| 580 |
+
|
| 581 |
+
# Save results (image with detections)
|
| 582 |
+
if save_img:
|
| 583 |
+
if dataset.mode == 'images':
|
| 584 |
+
cv2.imwrite(save_path, im0)
|
| 585 |
+
else:
|
| 586 |
+
if vid_path != save_path: # new video
|
| 587 |
+
vid_path = save_path
|
| 588 |
+
if isinstance(vid_writer, cv2.VideoWriter):
|
| 589 |
+
vid_writer.release() # release previous video writer
|
| 590 |
+
|
| 591 |
+
fourcc = 'mp4v' # output video codec
|
| 592 |
+
fps = vid_cap.get(cv2.CAP_PROP_FPS)
|
| 593 |
+
w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
| 594 |
+
h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
| 595 |
+
vid_writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*fourcc), fps, (w, h))
|
| 596 |
+
vid_writer.write(im0)
|
| 597 |
+
|
| 598 |
+
# data_deque assign inside yolor.py
|
| 599 |
+
|
| 600 |
+
kpi2_text.write(f"<h1 style='text-align: center; color: red;'>{len(data_deque)}</h1>", unsafe_allow_html=True)
|
| 601 |
+
kpi3_text.write(f"<h1 style='text-align: center; color: red;'>{count}</h1>", unsafe_allow_html=True)
|
| 602 |
+
stframe.image(im0,channels = 'BGR',use_column_width=True)
|
| 603 |
+
|
| 604 |
+
|
| 605 |
+
if save_txt or save_img:
|
| 606 |
+
print('Results saved to %s' % Path(out))
|
| 607 |
+
if platform == 'darwin': # MacOS
|
| 608 |
+
os.system('open ' + save_path)
|
| 609 |
+
|
| 610 |
+
print('Done. (%.3fs)' % (time.time() - t0))
|
| 611 |
+
cv2.destroyAllWindows()
|
| 612 |
+
vid.release()
|
yolov7-tiny-demo.py
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# To run use
|
| 2 |
+
# $ streamlit run yolor_streamlit_demo.py
|
| 3 |
+
|
| 4 |
+
from yolo_v7 import names, load_yolov7_and_process_each_frame
|
| 5 |
+
|
| 6 |
+
import tempfile
|
| 7 |
+
import cv2
|
| 8 |
+
|
| 9 |
+
from models.models import *
|
| 10 |
+
from utils.datasets import *
|
| 11 |
+
from utils.general import *
|
| 12 |
+
import streamlit as st
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def main():
|
| 16 |
+
|
| 17 |
+
#title
|
| 18 |
+
st.title('Object Tracking Dashboard YOLOv7-tiny')
|
| 19 |
+
|
| 20 |
+
#side bar title
|
| 21 |
+
st.sidebar.title('Settings')
|
| 22 |
+
|
| 23 |
+
st.markdown(
|
| 24 |
+
"""
|
| 25 |
+
<style>
|
| 26 |
+
[data-testid="stSidebar"][aria-expanded="true"] > div:first-child {
|
| 27 |
+
width: 350px;
|
| 28 |
+
}
|
| 29 |
+
[data-testid="stSidebar"][aria-expanded="false"] > div:first-child {
|
| 30 |
+
width: 350px;
|
| 31 |
+
margin-left: -350px;
|
| 32 |
+
}
|
| 33 |
+
</style>
|
| 34 |
+
""",
|
| 35 |
+
unsafe_allow_html=True,
|
| 36 |
+
)
|
| 37 |
+
|
| 38 |
+
use_webcam = st.sidebar.checkbox('Use Webcam')
|
| 39 |
+
|
| 40 |
+
st.sidebar.markdown('---')
|
| 41 |
+
confidence = st.sidebar.slider('Confidence',min_value=0.0, max_value=1.0, value = 0.25)
|
| 42 |
+
st.sidebar.markdown('---')
|
| 43 |
+
|
| 44 |
+
save_img = st.sidebar.checkbox('Save Video')
|
| 45 |
+
enable_GPU = st.sidebar.checkbox('enable GPU')
|
| 46 |
+
|
| 47 |
+
custom_classes = st.sidebar.checkbox('Use Custom Classes')
|
| 48 |
+
assigned_class_id = []
|
| 49 |
+
if custom_classes:
|
| 50 |
+
assigned_class = st.sidebar.multiselect('Select The Custom Classes',list(names),default='person')
|
| 51 |
+
for each in assigned_class:
|
| 52 |
+
assigned_class_id.append(names.index(each))
|
| 53 |
+
|
| 54 |
+
video_file_buffer = st.sidebar.file_uploader("Upload a video", type=[ "mp4", "mov",'avi','asf', 'm4v' ])
|
| 55 |
+
|
| 56 |
+
DEMO_VIDEO = 'test.mp4'
|
| 57 |
+
|
| 58 |
+
tfflie = tempfile.NamedTemporaryFile(suffix='.mp4', delete=False)
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
##We get our input video here
|
| 62 |
+
|
| 63 |
+
if not video_file_buffer:
|
| 64 |
+
if use_webcam:
|
| 65 |
+
vid = cv2.VideoCapture(0, cv2.CAP_ARAVIS)
|
| 66 |
+
tfflie.name = 0
|
| 67 |
+
else:
|
| 68 |
+
vid = cv2.VideoCapture(DEMO_VIDEO)
|
| 69 |
+
tfflie.name = DEMO_VIDEO
|
| 70 |
+
dem_vid = open(tfflie.name,'rb')
|
| 71 |
+
demo_bytes = dem_vid.read()
|
| 72 |
+
|
| 73 |
+
st.sidebar.text('Input Video')
|
| 74 |
+
st.sidebar.video(demo_bytes)
|
| 75 |
+
|
| 76 |
+
else:
|
| 77 |
+
tfflie.write(video_file_buffer.read())
|
| 78 |
+
# print("No Buffer")
|
| 79 |
+
dem_vid = open(tfflie.name,'rb')
|
| 80 |
+
demo_bytes = dem_vid.read()
|
| 81 |
+
|
| 82 |
+
st.sidebar.text('Input Video')
|
| 83 |
+
st.sidebar.video(demo_bytes)
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
print(tfflie.name)
|
| 87 |
+
# vid = cv2.VideoCapture(tfflie.name)
|
| 88 |
+
|
| 89 |
+
stframe = st.empty()
|
| 90 |
+
|
| 91 |
+
st.markdown("<hr/>", unsafe_allow_html=True)
|
| 92 |
+
kpi1, kpi2, kpi3 = st.beta_columns(3) #st.columns(3)
|
| 93 |
+
|
| 94 |
+
# stframe.image(im0,channels = 'BGR',use_column_width=True)
|
| 95 |
+
|
| 96 |
+
with kpi1:
|
| 97 |
+
st.markdown("**Frame Rate**")
|
| 98 |
+
kpi1_text = st.markdown("0")
|
| 99 |
+
|
| 100 |
+
with kpi2:
|
| 101 |
+
st.markdown("**Tracked Objects**")
|
| 102 |
+
kpi2_text = st.markdown("0")
|
| 103 |
+
|
| 104 |
+
with kpi3:
|
| 105 |
+
st.markdown("**Total Count**")
|
| 106 |
+
kpi3_text = st.markdown("0")
|
| 107 |
+
|
| 108 |
+
st.markdown("<hr/>", unsafe_allow_html=True)
|
| 109 |
+
# call yolor
|
| 110 |
+
# load_yolor_and_process_each_frame(tfflie.name, enable_GPU, confidence, assigned_class_id, kpi1_text, kpi2_text, kpi3_text, stframe)
|
| 111 |
+
load_yolov7_and_process_each_frame('yolov7-tiny', tfflie.name, enable_GPU, save_img, confidence, assigned_class_id, kpi1_text, kpi2_text, kpi3_text, stframe)
|
| 112 |
+
|
| 113 |
+
st.text('Video is Processed')
|
| 114 |
+
|
| 115 |
+
if __name__ == '__main__':
|
| 116 |
+
try:
|
| 117 |
+
main()
|
| 118 |
+
except SystemExit:
|
| 119 |
+
pass
|
| 120 |
+
|
| 121 |
+
|