提交 c1189b8b 编写于 作者: R Ross Girshick

move voc evaluation code into pascal_voc dataset class

上级 7c149dbc
......@@ -52,3 +52,14 @@ class imdb(object):
def default_roidb(self):
raise NotImplementedError
def evaluate_detections(self, all_boxes):
"""
all_boxes is a list of length number-of-classes.
Each list element is a list of length number-of-images.
Each of those list elements is either an empty list []
or a numpy array of detection.
all_boxes[class][image] = [] or np.array of shape #dets x 5
"""
raise NotImplementedError
......@@ -8,12 +8,7 @@ import scipy.sparse
import scipy.io as sio
import utils.cython_bbox
import cPickle
# Not bothering with image size for now
# can use:
# sizes =
# [PIL.Image.open(d.image_path_at(i)).size
# for i in xrange(0, len(d.image_index))]
import subprocess
class pascal_voc(datasets.imdb):
def __init__(self, image_set, year, devkit_path=None):
......@@ -35,6 +30,9 @@ class pascal_voc(datasets.imdb):
# Default to roidb handler
self._roidb_handler = self.selective_search_roidb
assert os.path.exists(self._devkit_path)
assert os.path.exists(self._base_path)
def image_path_at(self, i):
"""
Return the absolute path to image i in the image sequence.
......@@ -70,7 +68,6 @@ class pascal_voc(datasets.imdb):
path = os.path.abspath(os.path.join(
os.path.dirname(__file__),
'..', 'datasets', 'VOCdevkit' + self._year))
assert os.path.exists(path)
return path
def gt_roidb(self):
......@@ -197,6 +194,43 @@ class pascal_voc(datasets.imdb):
'gt_classes': gt_classes,
'gt_overlaps' : overlaps}
def _write_voc_results_file(self, all_boxes):
pid = os.getpid()
# VOCdevkit/results/VOC2007/Main/comp4-44503_det_test_aeroplane.txt
path = os.path.join(self._devkit_path, 'results', 'VOC' + self._year,
'Main', 'comp4-{}_'.format(pid))
for cls_ind, cls in enumerate(self.classes):
if cls == '__background__':
continue
print 'Writing {} VOC results file'.format(cls)
filename = path + 'det_test_' + cls + '.txt'
with open(filename, 'wt') as f:
for im_ind, index in enumerate(self.image_index):
dets = all_boxes[cls_ind][im_ind]
if dets == []:
continue
# the VOCdevkit expects 1-based indices
dets[:, :4] += 1
for k in xrange(dets.shape[0]):
f.write('{:s} {:.3f} {:.1f} {:.1f} {:.1f} {:.1f}\n'.
format(index, dets[k, -1],
dets[k, 0], dets[k, 1],
dets[k, 2], dets[k, 3]))
return pid
def _do_matlab_eval(self, pid, rm_results=True):
path = os.path.join(os.path.dirname(__file__),
'VOCdevkit-matlab-wrapper')
cmd = 'cd {} && '.format(path)
cmd += 'matlab -nodisplay -nodesktop '
cmd += '-r "voc_eval(\'{:s}\', {:d}, {:d}); quit;"' \
.format(self._devkit_path, pid, int(rm_results))
status = subprocess.call(cmd, shell=True)
def evaluate_detections(self, all_boxes):
pid = self._write_voc_results_file(all_boxes)
self._do_matlab_eval(pid)
if __name__ == '__main__':
d = datasets.pascal_voc('trainval', '2007')
res = d.roidb
......
import os
import sys
caffe_path = os.path.abspath(os.path.join('..', 'caffe', 'python'))
sys.path.insert(0, caffe_path)
import numpy as np
# Scales used in the SPP-net paper
......@@ -29,3 +34,4 @@ SNAPSHOT_ITERS = 10000
TEST_SCALES = (600,)
TEST_MAX_SIZE = 1000
TEST_NMS = 0.3
#!/usr/bin/env python
import sys
import subprocess
import os
caffe_path = '../caffe/python'
sys.path.insert(0, caffe_path)
import fast_rcnn_config as conf
import argparse
from utils.timer import Timer
......@@ -12,9 +8,7 @@ import numpy as np
import matplotlib.pyplot as plt
import cv2
import caffe
import fast_rcnn_config as conf
import utils.cython_nms
import datasets.pascal_voc
import cPickle
import heapq
......@@ -122,9 +116,9 @@ def _clip_boxes(boxes, im_shape):
return boxes
def im_detect(net, im, boxes):
# TODO: remove duplicates
blobs, im_scale_factors = _get_blobs(im, boxes)
# TODO: remove duplicates
# v = np.array([1, 1e3, 1e6, 1e9, 1e12])
# hashes = blobs['rois'][:, :, 0, 0].dot(v.T)
hashes = (blobs['rois'][:, :, 0, 0] *
......@@ -187,40 +181,23 @@ def _vis_detections(im, class_name, dets):
plt.title('{} {:.3f}'.format(class_name, score))
plt.pause(0.5)
def _write_voc_results_file(imdb, all_boxes):
pid = os.getpid()
#/data/VOC2007/VOCdevkit/results/VOC2007/Main/comp4-44503_det_test_aeroplane.txt
base_path = './datasets/VOCdevkit2007/results/VOC2007/Main/comp4-{}_'.format(pid)
for cls_ind, cls in enumerate(imdb.classes):
if cls == '__background__':
continue
file_name = base_path + 'det_test_' + cls + '.txt'
with open(file_name, 'wt') as f:
for im_ind, index in enumerate(imdb.image_index):
dets = all_boxes[cls_ind][im_ind]
if dets == []:
continue
keep = utils.cython_nms.nms(dets, 0.3)
if len(keep) == 0:
continue
dets = dets[keep, :]
# the VOCdevkit expects 1-based indices
dets[:, :4] += 1
for k in xrange(dets.shape[0]):
f.write('{:s} {:.3f} {:.1f} {:.1f} {:.1f} {:.1f}\n'.format(
index, dets[k, -1], dets[k, 0], dets[k, 1],
dets[k, 2], dets[k, 3]))
print 'Evaluate comp4-{}'.format(pid)
return pid
def _do_matlab_eval(pid):
cmd = 'cd ../rcnn && '
cmd += 'matlab -nodisplay -nodesktop '
cmd += '-r "load imdb/cache/imdb_voc_2007_test.mat; '
cmd += 'imdb_eval_voc_py(imdb, {}); quit;"'.format(pid)
status = subprocess.call(cmd, shell=True)
def fast_rcnn_test(net, imdb):
def _apply_nms(all_boxes, thresh):
num_classes = len(all_boxes)
num_images = len(all_boxes[0])
nms_boxes = [[[] for _ in xrange(num_images)]
for _ in xrange(num_classes)]
for cls_ind in xrange(num_classes):
for im_ind in xrange(num_images):
dets = all_boxes[cls_ind][im_ind]
if dets == []:
continue
keep = utils.cython_nms.nms(dets, thresh)
if len(keep) == 0:
continue
nms_boxes[cls_ind][im_ind] = dets[keep, :].copy()
return nms_boxes
def test_net(net, imdb):
num_images = len(imdb.image_index)
# heuristic: keep an average of 40 detections per class per images prior
# to NMS
......@@ -289,22 +266,8 @@ def fast_rcnn_test(net, imdb):
with open('dets.pkl', 'wb') as f:
cPickle.dump(all_boxes, f, cPickle.HIGHEST_PROTOCOL)
pid = _write_voc_results_file(imdb, all_boxes)
_do_matlab_eval(pid)
# Write results file and call matlab to evaluate
if __name__ == '__main__':
prototxt = 'model-defs/vgg16_pyramid_forward_only_bbox_reg.prototxt'
caffemodel = '/home/rbg/working/pyramid-rcnn/fast-rcnn/snapshots/vgg16_finetune_all_joint_bbox_reg_smoothL1_roidb2_iter_40000.caffemodel'
caffe.set_phase_test()
caffe.set_mode_gpu()
GPU_ID = 2
if GPU_ID is not None:
caffe.set_device(GPU_ID)
net = caffe.Net(prototxt, caffemodel)
print 'Applying NMS to all detections'
nms_dets = _apply_nms(all_boxes, conf.TEST_NMS)
import datasets.pascal_voc
imdb = datasets.pascal_voc('test', '2007')
fast_rcnn_test(net, imdb)
print 'Evaluating detections'
imdb.evaluate_detections(nms_dets)
#!/usr/bin/env python
import sys
caffe_path = '../caffe/python'
sys.path.insert(0, caffe_path)
import fast_rcnn_config as conf
import argparse
import time
import numpy as np
......@@ -11,7 +8,6 @@ import matplotlib.pyplot as plt
import cv2
import caffe
import finetuning
import fast_rcnn_config as conf
import datasets.pascal_voc
import bbox_regression_targets
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册