Skip to content

Commit

Permalink
webcam updates
Browse files Browse the repository at this point in the history
  • Loading branch information
glenn-jocher committed Feb 11, 2019
1 parent 585f2e2 commit e23b1a3
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 233 deletions.
13 changes: 8 additions & 5 deletions detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,16 @@ def detect(

for i, (path, img, im0) in enumerate(dataloader):
t = time.time()
print("%g/%g '%s': " % (i + 1, len(dataloader), path if not webcam else 'webcam'), end='')
if webcam:
print('webcam frame %g: ' % (i + 1), end='')
else:
print('image %g/%g %s: ' % (i + 1, len(dataloader), path), end='')
save_path = os.path.join(output, path.split('/')[-1])

# Get detections
img = torch.from_numpy(img).unsqueeze(0).to(device)
if ONNX_EXPORT:
torch.onnx._export(model, img, 'weights/model.onnx', verbose=True)
torch.onnx.export(model, img, 'weights/model.onnx', verbose=True)
return # ONNX export
pred = model(img)
pred = pred[pred[:, :, 4] > conf_thres] # remove boxes < threshold
Expand All @@ -70,9 +73,9 @@ def detect(

# Print results to screen
unique_classes = detections[:, -1].cpu().unique()
for i in unique_classes:
n = (detections[:, -1].cpu() == i).sum()
print('%g %ss' % (n, classes[int(i)]), end=', ')
for c in unique_classes:
n = (detections[:, -1].cpu() == c).sum()
print('%g %ss' % (n, classes[int(c)]), end=', ')

# Draw bounding boxes and labels of detections
for x1, y1, x2, y2, conf, cls_conf, cls in detections:
Expand Down
20 changes: 12 additions & 8 deletions models.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ class EmptyLayer(nn.Module):
def __init__(self):
super(EmptyLayer, self).__init__()

def forward(self, x):
return x


class Upsample(nn.Module):
# Custom Upsample layer (nn.Upsample gives deprecated warning message)
Expand Down Expand Up @@ -121,8 +124,8 @@ def __init__(self, anchors, nC, img_dim, anchor_idxs, cfg):

# Build anchor grids
nG = int(self.img_dim / stride) # number grid points
self.grid_x = torch.arange(nG).repeat(nG, 1).view([1, 1, nG, nG]).float()
self.grid_y = torch.arange(nG).repeat(nG, 1).t().view([1, 1, nG, nG]).float()
self.grid_x = torch.arange(nG).repeat((nG, 1)).view((1, 1, nG, nG)).float()
self.grid_y = torch.arange(nG).repeat((nG, 1)).t().view((1, 1, nG, nG)).float()
self.anchor_wh = torch.FloatTensor([(a_w / stride, a_h / stride) for a_w, a_h in anchors]) # scale anchors
self.anchor_w = self.anchor_wh[:, 0].view((1, nA, 1, 1))
self.anchor_h = self.anchor_wh[:, 1].view((1, nA, 1, 1))
Expand Down Expand Up @@ -169,8 +172,8 @@ def forward(self, p, targets=None, var=None):
# Width and height (yolo method)
w = p[..., 2] # Width
h = p[..., 3] # Height
width = torch.exp(w.data) * self.anchor_w
height = torch.exp(h.data) * self.anchor_h
# width = torch.exp(w.data) * self.anchor_w
# height = torch.exp(h.data) * self.anchor_h

# Width and height (power method)
# w = torch.sigmoid(p[..., 2]) # Width
Expand Down Expand Up @@ -217,8 +220,8 @@ def forward(self, p, targets=None, var=None):

# Broadcasting only supported on first dimension in CoreML. See onnx-coreml/_operators.py
# p_cls = F.softmax(p_cls, 2) * p_conf # SSD-like conf
p_cls = torch.exp(p_cls).permute(2, 1, 0)
p_cls = p_cls / p_cls.sum(0).unsqueeze(0) * p_conf.permute(2, 1, 0) # F.softmax() equivalent
p_cls = torch.exp(p_cls).permute((2, 1, 0))
p_cls = p_cls / p_cls.sum(0).unsqueeze(0) * p_conf.permute((2, 1, 0)) # F.softmax() equivalent
p_cls = p_cls.permute(2, 1, 0)

return torch.cat((xy / nG, width_height, p_conf, p_cls), 2).squeeze().t()
Expand Down Expand Up @@ -246,6 +249,7 @@ def __init__(self, cfg_path, img_size=416):
self.hyperparams, self.module_list = create_modules(self.module_defs)
self.img_size = img_size
self.loss_names = ['loss', 'x', 'y', 'w', 'h', 'conf', 'cls', 'nT']
self.losses = []

def forward(self, x, targets=None, var=0):
self.losses = defaultdict(float)
Expand Down Expand Up @@ -296,8 +300,8 @@ def load_darknet_weights(self, weights, cutoff=-1):
if not os.path.isfile(weights):
try:
os.system('wget https://pjreddie.com/media/files/' + weights_file + ' -P ' + weights)
except:
assert os.path.isfile(weights)
except IOError:
print(weights + ' not found')

# Establish cutoffs
if weights_file == 'darknet53.conv.74':
Expand Down
5 changes: 2 additions & 3 deletions train.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ def train(

# Configure run
data_cfg = parse_data_cfg(data_cfg)
num_classes = int(data_cfg['classes'])
train_path = data_cfg['train']

# Initialize model
Expand All @@ -62,7 +61,7 @@ def train(
# p.requires_grad = False

# Set optimizer
optimizer = torch.optim.SGD(filter(lambda p: p.requires_grad, model.parameters()), lr=lr0, momentum=.9)
optimizer = torch.optim.SGD(filter(lambda x: x.requires_grad, model.parameters()), lr=lr0, momentum=.9)

start_epoch = checkpoint['epoch'] + 1
if checkpoint['optimizer'] is not None:
Expand All @@ -85,7 +84,7 @@ def train(
model.to(device).train()

# Set optimizer
optimizer = torch.optim.SGD(filter(lambda p: p.requires_grad, model.parameters()), lr=lr0, momentum=.9)
optimizer = torch.optim.SGD(filter(lambda x: x.requires_grad, model.parameters()), lr=lr0, momentum=.9)

# Set scheduler
# scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[54, 61], gamma=0.1)
Expand Down
3 changes: 1 addition & 2 deletions utils/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ def __len__(self):
class LoadWebcam: # for inference
def __init__(self, img_size=416):
self.cam = cv2.VideoCapture(0)
self.nF = 9999 # number of image files
self.height = img_size

def __iter__(self):
Expand Down Expand Up @@ -88,7 +87,7 @@ def __next__(self):
return img_path, img, img0

def __len__(self):
return self.nF # number of files
return 0


class LoadImagesAndLabels: # for training
Expand Down
208 changes: 0 additions & 208 deletions utils/onnx2coreml.py

This file was deleted.

7 changes: 3 additions & 4 deletions utils/parse_config.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@


def parse_model_config(path):
"""Parses the yolo-v3 layer configuration file and returns module definitions"""
file = open(path, 'r')
lines = file.read().split('\n')
lines = [x for x in lines if x and not x.startswith('#')]
lines = [x.rstrip().lstrip() for x in lines] # get rid of fringe whitespaces
lines = [x.rstrip().lstrip() for x in lines] # get rid of fringe whitespaces
module_defs = []
for line in lines:
if line.startswith('['): # This marks the start of a new block
if line.startswith('['): # This marks the start of a new block
module_defs.append({})
module_defs[-1]['type'] = line[1:-1].rstrip()
if module_defs[-1]['type'] == 'convolutional':
Expand All @@ -20,6 +18,7 @@ def parse_model_config(path):

return module_defs


def parse_data_cfg(path):
"""Parses the data configuration file"""
options = dict()
Expand Down
6 changes: 3 additions & 3 deletions utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ def build_targets(target, anchor_wh, nA, nC, nG):
iou_order = torch.argsort(-iou_best) # best to worst

# Unique anchor selection
u = torch.cat((gi, gj, a), 0).view(3, -1)
u = torch.cat((gi, gj, a), 0).view((3, -1))
_, first_unique = np.unique(u[:, iou_order], axis=1, return_index=True) # first unique indices
# _, first_unique = torch.unique(u[:, iou_order], dim=1, return_inverse=True) # different than numpy?

Expand Down Expand Up @@ -340,7 +340,8 @@ def non_max_suppression(prediction, conf_thres=0.5, nms_thres=0.4):
# x = np.concatenate((log_w.reshape(-1, 1), log_h.reshape(-1, 1)), 1)
# from scipy.stats import multivariate_normal
# for c in range(60):
# shape_likelihood[:, c] = multivariate_normal.pdf(x, mean=mat['class_mu'][c, :2], cov=mat['class_cov'][c, :2, :2])
# shape_likelihood[:, c] =
# multivariate_normal.pdf(x, mean=mat['class_mu'][c, :2], cov=mat['class_cov'][c, :2, :2])

class_prob, class_pred = torch.max(F.softmax(pred[:, 5:], 1), 1)

Expand Down Expand Up @@ -436,7 +437,6 @@ def coco_class_count(path='../coco/labels/train2014/'):
def plot_results():
# Plot YOLO training results file 'results.txt'
import glob
import numpy as np
import matplotlib.pyplot as plt
# import os; os.system('rm -rf results.txt && wget https://storage.googleapis.com/ultralytics/results_v1_0.txt')

Expand Down

0 comments on commit e23b1a3

Please sign in to comment.