
def read_annotation_file(annotation_file, annotation_type):
  """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)}]``.
  """
  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
