2013-01-16 22:21:47 +08:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
import cv2, re, glob
|
2013-01-18 00:36:39 +08:00
|
|
|
import numpy as np
|
2013-01-18 16:22:03 +08:00
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
|
|
|
def plot_curve():
|
|
|
|
|
|
|
|
fig, ax = plt.subplots()
|
|
|
|
fig.canvas.draw()
|
|
|
|
|
|
|
|
x = np.linspace(pow(10,-4), pow(10,1), 101)
|
|
|
|
y = 1 - x
|
|
|
|
|
|
|
|
plt.semilogy(x,y,color='m',linewidth=2)
|
|
|
|
plt.xlabel("fppi")
|
|
|
|
plt.ylabel("miss rate")
|
|
|
|
plt.title("ROC curve Bahnhof")
|
|
|
|
|
|
|
|
plt.yticks( [0.05, 0.10, 0.20, 0.30, 0.40, 0.50, 0.64, 0.80])
|
|
|
|
ylabels = [item.get_text() for item in ax.get_yticklabels()]
|
|
|
|
ax.set_yticklabels( ylabels )
|
|
|
|
plt.grid(True)
|
|
|
|
|
|
|
|
# plt.xticks( [pow(10, -4), pow(10, -3), pow(10, -2), pow(10, -1), pow(10, 0), pow(10, 0)])
|
|
|
|
# xlabels = [item.get_text() for item in ax.get_xticklabels()]
|
|
|
|
# ax.set_xticklabels( xlabels )
|
|
|
|
|
|
|
|
plt.xscale('log')
|
|
|
|
plt.show()
|
|
|
|
|
2013-01-20 01:25:09 +08:00
|
|
|
def crop_rect(rect, factor):
|
|
|
|
val_x = factor * float(rect[2])
|
|
|
|
val_y = factor * float(rect[3])
|
|
|
|
x = [int(rect[0] + val_x), int(rect[1] + val_y), int(rect[2] - 2.0 * val_x), int(rect[3] - 2.0 * val_y)]
|
|
|
|
return x
|
2013-01-16 22:21:47 +08:00
|
|
|
|
|
|
|
def draw_rects(img, rects, color, l = lambda x, y : x + y):
|
|
|
|
if rects is not None:
|
|
|
|
for x1, y1, x2, y2 in rects:
|
|
|
|
cv2.rectangle(img, (x1, y1), (l(x1, x2), l(y1, y2)), color, 2)
|
|
|
|
|
2013-01-20 01:25:09 +08:00
|
|
|
def draw_dt(img, dts, color, l = lambda x, y : x + y):
|
|
|
|
if dts is not None:
|
|
|
|
for dt in dts:
|
|
|
|
bb = dt.bb
|
|
|
|
x1, y1, x2, y2 = dt.bb[0], dt.bb[1], dt.bb[2], dt.bb[3]
|
|
|
|
|
|
|
|
cv2.rectangle(img, (x1, y1), (l(x1, x2), l(y1, y2)), color, 2)
|
|
|
|
|
2013-01-18 16:22:03 +08:00
|
|
|
class Annotation:
|
|
|
|
def __init__(self, bb):
|
|
|
|
self.bb = bb
|
2013-01-16 22:21:47 +08:00
|
|
|
|
2013-01-18 00:36:39 +08:00
|
|
|
class Detection:
|
|
|
|
def __init__(self, bb, conf):
|
|
|
|
self.bb = bb
|
|
|
|
self.conf = conf
|
2013-01-18 16:22:03 +08:00
|
|
|
self.matched = False
|
|
|
|
|
|
|
|
# def crop(self):
|
|
|
|
# rel_scale = self.bb[1] / 128
|
|
|
|
|
2013-01-20 01:25:09 +08:00
|
|
|
def crop(self, factor):
|
|
|
|
print "was", self.bb
|
|
|
|
self.bb = crop_rect(self.bb, factor)
|
|
|
|
print "bec", self.bb
|
2013-01-18 00:36:39 +08:00
|
|
|
|
|
|
|
# we use rect-stype for dt and box style for gt. ToDo: fix it
|
|
|
|
def overlap(self, b):
|
|
|
|
a = self.bb
|
2013-01-18 16:22:03 +08:00
|
|
|
w = min( a[0] + a[2], b[2]) - max(a[0], b[0]);
|
|
|
|
h = min( a[1] + a[3], b[3]) - max(a[1], b[1]);
|
2013-01-18 00:36:39 +08:00
|
|
|
|
|
|
|
cross_area = 0.0 if (w < 0 or h < 0) else float(w * h)
|
|
|
|
union_area = (a[2] * a[3]) + ((b[2] - b[0]) * (b[3] - b[1])) - cross_area;
|
|
|
|
|
2013-01-18 16:22:03 +08:00
|
|
|
return cross_area / union_area
|
|
|
|
|
|
|
|
def mark_matched(self):
|
|
|
|
self.matched = True
|
2013-01-18 00:36:39 +08:00
|
|
|
|
|
|
|
|
2013-01-16 22:21:47 +08:00
|
|
|
def parse_inria(ipath, f):
|
|
|
|
bbs = []
|
|
|
|
path = None
|
|
|
|
for l in f:
|
|
|
|
box = None
|
|
|
|
if l.startswith("Bounding box"):
|
|
|
|
b = [x.strip() for x in l.split(":")[1].split("-")]
|
|
|
|
c = [x[1:-1].split(",") for x in b]
|
|
|
|
d = [int(x) for x in sum(c, [])]
|
|
|
|
bbs.append(d)
|
|
|
|
|
|
|
|
if l.startswith("Image filename"):
|
|
|
|
path = l.split('"')[-2]
|
|
|
|
|
|
|
|
return Sample(path, bbs)
|
|
|
|
|
|
|
|
def glob_set(pattern):
|
|
|
|
return [__n for __n in glob.iglob(pattern)] #glob.iglob(pattern)
|
|
|
|
|
|
|
|
# parse ETH idl file
|
|
|
|
def parse_idl(f):
|
|
|
|
map = {}
|
|
|
|
for l in open(f):
|
|
|
|
l = re.sub(r"^\"left\/", "{\"", l)
|
|
|
|
l = re.sub(r"\:", ":[", l)
|
|
|
|
l = re.sub(r"(\;|\.)$", "]}", l)
|
|
|
|
map.update(eval(l))
|
2013-01-18 00:36:39 +08:00
|
|
|
return map
|
|
|
|
|
2013-01-20 01:25:09 +08:00
|
|
|
def norm_box(box, ratio):
|
|
|
|
middle = float(box[0] + box[2]) / 2.0
|
|
|
|
new_half_width = float(box[3] - box[1]) * ratio / 2.0
|
|
|
|
return (int(round(middle - new_half_width)), box[1], int(round(middle + new_half_width)), box[3])
|
|
|
|
|
|
|
|
|
|
|
|
def norm_acpect_ratio(boxes, ratio):
|
|
|
|
return [ norm_box(box, ratio) for box in boxes]
|
|
|
|
|
|
|
|
|
2013-01-18 00:36:39 +08:00
|
|
|
def match(gts, rects, confs):
|
|
|
|
if rects is None:
|
|
|
|
return 0
|
|
|
|
|
2013-01-18 16:22:03 +08:00
|
|
|
fp = 0
|
|
|
|
fn = 0
|
|
|
|
|
2013-01-18 00:36:39 +08:00
|
|
|
dts = zip(*[rects.tolist(), confs.tolist()])
|
|
|
|
dts = zip(dts[0][0], dts[0][1])
|
|
|
|
dts = [Detection(r,c) for r, c in dts]
|
|
|
|
|
2013-01-20 01:25:09 +08:00
|
|
|
factor = 1.0 / 8.0
|
|
|
|
dt_old = dts
|
|
|
|
for dt in dts:
|
|
|
|
dt.crop(factor)
|
|
|
|
|
2013-01-18 16:22:03 +08:00
|
|
|
for gt in gts:
|
|
|
|
|
|
|
|
# exclude small
|
|
|
|
if gt[2] - gt[0] < 27:
|
|
|
|
continue
|
|
|
|
|
|
|
|
matched = False
|
|
|
|
|
|
|
|
for dt in dts:
|
|
|
|
# dt.crop()
|
2013-01-18 00:36:39 +08:00
|
|
|
overlap = dt.overlap(gt)
|
2013-01-18 16:22:03 +08:00
|
|
|
print dt.bb, "vs", gt, overlap
|
|
|
|
if overlap > 0.5:
|
|
|
|
dt.mark_matched()
|
|
|
|
matched = True
|
|
|
|
print "matched ", dt.bb, gt
|
|
|
|
|
|
|
|
if not matched:
|
|
|
|
fn = fn + 1
|
|
|
|
|
|
|
|
print "fn", fn
|
|
|
|
|
|
|
|
for dt in dts:
|
|
|
|
if not dt.matched:
|
|
|
|
fp = fp + 1
|
|
|
|
|
|
|
|
print "fp", fp
|
2013-01-20 01:25:09 +08:00
|
|
|
return dt_old
|