Source code for bob.ip.facedetect.train.annotations


[docs]def read_annotation_file(annotation_file, annotation_type): """read_annotation_file(annotation_file, annotation_type) -> annotations Reads annotations from the given ``annotation_file``. The way, how annotations are read depends on the given ``annotation_type``. Depending on the type, one or several annotations might be present in the annotation file. Currently, these variants are implemented: - ``'lr-eyes'``: Only the eye positions are stored, in a single row, like: ``le_x le_y re_x re_y``, comment lines starting with ``'#'`` are ignored. - ``'named'``: Each line of the file contains a name and two floats, like ``reye x y``; empty lines separate between sets of annotations. - ``'idiap'``: A special 22 point format, where each line contains the index and the locations, like ``1 x y``. - ``'fddb'``: a special format for the FDDB database; empty lines separate between sets of annotations Finally, a list of ``annotations`` is returned in the format: ``[{name: (y,x)}]``. **Parameters:** ``annotation_file`` : str The file name of the annotation file to read ``annotation_type`` : str (see above) The style of annotation file, in which the given ``annotation_file`` is **Returns:** ``annotations`` : [dict] A list of annotations read from the given file, grouped by annotated objects (faces). Each annotation is generally specified as the two eye coordinates, i.e., ``{'reye' : (rey, rex), 'leye' : (ley, lex)}``, but other types of annotations might occur as well. """ annotations = [{}] with open(annotation_file) as f: if annotation_type == 'idiap': # This is a special format where we have enumerated annotations, and a 'gender' for line in f: positions = line.rstrip().split() if positions: if positions[0].isdigit(): # position field assert len(positions) == 3 id = int(positions[0]) annotations[-1]['key%d'%id] = (float(positions[2]),float(positions[1])) else: # another field, we take the first entry as key and the rest as values annotations[-1][positions[0]] = positions[1:] elif len(annotations[-1]) > 0: # empty line; split between annotations annotations.append({}) # finally, we add the eye center coordinates as the center between the eye corners; the annotations 3 and 8 seem to be the pupils... for annotation in annotations: if 'key1' in annotation and 'key5' in annotation: annotation['reye'] = ((annotation['key1'][0] + annotation['key5'][0])/2., (annotation['key1'][1] + annotation['key5'][1])/2.) if 'key6' in annotation and 'key10' in annotation: annotation['leye'] = ((annotation['key6'][0] + annotation['key10'][0])/2., (annotation['key6'][1] + annotation['key10'][1])/2.) elif annotation_type == 'lr-eyes': # In this format, the eyes are given in a single row "le_x le_y re_x re_y", possibly with a comment line # There is only a single annotation per image for line in f: if len(line) and line[0] != '#': positions = line.rstrip().split() annotations[0]['leye'] = (float(positions[1]),float(positions[0])) annotations[0]['reye'] = (float(positions[3]),float(positions[2])) elif annotation_type == 'named': # In this format, each line contains three entries: "keyword x y" for line in f: positions = line.rstrip().split() if positions: annotations[-1][positions[0]] = (float(positions[2]),float(positions[1])) elif len(annotations[-1]) > 0: # empty line; split between annotations annotations.append({}) elif annotation_type == 'fddb': # This is a special format for the FDDB database for line in f: positions = line.rstrip().split() if not len(positions): if len(annotations[-1]) > 0: # empty line; split between annotations annotations.append({}) elif len(positions) == 2: annotations[-1][positions[0]] = float(positions[1]) elif len(positions) == 3: annotations[-1][positions[0]] = (float(positions[2]),float(positions[1])) else: raise ValueError("Could not interpret line %s of the annotation file" % line) else: raise ValueError("The given annotation type %s is not known" % annotation_type) if not annotations[-1]: del annotations[-1] return annotations