Commit be18452d authored by André Anjos's avatar André Anjos 💬
Browse files

Streamline bounding-box and heart-rate saving/loading

parent ce1c62ae
......@@ -68,7 +68,10 @@ def create_meta(args):
(pos, len(objects))
objects = [objects[pos]]
basedir = pkg_resources.resource_filename(__name__, 'data')
if args.selftest:
basedir = pkg_resources.resource_filename(__name__, 'test-data')
else:
basedir = pkg_resources.resource_filename(__name__, 'data')
for obj in objects:
output = obj.make_path(basedir, '.hdf5')
......@@ -77,24 +80,32 @@ def create_meta(args):
continue
try:
print "Creating meta data for `%s'..." % obj.make_path()
max_faces = 0
if args.selftest: max_faces = 2
detections = obj.run_face_detector(args.directory, max_faces)
quality = []
arr = []
for k in sorted(detections.keys()):
det = detections[k]
quality.append(det['quality'])
bb = det['boundingbox']
arr.append([k, bb.topleft[1], bb.topleft[0], bb.size[1], bb.size[0]])
outdir = os.path.dirname(output)
if not os.path.exists(outdir): os.makedirs(outdir)
h5 = bob.io.base.HDF5File(output, 'w')
h5.set('detections', numpy.array(arr))
h5.set_attribute('quality', numpy.array(quality))
h5.set_attribute('heartrate_bpm',
obj.estimate_heartrate_in_bpm(args.directory))
h5.close()
bb = obj.run_face_detector(args.directory, max_frames=1)[0]
hr = obj.estimate_heartrate_in_bpm(args.directory)
if bb and hr:
outdir = os.path.dirname(output)
if not os.path.exists(outdir): os.makedirs(outdir)
h5 = bob.io.base.HDF5File(output, 'w')
h5.create_group('face_detector')
h5.cd('face_detector')
h5.set('topleft_x', bb.topleft.x)
h5.set('topleft_y', bb.topleft.y)
h5.set('width', bb.size.x)
h5.set('height', bb.size.y)
h5.set_attribute('quality', bb.quality)
h5.cd('..')
h5.set('heartrate', hr)
h5.set_attribute('units', 'beats-per-minute', 'heartrate')
h5.close()
else:
print "Skipping `%s': Missing Bounding box and/or Heart-rate" % (obj.stem,)
print " -> Bounding box: %s" % bb
print " -> Heart-rate : %s" % hr
except IOError as e:
print "Skipping `%s': %s" % (obj.stem, str(e))
continue
finally:
if args.selftest:
if os.path.exists(basedir):
......@@ -135,10 +146,7 @@ def debug(args):
print "Creating debug data for `%s'..." % obj.make_path()
try:
detections = obj.load_face_detections()
if detections is None:
detections = obj.run_face_detector(args.directory)
detections = dict([(k, (v.topleft[1], v.topleft[0], v.size[1], v.size[0])) for k,v in detections.items()])
detections = obj.run_face_detector(args.directory)
# save annotated video file
output = obj.make_path(args.output_directory, '.avi')
print "Annotating video `%s'" % output
......@@ -148,6 +156,10 @@ def debug(args):
output = obj.make_path(args.output_directory, '.pdf')
utils.explain_heartrate(obj, args.directory, output)
except IOError as e:
print "Skipping `%s': %s" % (obj.stem, str(e))
continue
finally:
if args.selftest:
if os.path.exists(args.output_directory):
......
......@@ -4,6 +4,7 @@
# Wed 30 Sep 2015 12:13:47 CEST
import os
import collections
import pkg_resources
import bob.io.base
......@@ -12,6 +13,11 @@ import bob.ip.facedetect
from . import utils
# Some utility definitions
Point = collections.namedtuple('Point', 'y,x')
BoundingBox = collections.namedtuple('BoundingBox', 'topleft,size,quality')
class File(object):
""" Generic file container for HCI-Tagging files
......@@ -81,7 +87,7 @@ class File(object):
def run_face_detector(self, directory, max_frames=0):
"""Runs bob.ip.facedetect stock detector on the whole video.
"""Runs bob.ip.facedetect stock detector on the selected frames.
Parameters:
......@@ -96,6 +102,7 @@ class File(object):
dict: A dictionary containing the detected face bounding boxes and
quality information.
"""
detections = {}
......@@ -103,12 +110,12 @@ class File(object):
if max_frames: data = data[:max_frames]
for k, frame in enumerate(data):
bb, quality = bob.ip.facedetect.detect_single_face(frame)
detections[k] = {'boundingbox': bb, 'quality': quality}
detections[k] = BoundingBox(Point(*bb.topleft), Point(*bb.size), quality)
return detections
def load_face_detections(self):
"""Loads face detections from locally stored files if they exist, fails
def load_face_detection(self):
"""Loads the face detection from locally stored files if they exist, fails
gracefully otherwise, returning `None`"""
data_dir = pkg_resources.resource_filename(__name__, 'data')
......@@ -116,8 +123,12 @@ class File(object):
if os.path.exists(path):
f = bob.io.base.HDF5File(path)
data = f.get('detections')
return dict([(k[0], k[1:]) for k in f.get('detections')])
f.cd('face_detector')
return BoundingBox(
Point(f.get('topleft_y'), f.get('topleft_x')),
Point(f.get('height'), f.get('width')),
f.get_attribute('quality'),
)
return None
......@@ -153,7 +164,7 @@ class File(object):
if os.path.exists(path):
f = bob.io.base.HDF5File(path)
return f.get_attribute('heartrate_bpm')
return f.get('heartrate')
return None
......
......@@ -60,9 +60,9 @@ class HCITaggingTest(unittest.TestCase):
@db_available
def test02_can_read_bdf(self):
from .models import bdf_load_signal
from .utils import bdf_load_signal
for obj in self.db.objects()[:10]:
for obj in self.db.objects()[:3]:
path = obj.make_path(DATABASE_LOCATION, '.bdf')
self.assertTrue(os.path.exists(path))
......@@ -93,10 +93,10 @@ class HCITaggingTest(unittest.TestCase):
@meta_available
def test04_can_read_meta(self):
for obj in self.db.objects()[:5]:
for obj in self.db.objects()[:3]:
detections = obj.load_face_detections()
assert len(detections)
detection = obj.load_face_detection()
assert detection
hr = obj.load_heart_rate_in_bpm()
assert hr
......
......@@ -84,6 +84,9 @@ def bdf_load_signal(fn, name='EXG3', start=None, end=None):
import edflib
if not os.path.exists(fn): #or the EdfReader will crash the interpreter
raise IOError("file `%s' does not exist" % fn)
with edflib.EdfReader(fn) as e:
# get the status information, so we how the video is synchronized
......@@ -240,8 +243,7 @@ def annotate_video(video, annotations, output, thickness=3,
bb = annotations.get(k)
if bb is not None:
for t in range(thickness):
bob.ip.draw.box(frame, (bb[1]-t, bb[0]-t),
(bb[3]+2*t, bb[2]+2*t), color)
bob.ip.draw.box(frame, bb.topleft, bb.size, color)
writer.append(frame)
del writer
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment