Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.idea/
build/
data/
__pycache__
output
21 changes: 16 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# High-level Semantic Feature Detection: A New Perspective for Pedestrian Detection
Keras implementation of [CSP] accepted by CVPR 2019.
## Introduction
This paper provides a new perspective for detecting pedestrians where detection is formulated as Center and Scale Prediction (CSP), the pipeline is illustrated in the following. For more details, please refer to our [paper](./docs/2019CVPR-CSP.pdf).
This paper provides a new perspective for detecting pedestrians where detection is formulated as Center and Scale Prediction (CSP), the pipeline is illustrated in the following. For more details, please refer to our [paper](http://openaccess.thecvf.com/content_CVPR_2019/papers/Liu_High-Level_Semantic_Feature_Detection_A_New_Perspective_for_Pedestrian_Detection_CVPR_2019_paper.pdf).
![img01](./docs/pipeline.png)

Besides the superority on pedestrian detection demonstrated in the paper, we take a step further towards the generablity of CSP and validate it on face detection. Experimental reults on WiderFace benchmark also show the competitiveness of CSP.
Expand All @@ -10,10 +10,10 @@ Besides the superority on pedestrian detection demonstrated in the paper, we tak

### Dependencies

* Python 2.7
* Tensorflow 1.4.1
* Keras 2.0.6
* OpenCV 3.4.1.15
* Python >= 3.6
* Tensorflow >= 1.1.3
* Keras >= 2.0.6
* OpenCV >= 3.4.1.15 (note that other versions than 3.4.1.15 will result in different performance on Caltech)

## Contents
1. [Installation](#installation)
Expand All @@ -33,6 +33,17 @@ Besides the superority on pedestrian detection demonstrated in the paper, we tak
pip install -r requirements.txt
```

3. Build dependencies
```
python setup.py build_ext --inplace
```

4. Download pretrained resnet50 weights (basenet only):
```
./download_weights.sh
```


### Preparation
1. Download the dataset.

Expand Down
2 changes: 2 additions & 0 deletions download_weights.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mkdir -p data/models
wget -O ./data/models/resnet50_weights_tf_dim_ordering_tf_kernels.h5 https://github.com/fchollet/deep-learning-models/releases/download/v0.2/resnet50_weights_tf_dim_ordering_tf_kernels.h5 --no-check-certificate
24 changes: 12 additions & 12 deletions eval_city/cocoapi/PythonAPI/pycocotools/coco.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
import sys
PYTHON_VERSION = sys.version_info[0]
if PYTHON_VERSION == 2:
from urllib import urlretrieve
from urllib.request import urlretrieve
elif PYTHON_VERSION == 3:
from urllib.request import urlretrieve

Expand All @@ -83,7 +83,7 @@ def __init__(self, annotation_file=None):
tic = time.time()
dataset = json.load(open(annotation_file, 'r'))
assert type(dataset)==dict, 'annotation file format {} not supported'.format(type(dataset))
print('Done (t={:0.2f}s)'.format(time.time()- tic))
print(('Done (t={:0.2f}s)'.format(time.time()- tic)))
self.dataset = dataset
self.createIndex()

Expand Down Expand Up @@ -123,8 +123,8 @@ def info(self):
Print information about the annotation file.
:return:
"""
for key, value in self.dataset['info'].items():
print('{}: {}'.format(key, value))
for key, value in list(self.dataset['info'].items()):
print(('{}: {}'.format(key, value)))

def getAnnIds(self, imgIds=[], catIds=[], areaRng=[], iscrowd=None):
"""
Expand Down Expand Up @@ -187,7 +187,7 @@ def getImgIds(self, imgIds=[], catIds=[]):
catIds = catIds if _isArrayLike(catIds) else [catIds]

if len(imgIds) == len(catIds) == 0:
ids = self.imgs.keys()
ids = list(self.imgs.keys())
else:
ids = set(imgIds)
for i, catId in enumerate(catIds):
Expand Down Expand Up @@ -292,7 +292,7 @@ def showAnns(self, anns):
ax.add_collection(p)
elif datasetType == 'captions':
for ann in anns:
print(ann['caption'])
print((ann['caption']))

def loadRes(self, resFile):
"""
Expand All @@ -305,7 +305,7 @@ def loadRes(self, resFile):

print('Loading and preparing results...')
tic = time.time()
if type(resFile) == str or type(resFile) == unicode:
if type(resFile) == str or type(resFile) == str:
anns = json.load(open(resFile))
elif type(resFile) == np.ndarray:
anns = self.loadNumpyAnnotations(resFile)
Expand Down Expand Up @@ -349,7 +349,7 @@ def loadRes(self, resFile):
ann['area'] = (x1-x0)*(y1-y0)
ann['id'] = id + 1
ann['bbox'] = [x0,y0,x1-x0,y1-y0]
print('DONE (t={:0.2f}s)'.format(time.time()- tic))
print(('DONE (t={:0.2f}s)'.format(time.time()- tic)))

res.dataset['annotations'] = anns
res.createIndex()
Expand All @@ -366,7 +366,7 @@ def download(self, tarDir = None, imgIds = [] ):
print('Please specify target directory')
return -1
if len(imgIds) == 0:
imgs = self.imgs.values()
imgs = list(self.imgs.values())
else:
imgs = self.loadImgs(imgIds)
N = len(imgs)
Expand All @@ -377,7 +377,7 @@ def download(self, tarDir = None, imgIds = [] ):
fname = os.path.join(tarDir, img['file_name'])
if not os.path.exists(fname):
urlretrieve(img['coco_url'], fname)
print('downloaded {}/{} images (t={:0.1f}s)'.format(i, N, time.time()- tic))
print(('downloaded {}/{} images (t={:0.1f}s)'.format(i, N, time.time()- tic)))

def loadNumpyAnnotations(self, data):
"""
Expand All @@ -387,13 +387,13 @@ def loadNumpyAnnotations(self, data):
"""
print('Converting ndarray to lists...')
assert(type(data) == np.ndarray)
print(data.shape)
print((data.shape))
assert(data.shape[1] == 7)
N = data.shape[0]
ann = []
for i in range(N):
if i % 1000000 == 0:
print('{}/{}'.format(i,N))
print(('{}/{}'.format(i,N)))
ann += [{
'image_id' : int(data[i, 0]),
'bbox' : [ data[i, 1], data[i, 2], data[i, 3], data[i, 4] ],
Expand Down
12 changes: 6 additions & 6 deletions eval_city/cocoapi/PythonAPI/pycocotools/cocoeval.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ def evaluate(self):
# add backward compatibility if useSegm is specified in params
if not p.useSegm is None:
p.iouType = 'segm' if p.useSegm == 1 else 'bbox'
print('useSegm (deprecated) is not None. Running {} evaluation'.format(p.iouType))
print('Evaluate annotation type *{}*'.format(p.iouType))
print(('useSegm (deprecated) is not None. Running {} evaluation'.format(p.iouType)))
print(('Evaluate annotation type *{}*'.format(p.iouType)))
p.imgIds = list(np.unique(p.imgIds))
if p.useCats:
p.catIds = list(np.unique(p.catIds))
Expand Down Expand Up @@ -159,7 +159,7 @@ def evaluate(self):
]
self._paramsEval = copy.deepcopy(self.params)
toc = time.time()
print('DONE (t={:0.2f}s).'.format(toc-tic))
print(('DONE (t={:0.2f}s).'.format(toc-tic)))

def computeIoU(self, imgId, catId):
p = self.params
Expand Down Expand Up @@ -346,7 +346,7 @@ def accumulate(self, p = None):
# get inds to evaluate
k_list = [n for n, k in enumerate(p.catIds) if k in setK]
m_list = [m for n, m in enumerate(p.maxDets) if m in setM]
a_list = [n for n, a in enumerate(map(lambda x: tuple(x), p.areaRng)) if a in setA]
a_list = [n for n, a in enumerate([tuple(x) for x in p.areaRng]) if a in setA]
i_list = [n for n, i in enumerate(p.imgIds) if i in setI]
I0 = len(_pe.imgIds)
A0 = len(_pe.areaRng)
Expand Down Expand Up @@ -418,7 +418,7 @@ def accumulate(self, p = None):
'scores': scores,
}
toc = time.time()
print('DONE (t={:0.2f}s).'.format( toc-tic))
print(('DONE (t={:0.2f}s).'.format( toc-tic)))

def summarize(self):
'''
Expand Down Expand Up @@ -454,7 +454,7 @@ def _summarize( ap=1, iouThr=None, areaRng='all', maxDets=100 ):
mean_s = -1
else:
mean_s = np.mean(s[s>-1])
print(iStr.format(titleStr, typeStr, iouStr, areaRng, maxDets, mean_s))
print((iStr.format(titleStr, typeStr, iouStr, areaRng, maxDets, mean_s)))
return mean_s
def _summarizeDets():
stats = np.zeros((12,))
Expand Down
20 changes: 10 additions & 10 deletions eval_city/eval_script/coco.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
import sys
PYTHON_VERSION = sys.version_info[0]
if PYTHON_VERSION == 2:
from urllib import urlretrieve
from urllib.request import urlretrieve
elif PYTHON_VERSION == 3:
from urllib.request import urlretrieve

Expand Down Expand Up @@ -118,8 +118,8 @@ def info(self):
Print information about the annotation file.
:return:
"""
for key, value in self.dataset['info'].items():
print('{}: {}'.format(key, value))
for key, value in list(self.dataset['info'].items()):
print(('{}: {}'.format(key, value)))

def getAnnIds(self, imgIds=[], catIds=[], areaRng=[], iscrowd=None):
"""
Expand Down Expand Up @@ -182,7 +182,7 @@ def getImgIds(self, imgIds=[], catIds=[]):
catIds = catIds if type(catIds) == list else [catIds]

if len(imgIds) == len(catIds) == 0:
ids = self.imgs.keys()
ids = list(self.imgs.keys())
else:
ids = set(imgIds)
for i, catId in enumerate(catIds):
Expand Down Expand Up @@ -287,7 +287,7 @@ def showAnns(self, anns):
ax.add_collection(p)
elif datasetType == 'captions':
for ann in anns:
print(ann['caption'])
print((ann['caption']))

def loadRes(self, resFile):
"""
Expand All @@ -300,7 +300,7 @@ def loadRes(self, resFile):

# print('Loading and preparing results...')
tic = time.time()
if type(resFile) == str or type(resFile) == unicode:
if type(resFile) == str or type(resFile) == str:
anns = json.load(open(resFile))
elif type(resFile) == np.ndarray:
anns = self.loadNumpyAnnotations(resFile)
Expand Down Expand Up @@ -364,7 +364,7 @@ def download(self, tarDir = None, imgIds = [] ):
print('Please specify target directory')
return -1
if len(imgIds) == 0:
imgs = self.imgs.values()
imgs = list(self.imgs.values())
else:
imgs = self.loadImgs(imgIds)
N = len(imgs)
Expand All @@ -375,7 +375,7 @@ def download(self, tarDir = None, imgIds = [] ):
fname = os.path.join(tarDir, img['file_name'])
if not os.path.exists(fname):
urlretrieve(img['coco_url'], fname)
print('downloaded {}/{} images (t={:0.1f}s)'.format(i, N, time.time()- tic))
print(('downloaded {}/{} images (t={:0.1f}s)'.format(i, N, time.time()- tic)))

def loadNumpyAnnotations(self, data):
"""
Expand All @@ -385,13 +385,13 @@ def loadNumpyAnnotations(self, data):
"""
print('Converting ndarray to lists...')
assert(type(data) == np.ndarray)
print(data.shape)
print((data.shape))
assert(data.shape[1] == 7)
N = data.shape[0]
ann = []
for i in range(N):
if i % 1000000 == 0:
print('{}/{}'.format(i,N))
print(('{}/{}'.format(i,N)))
ann += [{
'image_id' : int(data[i, 0]),
'bbox' : [ data[i, 1], data[i, 2], data[i, 3], data[i, 4] ],
Expand Down
Binary file removed eval_city/eval_script/coco.pyc
Binary file not shown.
4 changes: 2 additions & 2 deletions eval_city/eval_script/eval_MR_multisetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def evaluate(self, id_setup):
# add backward compatibility if useSegm is specified in params
if not p.useSegm is None:
p.iouType = 'segm' if p.useSegm == 1 else 'bbox'
print('useSegm (deprecated) is not None. Running {} evaluation'.format(p.iouType))
print(('useSegm (deprecated) is not None. Running {} evaluation'.format(p.iouType)))
# print('Evaluate annotation type *{}*'.format(p.iouType))
p.imgIds = list(np.unique(p.imgIds))
if p.useCats:
Expand Down Expand Up @@ -446,7 +446,7 @@ def _summarize(iouThr=None, maxDets=100 ):
mean_s = np.log(mrs[mrs<2])
mean_s = np.mean(mean_s)
mean_s = np.exp(mean_s)
print(iStr.format(titleStr, typeStr,setupStr, iouStr, heightStr, occlStr, mean_s*100))
print((iStr.format(titleStr, typeStr,setupStr, iouStr, heightStr, occlStr, mean_s*100)))
# res_file.write(iStr.format(titleStr, typeStr,setupStr, iouStr, heightStr, occlStr, mean_s*100))
res_file.write(str(mean_s * 100))
res_file.write('\n')
Expand Down
Binary file removed eval_city/eval_script/eval_MR_multisetup.pyc
Binary file not shown.
2 changes: 1 addition & 1 deletion eval_city/eval_script/eval_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
annFile = '../val_gt.json'
main_path = '../../output/valresults/city/h/off'
for f in sorted(os.listdir(main_path)):
print f
print(f)
# initialize COCO detections api
dt_path = os.path.join(main_path, f)
resFile = os.path.join(dt_path,'val_dt.json')
Expand Down
79 changes: 40 additions & 39 deletions generate_cache_caltech.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import os
import cPickle
import pickle
import numpy as np
import matplotlib.pyplot as plt

Expand All @@ -18,46 +18,47 @@
box_count = 0
files = sorted(os.listdir(all_anno_path))
for l in range(len(files)):
gtname = files[l]
imgname = files[l].split('.')[0]+'.jpg'
img_path = os.path.join(all_img_path, imgname)
gt_path = os.path.join(all_anno_path, gtname)
gtname = files[l]
imgname = files[l].split('.')[0] + '.jpg'
img_path = os.path.join(all_img_path, imgname)
gt_path = os.path.join(all_anno_path, gtname)

boxes = []
ig_boxes = []
with open(gt_path, 'rb') as fid:
lines = fid.readlines()
if len(lines)>1:
for i in range(1, len(lines)):
info = lines[i].strip().split(' ')
label = info[0]
occ, ignore = info[5], info[10]
x1, y1 = max(int(float(info[1])), 0), max(int(float(info[2])), 0)
w, h = min(int(float(info[3])), cols - x1 - 1), min(int(float(info[4])), rows - y1 - 1)
box = np.array([int(x1), int(y1), int(x1) + int(w), int(y1) + int(h)])
if int(ignore) == 0:
boxes.append(box)
else:
ig_boxes.append(box)
boxes = np.array(boxes)
ig_boxes = np.array(ig_boxes)
boxes = []
ig_boxes = []
with open(gt_path, 'rb') as fid:
lines = fid.readlines()
if len(lines) > 1:
for i in range(1, len(lines)):
info = lines[i].strip().split(' ')
label = info[0]
occ, ignore = info[5], info[10]
x1, y1 = max(int(float(info[1])), 0), max(int(float(info[2])), 0)
w, h = min(int(float(info[3])), cols - x1 - 1), min(int(float(info[4])), rows - y1 - 1)
box = np.array([int(x1), int(y1), int(x1) + int(w), int(y1) + int(h)])
if int(ignore) == 0:
boxes.append(box)
else:
ig_boxes.append(box)
boxes = np.array(boxes)
ig_boxes = np.array(ig_boxes)

annotation = {}
annotation['filepath'] = img_path
box_count += len(boxes)
iggt_count += len(ig_boxes)
annotation['bboxes'] = boxes
annotation['ignoreareas'] = ig_boxes
if len(boxes) == 0:
image_data_nogt.append(annotation)
else:
image_data_gt.append(annotation)
valid_count += 1
print '{} images and {} valid images, {} valid gt and {} ignored gt'.format(len(files), valid_count, box_count, iggt_count)
annotation = {}
annotation['filepath'] = img_path
box_count += len(boxes)
iggt_count += len(ig_boxes)
annotation['bboxes'] = boxes
annotation['ignoreareas'] = ig_boxes
if len(boxes) == 0:
image_data_nogt.append(annotation)
else:
image_data_gt.append(annotation)
valid_count += 1
print('{} images and {} valid images, {} valid gt and {} ignored gt'.format(len(files), valid_count, box_count,
iggt_count))

if not os.path.exists(res_path_gt):
with open(res_path_gt, 'wb') as fid:
cPickle.dump(image_data_gt, fid, cPickle.HIGHEST_PROTOCOL)
with open(res_path_gt, 'wb') as fid:
pickle.dump(image_data_gt, fid, pickle.HIGHEST_PROTOCOL)
if not os.path.exists(res_path_nogt):
with open(res_path_nogt, 'wb') as fid:
cPickle.dump(image_data_nogt, fid, cPickle.HIGHEST_PROTOCOL)
with open(res_path_nogt, 'wb') as fid:
pickle.dump(image_data_nogt, fid, pickle.HIGHEST_PROTOCOL)
Loading