Skip to content

Instantly share code, notes, and snippets.

@simeneide
Created December 29, 2019 17:28
Show Gist options
  • Save simeneide/d6b50871246d76141a811a0e370505ed to your computer and use it in GitHub Desktop.
Save simeneide/d6b50871246d76141a811a0e370505ed to your computer and use it in GitHub Desktop.
bounding box of videostream. visualized in streamlit
#%%
import time
import numpy as np
import streamlit as st
import pandas as pd
import cv2
video_sources = {
'Rindabotn' : "http://217.17.213.66:8081/mjpg/video.mjpg?overview=0&camera=1&videoframeskipmode=empty&Axis-Orig-Sw=true&resolution=1280x720",
'Hodlekve' : "http://217.17.213.66:8080/mjpg/video.mjpg?overview=0&camera=1&videoframeskipmode=empty&Axis-Orig-Sw=true&resolution=1280x720",
'Times Square ground' : 'https://videos3.earthcam.com/fecnetwork/9974.flv/chunklist_w1421640637.m3u8',
'Times Square' : 'https://videos3.earthcam.com/fecnetwork/hdtimes10.flv/chunklist_w1581551174.m3u8',
'Road' : 'https://videos3.earthcam.com/fecnetwork/15559.flv/chunklist_w1295434004.m3u8'
}
#%% Run the YOLO model to detect objects.
# Borrowed functions from https://github.com/streamlit/demo-self-driving/blob/master/app.py
def yolo_v3(image, confidence_threshold, overlap_threshold):
# Load the network. Because this is cached it will only happen once.
@st.cache(allow_output_mutation=True)
def load_network(config_path, weights_path):
net = cv2.dnn.readNetFromDarknet(config_path, weights_path)
output_layer_names = net.getLayerNames()
output_layer_names = [output_layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
return net, output_layer_names
net, output_layer_names = load_network("yolov3.cfg", "yolov3.weights")
# Run the YOLO neural net.
blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416), swapRB=True, crop=False)
net.setInput(blob)
layer_outputs = net.forward(output_layer_names)
# Supress detections in case of too low confidence or too much overlap.
boxes, confidences, class_IDs = [], [], []
H, W = image.shape[:2]
for output in layer_outputs:
for detection in output:
scores = detection[5:]
classID = np.argmax(scores)
confidence = scores[classID]
if confidence > confidence_threshold:
box = detection[0:4] * np.array([W, H, W, H])
centerX, centerY, width, height = box.astype("int")
x, y = int(centerX - (width / 2)), int(centerY - (height / 2))
boxes.append([x, y, int(width), int(height)])
confidences.append(float(confidence))
class_IDs.append(classID)
indices = cv2.dnn.NMSBoxes(boxes, confidences, confidence_threshold, overlap_threshold)
# Map from YOLO labels to Udacity labels.
UDACITY_LABELS = {
0: 'pedestrian',
1: 'biker',
2: 'car',
3: 'biker',
5: 'truck',
7: 'truck',
9: 'trafficLight'
}
xmin, xmax, ymin, ymax, labels = [], [], [], [], []
if len(indices) > 0:
# loop over the indexes we are keeping
for i in indices.flatten():
label = class_IDs[i]#UDACITY_LABELS.get(class_IDs[i], None)
if label is None:
continue
# extract the bounding box coordinates
x, y, w, h = boxes[i][0], boxes[i][1], boxes[i][2], boxes[i][3]
xmin.append(x)
ymin.append(y)
xmax.append(x+w)
ymax.append(y+h)
labels.append(label)
boxes = pd.DataFrame({"xmin": xmin, "ymin": ymin, "xmax": xmax, "ymax": ymax, "labels": labels})
return boxes[["xmin", "ymin", "xmax", "ymax", "labels"]]
def create_image_with_boxes(image, boxes, header, description):
# Superpose the semi-transparent object detection boxes. # Colors for the boxes
LABEL_COLORS = {
"car": [255, 0, 0],
"pedestrian": [0, 255, 0],
"truck": [0, 0, 255],
"trafficLight": [255, 255, 0],
"biker": [255, 0, 255],
}
image_with_boxes = image.astype(np.float64)
for _, (xmin, ymin, xmax, ymax, label) in boxes.iterrows():
image_with_boxes[int(ymin):int(ymax),int(xmin):int(xmax),:] += [label*10,255-10*label,label] #LABEL_COLORS[label]
image_with_boxes[int(ymin):int(ymax),int(xmin):int(xmax),:] /= 2
return image_with_boxes.astype(np.uint8)
#%%
import cv2
from threading import Thread
class ThreadedCamera(object):
def __init__(self, source = 0):
self.capture = cv2.VideoCapture(source)
self.thread = Thread(target = self.update, args = ())
self.thread.daemon = True
self.thread.start()
self.status = False
self.frame = None
def update(self):
while True:
if self.capture.isOpened():
(self.status, self.frame) = self.capture.read()
def grab_frame(self):
if self.status:
return self.frame
return None
#%% DISPLAY
st.sidebar.title("Parameters")
source = st.sidebar.radio("Velg kamera", list(video_sources.keys()))
st.markdown(f"# {source}")
url = video_sources[source]
streamer = ThreadedCamera(url)
cap = cv2.VideoCapture(url)
confidence_threshold = st.sidebar.slider("Confidence threshold", 0.0, 1.0, 0.5, 0.01)
overlap_threshold = st.sidebar.slider("Overlap threshold", 0.0, 1.0, 0.3, 0.01)
sleeptime = st.sidebar.slider("Sleep", 0.0, 10.0, 1.0, 0.1)
stream = st.empty()
while True:
#result, frame = cap.read()
frame = streamer.grab_frame()
boxes = yolo_v3(frame, confidence_threshold=confidence_threshold, overlap_threshold=overlap_threshold)
frame = create_image_with_boxes(frame,boxes, header="",description="")
stream.image(frame, use_column_width=True)
time.sleep(sleeptime)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment