示例#1
0
 def copyAnnotation(self, token, name):
     """ copy an annotation with a given name from a given token """
     if token.hasAnnotation(name) == True and self.hasAnnotation(name) == False:
         annotation = token.annotations.get(name)
         newAnnotation = Annotation(name)
         newAnnotation.copy(annotation)
         self.annotations.add(newAnnotation)
示例#2
0
 def query_article(self, article):
     escaped = self.escape_sparql(article)
     ret = []
     query = """
     SELECT DISTINCT ?author ?author_fullname ?author_email
      ?date ?label ?type ?body_s ?body_p ?body_o ?body_l
      ?target_start ?target_startoffset ?target_endoffset
     WHERE {
         ?annotation rdf:type oa:Annotation ;
             oa:annotatedAt ?date ;
             oa:annotatedBy ?author .
         OPTIONAL { ?author foaf:name ?author_fullname }
         OPTIONAL { ?author schema:email ?author_email }
         OPTIONAL { ?annotation rdfs:label ?label }
         OPTIONAL { ?annotation ao:type ?type }
         OPTIONAL { ?annotation oa:hasBody ?body }
         OPTIONAL { ?body rdf:subject ?body_s }
         OPTIONAL { ?body rdf:predicate ?body_p }
         OPTIONAL { ?body rdf:object ?body_o }
         OPTIONAL { ?body rdfs:label ?body_l }
         { ?annotation oa:hasTarget ao:""" + escaped + """ }
          UNION
         { ?annotation oa:hasTarget ?bnode .
           ?bnode rdf:type oa:SpecificResource ;
                 oa:hasSource ao:""" + escaped + """ ;
                 oa:hasSelector ?selector .
           ?selector rdf:type oa:FragmentSelector ;
                 rdf:value ?target_start ;
                 oa:start ?target_startoffset ;
                 oa:end ?target_endoffset }
     }
     """
     for row in self.sparql.query(query, initNs=initNS):
         annotation = Annotation()
         annotation.parse_rdf({
             'target': article,
             'author': row[0].encode('utf-8'),
             'author_fullname': row[1].encode('utf-8') if row[1] is not None else None,
             'author_email': row[2].encode('utf-8') if row[2] is not None else None,
             'created': row[3].encode('utf-8') if row[3] is not None else None,
             'label': row[4].encode('utf-8') if row[4] is not None else None,
             'type': row[5].encode('utf-8') if row[5] is not None else None,
             'subject': row[6].encode('utf-8') if row[6] is not None else None,
             'predicate': row[7].encode('utf-8') if row[7] is not None else None,
             'object': row[8].encode('utf-8') if row[8] is not None else None,
             'obj_label': row[9].encode('utf-8') if row[9] is not None else None,
             'target_start': row[10].encode('utf-8') if row[10] is not None else None,
             'target_startoff': int(row[11]) if row[11] is not None else None,
             'target_endoff': int(row[12]) if row[12] is not None else None
         })
         ret.append(annotation.to_dict())
     return ret
示例#3
0
 def __init__(self, name, pnts, channels, scatters=None, notes=None):
     """
     fcmdata(name, pnts, channels, scatters=None)
     name: name of corresponding FCS file minus extension
     pnts: array of data points
     channels: a list of which markers/scatters are on which column of
                 the array.
     scatters: a list of which indexes in channels are scatters
     
     """
     self.name = name
     #        if type(pnts) != type(array([])):
     #            raise BadFCMPointDataTypeError(pnts, "pnts isn't a numpy.array")
     self.tree = Tree(pnts, channels)
     #self.pnts = pnts
     #self.channels = channels
     #TODO add some default intelegence for determining scatters if None
     self.scatters = scatters
     self.markers = []
     if self.scatters is not None:
         for chan in range(len(channels)):
             if chan in self.scatters:
                 pass
             elif self.tree.root.channels[chan] in self.scatters:
                 pass
             else:
                 self.markers.append(chan)
     if notes == None:
         notes = Annotation()
     self.notes = notes
    def loadLabels(self):
        filename = self.getLabelFilename()
        if not filename:
            self.clearAnnotation()
            return

        # If we have everything and the filename did not change, then we are good
        if self.annotation and filename == self.currentLabelFile:
            return

        # Clear the current labels first
        self.clearAnnotation()

        try:
            self.annotation = Annotation(self.gtType)
            self.annotation.fromJsonFile(filename)
        except IOError as e:
            # This is the error if the file does not exist
            message = "Error parsing labels in {0}. Message: {1}".format( filename, e.strerror )
            self.statusBar().showMessage(message)

        # Remember the filename loaded
        self.currentLabelFile = filename

        # Remeber the status bar message to restore it later
        restoreMessage = self.statusBar().currentMessage()

        # Restore the message
        self.statusBar().showMessage( restoreMessage )
示例#5
0
def object_hook(d):
    """
    Usage
    -----
    >>> import simplejson as json
    >>> with open('file.json', 'r') as f:
    ...   json.load(f, object_hook=object_hook)
    """

    from segment import Segment
    from timeline import Timeline
    from annotation import Annotation
    from transcription import Transcription

    if PYANNOTE_JSON_SEGMENT in d:
        return Segment.from_json(d)

    if PYANNOTE_JSON_TIMELINE in d:
        return Timeline.from_json(d)

    if PYANNOTE_JSON_ANNOTATION in d:
        return Annotation.from_json(d)

    if PYANNOTE_JSON_TRANSCRIPTION in d:
        return Transcription.from_json(d)

    return d
示例#6
0
def object_hook(d):
    """
    Usage
    -----
    >>> import simplejson as json
    >>> with open('file.json', 'r') as f:
    ...   json.load(f, object_hook=object_hook)
    """

    from segment import Segment
    from timeline import Timeline
    from annotation import Annotation
    from transcription import Transcription

    if PYANNOTE_JSON_SEGMENT in d:
        return Segment.from_json(d)

    if PYANNOTE_JSON_TIMELINE in d:
        return Timeline.from_json(d)

    if PYANNOTE_JSON_ANNOTATION in d:
        return Annotation.from_json(d)

    if PYANNOTE_JSON_TRANSCRIPTION in d:
        return Transcription.from_json(d)

    return d
示例#7
0
def geneNormalization(documents):
    print("Gene Normalization:", file=sys.stderr)
    for document in tqdm.tqdm(documents):
        ids_by_pmid = getGeneByPMID(document['id'])
        for passage in document['passages']:
            for ann in passage['annotations']:
                ids_by_mention = getGeneByMention(ann['text'])
                flag = False
                for id_by_mention in ids_by_mention:
                    if id_by_mention in ids_by_pmid:
                        flag = True
                        Annotation.setNCBIID(ann, id_by_mention)
                        break
                if not flag:
                    Annotation.setNCBIID(
                        ann, ids_by_mention[0]
                        if len(ids_by_mention) > 0 else 'TBD')
示例#8
0
    def __init__(self, dandelion_raw_list):
        self.dandelion_raw_list = dandelion_raw_list
        self.good_annotations = []

        if self.dandelion_raw_list:
            for annotation_dict in self.dandelion_raw_list.get(
                    "annotations", []):
                my_annotation = Annotation(annotation_dict)

                if not my_annotation.suppress:
                    for top_entity in self.dandelion_raw_list.get(
                            "topEntities", []):
                        if my_annotation.uri == top_entity["uri"]:
                            my_annotation.is_top_entity = True
                            my_annotation.top_entity_score = top_entity[
                                "score"]
                    self.good_annotations.append(my_annotation)
 def serialize(dic):
     if 'annotations' in dic:
         annotations = []
         for ann in dic['annotations']:
             annotations.append(Annotation.serialize(ann))
         return AnnotateResponse(annotations)
     else:
         return dic
示例#10
0
 def _preload_annotations(self):
     annotation_dir = self._annotation_dir
     jsons = [
         f for f in os.listdir(annotation_dir) if splitext(f)[1] == ".json"
     ]
     self._annotations = {
         splitext(f)[0]: Annotation.load(os.path.join(annotation_dir, f))
         for f in jsons
     }
示例#11
0
def loclabel_gen(ano_path, loc_path, out_path):
    pids = list(map(lambda x: x.strip('.json'), os.listdir(ano_path)))

    annotations = {}
    for pid in pids:
        pid_json_path = os.path.join(ano_path, pid + '.json')
        anno = Annotation()
        anno.from_json(pid_json_path)
        annotations[pid] = anno

    coords = []
    infile = open(loc_path)
    for i, line in enumerate(infile):
        pid, x_center, y_center = line.strip('\n').split(',')
        coords.append((pid, x_center, y_center))
    infile.close()

    num_sample = len(coords)
    print(f"{out_path} Total sample: {num_sample}")

    outfile = open(out_path,'w')
    for index in range(num_sample):
        pid, x_center, y_center = coords[index]
        x_center = int(x_center)
        y_center = int(y_center)

        x_top_left = int(x_center - IMG_SIZE / 2)
        y_top_left = int(y_center - IMG_SIZE / 2)

        label=[]
        for x_idx in range(3):
            for y_idx in range(3):
                # (x, y) is the center of each patch
                x = x_top_left + int((x_idx + 0.5) * SUB_SIZE)
                y = y_top_left + int((y_idx + 0.5) * SUB_SIZE)
                # get label information according to annotation
                if annotations[pid].inside_polygons((x, y), True):
                    label.append(1)
                else:
                    label.append(0)
                # write output
        outfile.write(f"{pid.lower()}, {x_center}, {y_center}, {str(label)[1:-1]}\n")
    outfile.close()
示例#12
0
def get_annotations():
    user_map = get_user_map()
    assignments = get_assignments(user_map)

    annotations = {
        video: Annotation(assignment, video)
        for video, assignment in assignments.items()
    }

    return annotations
示例#13
0
    def targets(self, field, keypoint_sets):
        assert self.keypoints is not None
        assert self.skeleton is not None

        annotations = [
            Annotation(keypoints=self.keypoints, skeleton=self.skeleton).set(kps, fixed_score=None)
            for kps in keypoint_sets
        ]

        self._confidences(field[0])
        self._regressions(field[1], field[2], field[3], field[4], annotations=annotations)
示例#14
0
    def parse_json(self, filename: str, classes: list) -> List[Annotation]:
        with open(filename, 'r') as json_file:
            json_data = json.load(json_file)
            images = json_data["images"]
            categories = json_data["categories"]
            annotations = []
            for anno in json_data["annotations"]:
                image_id = anno["image_id"]
                cls_id = anno["category_id"]

                for info in images:
                    if info["id"] == image_id:
                        annotation = Annotation(
                            info["file_name"].split(".")[0])
                        annotation.image_size()
                for category in categories:
                    if category["id"] == cls_id:
                        annotation.class_id = category["name"]
                bndbox = {
                    "xmin": anno["bbox"][0],
                    "ymin": anno["bbox"][1],
                    "xmax": anno["bbox"][2] + anno["bbox"][0],
                    "ymax": anno["bbox"][3] + anno["bbox"][1]
                }
                annotation.bbox = (bndbox["xmin"], bndbox["ymin"],
                                   bndbox["xmax"], bndbox["ymax"])
                annotations.append(annotation)
            return annotations
def dict_to_tf_examples(data):
    global DATA_DIR

    img_name = os.path.join(data['name'] + 'leftImg8bit.png')
    img_path = os.path.join(DATA_DIR, 'leftImg8bit', data['relpath'], img_name)

    annotation = Annotation()
    annotation.fromJsonFile(data['json_path'])
    instanceImg = createInstanceImage(annotation, "trainIds")
    instanceImg.Format = 'PNG'

    with tf.gfile.GFile(img_path, 'rb') as fid:
        image_file = fid.read()
        image_io = io.BytesIO(image_file)
        image = Image.open(image_io)

    splits_divider = FLAGS.splits_divider

    split_width = int(np.ceil(image.width / splits_divider))
    split_width_half = int(np.ceil(split_width / 2))

    split_positions = [i * split_width for i in range(splits_divider - 1)]
    split_positions.append(image.width - split_width)
    split_positions += [
        split_width_half + i * split_width for i in range(splits_divider - 1)
    ]
    # split_positions += [random.randint(10,(image.width-split_width-10)) for i in range(FLAGS.splits_add)]

    examples = []

    for i, pos in enumerate(split_positions):
        box = (pos, 0, pos + split_width, image.height)
        sub_image = image.crop(box)
        sub_instanceImg = instanceImg.crop(box)

        examples.append(
            sub_img_to_tf_example(img_name + '[#' + str(i) + ']', sub_image,
                                  sub_instanceImg))

    return (examples)
    def build_gold_annotations(self):
        """ Merge annotations, save as gold annotations.
            Take union of all extractions, discard mismatched attributions
        """

        # Merge annotations from annotators
        self.gold_fic_annotations = {}
        for fandom_fname in sorted(self.fandom_fnames):
            self.build_fic_gold_annotations(
                fandom_fname
            )  # saves to self.gold_fic_annotations[fandom_fname]

        # Save out
        for fandom_fname, annotations in sorted(
                self.gold_fic_annotations.items()):
            if self.span_type == 'coref':
                gold_annotations = Annotation(self.annotations_dirpath,
                                              fandom_fname,
                                              file_ext='_entity_clusters.csv')
            elif self.span_type == 'quotes':
                gold_annotations = Annotation(
                    self.annotations_dirpath,
                    fandom_fname,
                    file_ext='_quote_attribution.csv')
            gold_annotations.save_annotated_spans(annotations)
示例#17
0
 def __init__(self,
              parent=None,
              with_filename=True,
              with_slider=True,
              cache_capacity=500,
              max_fps=0):
     super(VideoWidget, self).__init__(parent)
     self.with_filename = with_filename
     self.with_slider = with_slider
     self.video = Video(cache_capacity=cache_capacity, max_fps=max_fps)
     self.annotation = Annotation()
     self.tube_id = 0
     self.tracker = None
     self.sim_thr = 0.9
     self.init_ui()
     self.installEventFilter(self)
     if self.with_slider:
         self.slider.sliderReleased.connect(self.on_slider_released)
     self.label_frame.bbox_added.connect(self.set_tracker)
     self.label_frame.bbox_deleted.connect(self.del_tracker)
     self.video.frame_updated.connect(self.update_frame)
     self.video.export_progress_updated.connect(self.update_export_progress)
    def modify_coref_tokens(self, coref_annotations_dirpath,
                            coref_annotations_ext):
        """ Changes coref tokens to gold annotations in self.token_data.
            Saves out to {token_output_dirpath}_gold_coref/token_fpath
        """
        # Load gold mentions
        gold = Annotation(coref_annotations_dirpath,
                          self.fandom_fname,
                          file_ext=coref_annotations_ext,
                          fic_csv_dirpath=self.fic_csv_dirpath)
        gold.extract_annotated_spans()

        # Build character name to id dictionary for gold characters (arbitrary)
        self.char_name2id = defaultdict(lambda: len(self.char_name2id))
        #self.char_name2id = {charname: len(self.char_name2id) for charname in sorted(gold.annotations_set)}

        # Clear existing character coref annotations
        self.token_data['characterId'] = -1

        # Modify original tokens file
        for span in gold.annotations:
            self.modify_coref_span(span)

        # Renumber BookNLP's own token IDs for re-running on modified output
        self.renumber_token_ids()

        # Save out
        self.modified_token_output_dirpath = self.modified_token_output_dirpath.rstrip(
            '/') + '_gold_coref'
        if not os.path.exists(self.modified_token_output_dirpath):
            os.mkdir(self.modified_token_output_dirpath)
        self.modified_token_fpath = os.path.join(
            self.modified_token_output_dirpath,
            f'{self.fandom_fname}{self.token_file_ext}')
        self.token_data.to_csv(self.modified_token_fpath,
                               sep='\t',
                               quoting=csv.QUOTE_NONE,
                               index=False)
示例#19
0
 def __init__(self, name, fcms=None, notes=None):
     """
     Initialize with fcm collection and notes.
     """
     #  - how is this done in fcmdata?
     self.fcmdict = {}
     self.name = name
     if fcms is not None:
         for fcm in fcms:
             self.fcmdict[fcm.name] = fcm
     if notes is not None:
         self.notes = Annotation()
     else:
         self.notes = notes
示例#20
0
    def targets(self, field, *, annotation_dicts):
        assert self.keypoints is not None
        assert self.skeleton is not None

        annotations = [
            Annotation(keypoints=self.keypoints,
                       skeleton=self.skeleton).set(ann['keypoints'],
                                                   fixed_score=None,
                                                   fixed_bbox=ann['bbox'])
            for ann in annotation_dicts
        ]

        self._confidences(field[0])
        self._regressions(field[1], field[2], annotations=annotations)
示例#21
0
 def parse_xml(self, filename: str) -> Annotation:
     name = os.path.splitext(filename)[0]
     annotation = Annotation(name)
     annotation.init_size()
     with open(filename, 'r') as xml_file:
         tree = ET.parse(xml_file)
         root = tree.getroot()
         labels = list()
         for obj in root.iter('object'):
             difficult = obj.find('difficult').text
             cls = obj.find('name').text
             if cls in self.classes.keys() and int(difficult) == 0:
                 cls_id = str(annotation.classes.get(cls))
                 xml_box = obj.find('bndbox')
                 bbox = (float(xml_box.find('xmin').text),
                         float(xml_box.find('xmax').text),
                         float(xml_box.find('ymin').text),
                         float(xml_box.find('ymax').text))
                 label = (cls_id, bbox)
                 print(label)
                 labels.append(label)
         annotation.labels = labels
         return annotation
    def evaluate_coref(self, fandom_fname, fic_representation, save=True):
        """ Evaluate coref for a fic.
            Args:
                save: save AnnotatedSpan objects in a pickled file in a tmp directory
        """
        # Load gold mentions
        gold = Annotation(self.coref_settings.gold_dirpath, fandom_fname, 
            file_ext=self.coref_settings.gold_ext, 
            fic_csv_dirpath=self.fic_csv_dirpath)
        gold.extract_annotated_spans()

        # Load predicted mentions
        fic_representation.extract_character_mentions(
            save_dirpath=self.coref_settings.preds_outpath)

        # Get scores
        coref_scores = scorer.coref_scores(
            fic_representation.character_mentions, gold.annotations, exact_match=True)
        print('\tCoref results:')
        for key in ['lea_f1', 'lea_precision', 'lea_recall']:
            print(f'\t\t{key}: {coref_scores[key]: .2%}')
        print()
        return coref_scores
示例#23
0
 def parse_txt(self, filename: str) -> Annotation:
     name = os.path.splitext(filename)[0]
     annotation = Annotation(name)
     annotation.init_size()
     labels = []
     with open(filename, "r") as txt_file:
         lines = txt_file.readlines()
         for line in lines:
             line = line.strip()
             words = line.split()
             class_id = words[0]
             w, h = annotation.size
             bbox_width = float(words[3]) * w
             bbox_height = float(words[4]) * h
             center_x = float(words[1]) * w
             center_y = float(words[2]) * h
             bbox = []
             bbox.append(center_x - (bbox_width / 2))
             bbox.append(center_y - (bbox_height / 2))
             bbox.append(center_x + (bbox_width / 2))
             bbox.append(center_y + (bbox_height / 2))
             labels.append((class_id, bbox))
         annotation.labels = labels
     return annotation
 def load_fic_annotations(self, fandom_fname, span_type):
     # Load annotations
     if span_type == 'coref':
         file_ext = 'entity_clusters'
     elif span_type == 'quotes':
         file_ext = 'quote_attribution'
     self.fic_annotations[fandom_fname] = {}
     for annotator in self.annotators:
         self.fic_annotations[fandom_fname][annotator] = Annotation(
             self.annotations_dirpath,
             fandom_fname,
             file_ext=f'_{file_ext}_{annotator}.csv',
             fic_csv_dirpath=self.fic_csv_dirpath)
         self.fic_annotations[fandom_fname][
             annotator].extract_annotated_spans()
示例#25
0
文件: ner.py 项目: dlutwy/ppim
def _ner_document_process(document, tokenizer):
    text_li = []
    tag_li = []

    def f(text):
        # str -> List[str]
        x = tokenizer.convert_ids_to_tokens(tokenizer(text)['input_ids'])[1:-1]
        tokens = []
        for token in x:
            if token[:2] == '##':
                tokens[-1] += token[2:]
            else:
                tokens.append(token)
        return tokens
    for passage in document['passages']:
        anns = passage['annotations']
        anns = Annotation.sortAnns(anns, TBDFilter= False)
        text = passage['text']
        offset_p = passage['offset']
        index = 0
        if len(anns) == 0:
            tokens = f(text)
            text_li.extend(tokens)
            tag_li.extend(['O'] * len(tokens))
        else:
            for ann in anns:
                for i, location in enumerate(ann['locations']): # unnecessary currently because of filter in `Annotation.sortAnns`
                    if i > 0:
                        print("WARNING: PMID:{}, Ann id:{} Text:{}".format(
                            document['id'], ann['id'], ann['text']))
                    offset = location['offset']
                    length = location['length']
                    tokens = f(text[index:offset-offset_p])
                    text_li.extend(tokens)
                    tag_li.extend(['O'] * len(tokens))
                    if i == len(ann['locations']) - 1:
                        mention = text[offset-offset_p: offset-offset_p+length]
                        tokens = f(mention)
                        assert mention == ann['text'], mention + '\t' + ann['text'] +'\t'+ document['id']
                        assert len(tokens) > 0
                        tag_li.extend(['B'] + ['I']*(len(tokens) - 1))
                        text_li.extend(tokens)
                    index = max(offset - offset_p + length, index)
            tokens = f(text[index:])
            text_li.extend(tokens)
            tag_li.extend(['O']*len(tokens))
    assert len(text_li) == len(tag_li)
    return text_li, tag_li
示例#26
0
 def move_mouse(self, event):
     """
     Handles the drawing of the arrow when deciding where to annotate
     """
     if WorldState.Instance().draw_plot:
         if WorldState.Instance().session_dict['click_one']:
             WorldState.Instance(
             ).session_dict['temp_annotation'] = Annotation(
                 WorldState.Instance()._ARROW,
                 (WorldState.Instance().session_dict['click_one_x'],
                  WorldState.Instance().session_dict['click_one_y']),
                 (event.xdata, event.ydata))
         if WorldState.Instance().session_dict['annotate']:
             WorldState.Instance().session_dict['redraw_legend'] = False
             WorldState.Instance().draw_plot.plot()
             WorldState.Instance().session_dict['redraw_legend'] = True
示例#27
0
def wrap_annotations(sentences):
    annotations = []
    tid = 0
    for sid, labels in enumerate(sentences):
        for idx, label in enumerate(labels):
            for ann in label.split('#'):
                type = ann[2:]
                if 'B-' in ann:
                    annotations.append(Annotation(type, sid, tid))
                elif 'I-' in ann:
                    for _ann in reversed(annotations):
                        if type == _ann.annotation:
                            _ann.add_id(tid)
                            break
            tid += 1
    return annotations
示例#28
0
    def to_annotation(self, threshold=-np.inf, posterior=False):
        """

        Parameters
        ----------
        threshold : float, optional
            Each track is annotated with the label with the highest score.
            Yet, if the latter is smaller than `threshold`, label is replaced
            with an `Unknown` instance.
        posterior : bool, optional
            If True, scores are posterior probabilities in open-set
            identification. If top model posterior is higher than unknown
            posterior, it is selected. Otherwise, label is replaced with an
            `Unknown` instance.
        """

        annotation = Annotation(uri=self.uri, modality=self.modality)
        if not self:
            return annotation

        best = self.nbest(1, invert=False)

        if posterior:

            # compute unknown posterior
            func = lambda p: 1. - np.nansum(p, axis=1)
            Pu = self.apply(func, new_columns=['_'])

            # threshold best target posterior
            # with unknown posterior and threshold
            for segment, track, label, value in best.itervalues():

                if value < Pu[segment, track, '_'] or value < threshold:
                    label = Unknown()

                annotation[segment, track] = label

        else:

            # threshold best target score with threshold
            for segment, track, label, value in best.itervalues():
                if value < threshold:
                    label = Unknown()
                annotation[segment, track] = label

        return annotation
示例#29
0
    def _load_annotations(self):
        f = open(self.file_name, 'r')
        for line in f:
            line = line.strip()
            if line != "":
                annotations_list = [
                    Annotation(
                        int(begin_index) + 1, int(end_index), time_expression,
                        timex3)
                    for begin_index, end_index, time_expression, timex3 in map(
                        None, *([iter(line.split("\t"))] * 4))
                ]
            else:
                annotations_list = []

            self.annotations.append(annotations_list)
        f.close()
示例#30
0
 def __init__(self, parent=None, with_filename=True, with_slider=True,
              cache_capacity=500, max_fps=0):
     super(VideoWidget, self).__init__(parent)
     self.with_filename = with_filename
     self.with_slider = with_slider
     self.video = Video(cache_capacity=cache_capacity, max_fps=max_fps)
     self.annotation = Annotation()
     self.tube_id = 0
     self.tracker = None
     self.sim_thr = 0.9
     self.init_ui()
     self.installEventFilter(self)
     if self.with_slider:
         self.slider.sliderReleased.connect(self.on_slider_released)
     self.label_frame.bbox_added.connect(self.set_tracker)
     self.label_frame.bbox_deleted.connect(self.del_tracker)
     self.video.frame_updated.connect(self.update_frame)
     self.video.export_progress_updated.connect(self.update_export_progress)
示例#31
0
    def test_get_annotated(self):

        text = 'Lorem ipsum dolor sit amet. Consectetur adipiscing elit. Sed do eiusmod tempor incididunt.'
        tagged_text = '<p><span>Lorem</span> ipsum dolor sit <span>amet</span>.</p><p>Consectetur adipiscing <span>elit</span>.</p><p>Sed do eiusmod tempor <span>incididunt</span>.</p>'
        lst_annotations = [
            Annotation('sentence', 0, 27),
            Annotation('sentence', 28, 56),
            Annotation('sentence', 57, 90),
            Annotation('word', 22, 26),
            Annotation('word', 51, 55),
            Annotation('word', 79, 89),
            Annotation('word', 0, 5)
        ]

        tagged_text_test = get_annotated(
            Document(text, 'test', lst_annotations))
        self.assertEqual(tagged_text_test, tagged_text)
示例#32
0
def count_annotated_objects_in_folder(folder:str, recursive:bool=True) -> int:
    jsons = [
        os.path.join(folder, f) for f in os.listdir(folder) 
        if os.path.splitext(f)[1] == ".json"
    ]
    count = 0
    for f in jsons:
        ann =  Annotation.load(f)
        count += len(ann.objects) + len(ann.missing)
        
    if recursive:
        subfolders = [
            os.path.join(folder, f)
            for f in os.listdir(folder)
            if os.path.isdir(os.path.join(folder, f))
        ]
        count += sum(
            count_annotated_objects_in_folder(subfolder, True)
            for subfolder in subfolders
        )
        
    return count
示例#33
0
 def write_annotation(self, ann, annotations_csv):
     unique_tuple = (ann[0], ann[1], ann[3]
                     )  #description have not to be there
     #check if annotation is already in dictionary
     if unique_tuple in self.map_ann2id:
         #assign current annotation id and increment count of this label
         return self.map_ann2id[unique_tuple]
     else:
         ann_info = Annotation(ann[0], ann[1], ann[2], ann[3])
         #add new annotation to dictionary and write row with annotation
         self.annotation_id_cnt += 1
         current_annotation_id = self.annotation_id_cnt
         self.map_ann2id[unique_tuple] = current_annotation_id
         self.id2counts[current_annotation_id] = {}
         for i in self.back_sets_ids:
             self.id2counts[current_annotation_id][i] = 0
         ann_desc_id = self.ann_descriptions.get_annotation_description(
             ann_info.attribute, ann_info.var_gene)
         annotations_csv.writerow([
             current_annotation_id, ann_info.label,
             ann_info.description.replace('\\', '\\\\'), ann_desc_id
         ])
         return current_annotation_id
def json2labelImg(inJson, outImg, encoding="trainIds"):
    annotation = Annotation()
    annotation.fromJsonFile(inJson)
    labelImg = createLabelImage(annotation, encoding)
    #labelImg   = createLabelImage( annotation , encoding ,outline= name2label['hasInstances boundary'].trainId)
    labelImg.save(outImg)
示例#35
0
def json2instanceArr(inJson, encoding="ids", label_tochose='car'):
    annotation = Annotation()
    annotation.fromJsonFile(inJson)
    instanceImg = getInstancewithLabel(annotation, encoding, label_tochose)
    return instanceImg
示例#36
0
class VideoWidget(QWidget):

    frame_updated = pyqtSignal(int)
    tube_annotated = pyqtSignal(dict)
    annotation_loaded = pyqtSignal(list)
    export_progress_updated = pyqtSignal(int)

    def __init__(self, parent=None, with_filename=True, with_slider=True,
                 cache_capacity=500, max_fps=0):
        super(VideoWidget, self).__init__(parent)
        self.with_filename = with_filename
        self.with_slider = with_slider
        self.video = Video(cache_capacity=cache_capacity, max_fps=max_fps)
        self.annotation = Annotation()
        self.tube_id = 0
        self.tracker = None
        self.sim_thr = 0.9
        self.init_ui()
        self.installEventFilter(self)
        if self.with_slider:
            self.slider.sliderReleased.connect(self.on_slider_released)
        self.label_frame.bbox_added.connect(self.set_tracker)
        self.label_frame.bbox_deleted.connect(self.del_tracker)
        self.video.frame_updated.connect(self.update_frame)
        self.video.export_progress_updated.connect(self.update_export_progress)

    def init_ui(self):
        self.vbox_layout = QVBoxLayout()
        if self.with_filename:
            self.init_label_filename()
        self.init_label_frame()
        if self.with_slider:
            self.init_slider()
        self.setLayout(self.vbox_layout)
        # self.setFocusPolicy(Qt.StrongFocus)

    def init_label_filename(self):
        self.label_filename = QLabel('filename')
        self.label_filename.setAlignment(Qt.AlignCenter)
        self.vbox_layout.addWidget(self.label_filename, 1)

    def init_label_frame(self):
        self.label_frame = ImageLabel('video')
        self.label_frame.setAlignment(Qt.AlignCenter)
        self.label_frame.setStyleSheet('border: 1px solid black')
        self.vbox_layout.addWidget(self.label_frame, 10)

    def init_slider(self):
        self.slider = QSlider(Qt.Horizontal)
        self.slider.setRange(0, 1000)
        self.slider.setTickInterval(1)
        self.slider.setValue(0)
        self.slider.setEnabled(False)
        self.vbox_layout.addWidget(self.slider, 1)

    def eventFilter(self, object, event):
        if event.type() == QEvent.KeyPress:
            key = event.key()
            if key == Qt.Key_D:
                self.frame_forward()
                return True
            elif key == Qt.Key_A:
                self.frame_backward()
                return True
            elif key == Qt.Key_S:
                self.last_keyframe = self.cursor()
                self.new_tube()
                return True
            elif key == Qt.Key_Left:
                if self.status() == VideoStatus.play_backward:
                    self.pause()
                elif self.video.status != VideoStatus.not_loaded:
                    self.play_backward()
                return True
            elif key == Qt.Key_Right:
                if self.status() == VideoStatus.play_forward:
                    self.pause()
                elif self.status() != VideoStatus.not_loaded:
                    self.play_forward()
                return True
            elif key == Qt.Key_Space:
                self.pause()
                return True
        return False

    def frame_forward(self):
        if self.tracker is not None:
            ori_hist = color_hist(self.tracker.init_region, 16)
            if self.cursor() >= self.annotation.tube_end(self.tube_id):
                self.last_keyframe = self.cursor()
        cnt = 0
        while cnt < 10:
            frame = self.video.frame_forward()
            self.update_frame(frame)
            if (self.tracker is None or
                    self.cursor() < self.annotation.tube_end(self.tube_id)):
                break
            bbox = self.tracker.bbox
            hist = color_hist(
                frame.raw_img[bbox.left: bbox.right, bbox.top: bbox.bottom], 16)
            if compare_hist(hist, ori_hist) < self.sim_thr:
                break
            cnt += 1

    def frame_backward(self):
        frame = self.video.frame_backward()
        self.update_frame(frame)

    def play_forward(self):
        self.video.play_forward()

    def play_backward(self):
        self.video.play_backward()

    def pause(self):
        self.video.pause()

    def jump_to_frame(self, frame_id):
        self.clear_tracker()
        frame = self.video.jump_to_frame(frame_id)
        self.update_frame(frame)

    def status(self):
        return self.video.status

    def cursor(self):
        return self.video.cursor

    def frame_cnt(self):
        return self.video.frame_cnt

    def current_frame(self):
        return self.video.current_frame()

    def new_tube(self):
        label = self.label_frame.bbox_label
        if label is not None:
            self.tube_id = self.annotation.next_tube_id
            self.annotation.add_tube(label, self.cursor())
            self.label_frame.flash_reticle()
            self.label_frame.toggle_reticle(True)
            self.label_frame.is_new_tube = True

    def clear_tracker(self):
        self.tracker = None

    def reset_tube_id(self):
        self.tube_id = 0

    def track(self, frame):
        frame_rect = BoundingBox(None, 0, 0, 0,
                                 self.video.width, self.video.height)
        bbox, score = self.tracker.update(frame)
        bbox = bbox.intersected(frame_rect)
        return bbox

    def adjust_track_bboxes(self, bbox):
        self.annotation.interpolate(self.tube_id, bbox, self.last_keyframe,
                                    self.cursor())

    @pyqtSlot(VideoFrame)
    def update_frame(self, frame):
        # get bounding boxes of current tube and other tubes
        bboxes = dict()
        if (self.tracker is not None and self.video.is_forward() and
                self.cursor() > self.annotation.tube_end(self.tube_id)):
            bboxes['current_tube'] = self.track(frame)
            self.annotation.set_bbox(self.tube_id, self.cursor(),
                                     bboxes['current_tube'])
        else:
            bboxes['current_tube'] = self.annotation.get_bbox(
                self.tube_id, self.cursor())
        bboxes['other_tubes'] = self.annotation.get_bboxes(
            self.cursor(), self.tube_id)
        # show the frame and corresponding bounding boxes
        self.label_frame.display(frame)
        self.label_frame.update_bboxes(bboxes)
        # update slider position
        if self.with_slider:
            self.slider.setValue(
                int(self.slider.maximum() * frame.id / self.frame_cnt()))
        # emit the frame id to the main window to update status bar
        self.frame_updated.emit(frame.id)

    @pyqtSlot(BoundingBox)
    def set_tracker(self, bbox):
        if self.tracker is not None and self.cursor() > self.last_keyframe + 1:
            self.adjust_track_bboxes(bbox)
        self.tracker = Tracker()
        self.tracker.start_track(self.current_frame(), bbox)
        self.annotation.set_bbox(self.tube_id, self.cursor(), bbox)

    @pyqtSlot()
    def del_tracker(self):
        self.clear_tracker()
        self.annotation.del_later_bboxes(self.tube_id, self.cursor())
        self.annotation.save()
        tube_info = self.annotation.tube(self.tube_id).to_dict(with_bboxes=False)
        self.tube_annotated.emit(tube_info)
        self.reset_tube_id()

    @pyqtSlot()
    def on_slider_released(self):
        progress = self.slider.value() / self.slider.maximum()
        frame_id = max(int(round(self.frame_cnt() * progress)), 1)
        self.jump_to_frame(frame_id)

    @pyqtSlot(int)
    def jump_to_tube(self, tube_id):
        self.tube_id = tube_id
        self.jump_to_frame(self.annotation.tube_start(tube_id))

    @pyqtSlot(int)
    def del_tube(self, tube_id):
        if self.tube_id == tube_id:
            self.tube_id = 0
        self.annotation.del_tube(tube_id)
        self.annotation.save()

    @pyqtSlot(int, str)
    def change_tube_label(self, tube_id, label):
        self.annotation.tubes[tube_id].label = label
        self.annotation.save()

    @pyqtSlot(str)
    def update_bbox_label(self, label):
        self.label_frame.update_bbox_label(label)

    @pyqtSlot()
    def open_file(self):
        self.filename, _ = QFileDialog.getOpenFileName(
            self, 'Load video', '/home/kchen/data/youtube/selected/',
            'Videos (*.mp4 *.avi *.mkv *.flv *.m4v)')
        if not self.filename:
            return
        if self.with_filename:
            self.label_filename.setText(os.path.basename(self.filename))
        if self.with_slider:
            self.slider.setEnabled(True)
        self.video.load(self.filename)
        self.annotation.load(self.filename + '.annotation')
        self.annotation_loaded.emit(self.annotation.get_brief_info())
        self.jump_to_frame(1)

    @pyqtSlot()
    def export_video(self):
        filename, _ = QFileDialog.getSaveFileName(
            self, 'Export video', './', 'Videos (*.avi)')
        t = threading.Thread(target=self.video.export,
                             kwargs=dict(out_file=filename,
                                         annotation=self.annotation))
        t.daemon = True
        t.start()

    @pyqtSlot(int)
    def update_export_progress(self, progress):
        self.export_progress_updated.emit(progress)

    @pyqtSlot()
    def save_annotation(self):
        self.annotation.save()
示例#37
0
 def __init__(self, description, subcat_filter, max_sentences=None):
     Annotation.__init__(self, description)
     self.subcat_filter = subcat_filter
     self.max_sentences = max_sentences
class CityscapesViewer(QtGui.QMainWindow):

    #############################
    ## Construction / Destruction
    #############################

    # Constructor
    def __init__(self):
        # Construct base class
        super(CityscapesViewer, self).__init__()

        # This is the configuration.

        # The filename of the image we currently working on
        self.currentFile       = ""
        # The filename of the labels we currently working on
        self.currentLabelFile  = ""
        # The path of the images of the currently loaded city
        self.city              = ""
        # The name of the currently loaded city
        self.cityName          = ""
        # Ground truth type
        self.gtType            = CsObjectType.POLY
        # The path of the labels. In this folder we expect a folder for each city
        # Within these city folders we expect the label with a filename matching
        # the images, except for the extension
        self.labelPath         = ""
        # The transparency of the labels over the image
        self.transp            = 0.5
        # The zoom toggle
        self.zoom              = False
        # The zoom factor
        self.zoomFactor        = 1.5
        # The size of the zoom window. Currently there is no setter or getter for that
        self.zoomSize          = 400 #px

        # The width that we actually use to show the image
        self.w                 = 0
        # The height that we actually use to show the image
        self.h                 = 0
        # The horizontal offset where we start drawing within the widget
        self.xoff              = 0
        # The vertical offset where we start drawing withing the widget
        self.yoff              = 0
        # A gap that we  leave around the image as little border
        self.bordergap         = 20
        # The scale that was used, ie
        # self.w = self.scale * self.image.width()
        # self.h = self.scale * self.image.height()
        self.scale             = 1.0
        # Filenames of all images in current city
        self.images            = []
        # Image extension
        self.imageExt          = "_leftImg8bit.png"
        # Ground truth extension
        self.gtExt             = "_gt*.json"
        # Current image as QImage
        self.image             = QtGui.QImage()
        # Index of the current image within the city folder
        self.idx               = 0
        # All annotated objects in current image, i.e. list of csPoly or csBbox
        self.annotation        = []
        # The current object the mouse points to. It's index in self.labels
        self.mouseObj          = -1
        # The object that is highlighted and its label. An object instance
        self.highlightObj      = None
        self.highlightObjLabel = None
        # The position of the mouse
        self.mousePosOrig      = None
        # The position of the mouse scaled to label coordinates
        self.mousePosScaled    = None
        # If the mouse is outside of the image
        self.mouseOutsideImage = True
        # The position of the mouse upon enabling the zoom window
        self.mousePosOnZoom    = None
        # A list of toolbar actions that need an image
        self.actImage          = []
        # A list of toolbar actions that need an image that is not the first
        self.actImageNotFirst  = []
        # A list of toolbar actions that need an image that is not the last
        self.actImageNotLast   = []
        # Toggle status of the play icon
        self.playState         = False
        # Enable disparity visu in general
        self.enableDisparity   = True
        # Show disparities instead of labels
        self.showDisparity     = False
        # The filename of the disparity map we currently working on
        self.currentDispFile   = ""
        # The disparity image
        self.dispImg           = None
        # As overlay
        self.dispOverlay       = None
        # The disparity search path
        self.dispPath          = None
        # Disparity extension
        self.dispExt           = "_disparity.png"
        # Generate colormap
        try:
            norm = matplotlib.colors.Normalize(vmin=3,vmax=100)
            cmap = matplotlib.cm.plasma
            self.colormap = matplotlib.cm.ScalarMappable( norm=norm , cmap=cmap )
        except:
            self.enableDisparity = False
        # check if pillow was imported, otherwise no disparity visu possible
        if not 'PILLOW_VERSION' in globals():
            self.enableDisparity = False

        # Default label
        self.defaultLabel = 'static'
        if self.defaultLabel not in name2label:
            print('The {0} label is missing in the internal label definitions.'.format(self.defaultLabel))
            return
        # Last selected label
        self.lastLabel = self.defaultLabel

        # Setup the GUI
        self.initUI()

        # If we already know a city from the saved config -> load it
        self.loadCity()
        self.imageChanged()

    # Destructor
    def __del__(self):
        return

    # Construct everything GUI related. Called by constructor
    def initUI(self):
        # Create a toolbar
        self.toolbar = self.addToolBar('Tools')

        # Add the tool buttons
        iconDir = os.path.join( os.path.dirname(sys.argv[0]) , 'icons' )

        # Loading a new city
        loadAction = QtGui.QAction(QtGui.QIcon( os.path.join( iconDir , 'open.png' )), '&Tools', self)
        loadAction.setShortcuts(['o'])
        self.setTip( loadAction, 'Open city' )
        loadAction.triggered.connect( self.getCityFromUser )
        self.toolbar.addAction(loadAction)

        # Open previous image
        backAction = QtGui.QAction(QtGui.QIcon( os.path.join( iconDir , 'back.png')), '&Tools', self)
        backAction.setShortcut('left')
        backAction.setStatusTip('Previous image')
        backAction.triggered.connect( self.prevImage )
        self.toolbar.addAction(backAction)
        self.actImageNotFirst.append(backAction)

        # Open next image
        nextAction = QtGui.QAction(QtGui.QIcon( os.path.join( iconDir , 'next.png')), '&Tools', self)
        nextAction.setShortcut('right')
        self.setTip( nextAction, 'Next image' )
        nextAction.triggered.connect( self.nextImage )
        self.toolbar.addAction(nextAction)
        self.actImageNotLast.append(nextAction)

        # Play
        playAction = QtGui.QAction(QtGui.QIcon( os.path.join( iconDir , 'play.png')), '&Tools', self)
        playAction.setShortcut(' ')
        playAction.setCheckable(True)
        playAction.setChecked(False)
        self.setTip( playAction, 'Play all images' )
        playAction.triggered.connect( self.playImages )
        self.toolbar.addAction(playAction)
        self.actImageNotLast.append(playAction)
        self.playAction = playAction

        # Select image
        selImageAction = QtGui.QAction(QtGui.QIcon( os.path.join( iconDir , 'shuffle.png' )), '&Tools', self)
        selImageAction.setShortcut('i')
        self.setTip( selImageAction, 'Select image' )
        selImageAction.triggered.connect( self.selectImage )
        self.toolbar.addAction(selImageAction)
        self.actImage.append(selImageAction)

        # Enable/disable disparity visu. Toggle button
        if self.enableDisparity:
            dispAction = QtGui.QAction(QtGui.QIcon( os.path.join( iconDir , 'disp.png' )), '&Tools', self)
            dispAction.setShortcuts(['d'])
            dispAction.setCheckable(True)
            dispAction.setChecked(self.showDisparity)
            self.setTip( dispAction, 'Enable/disable depth visualization' )
            dispAction.toggled.connect( self.dispToggle )
            self.toolbar.addAction(dispAction)
            self.actImage.append(dispAction)

        # Enable/disable zoom. Toggle button
        zoomAction = QtGui.QAction(QtGui.QIcon( os.path.join( iconDir , 'zoom.png' )), '&Tools', self)
        zoomAction.setShortcuts(['z'])
        zoomAction.setCheckable(True)
        zoomAction.setChecked(self.zoom)
        self.setTip( zoomAction, 'Enable/disable permanent zoom' )
        zoomAction.toggled.connect( self.zoomToggle )
        self.toolbar.addAction(zoomAction)
        self.actImage.append(zoomAction)

        # Decrease transparency
        minusAction = QtGui.QAction(QtGui.QIcon( os.path.join( iconDir , 'minus.png' )), '&Tools', self)
        minusAction.setShortcut('-')
        self.setTip( minusAction, 'Decrease transparency' )
        minusAction.triggered.connect( self.minus )
        self.toolbar.addAction(minusAction)

        # Increase transparency
        plusAction = QtGui.QAction(QtGui.QIcon( os.path.join( iconDir , 'plus.png' )), '&Tools', self)
        plusAction.setShortcut('+')
        self.setTip( plusAction, 'Increase transparency' )
        plusAction.triggered.connect( self.plus )
        self.toolbar.addAction(plusAction)

        # Display path to current image in message bar
        displayFilepathAction = QtGui.QAction(QtGui.QIcon( os.path.join( iconDir , 'filepath.png' )), '&Tools', self)
        displayFilepathAction.setShortcut('f')
        self.setTip( displayFilepathAction, 'Show path to current image' )
        displayFilepathAction.triggered.connect( self.displayFilepath )
        self.toolbar.addAction(displayFilepathAction)

        # Display help message
        helpAction = QtGui.QAction(QtGui.QIcon( os.path.join( iconDir , 'help19.png' )), '&Tools', self)
        helpAction.setShortcut('h')
        self.setTip( helpAction, 'Help' )
        helpAction.triggered.connect( self.displayHelpMessage )
        self.toolbar.addAction(helpAction)

        # Close the application
        exitAction = QtGui.QAction(QtGui.QIcon( os.path.join( iconDir , 'exit.png' )), '&Tools', self)
        exitAction.setShortcuts(['Esc'])
        self.setTip( exitAction, 'Exit' )
        exitAction.triggered.connect( self.close )
        self.toolbar.addAction(exitAction)

        # The default text for the status bar
        self.defaultStatusbar = 'Ready'
        # Create a statusbar. Init with default
        self.statusBar().showMessage( self.defaultStatusbar )

        # Enable mouse move events
        self.setMouseTracking(True)
        self.toolbar.setMouseTracking(True)
        # Open in full screen
        self.showFullScreen( )
        # Set a title
        self.applicationTitle = 'Cityscapes Viewer v1.0'
        self.setWindowTitle(self.applicationTitle)
        self.displayHelpMessage()
        self.getCityFromUser()
        # And show the application
        self.show()

    #############################
    ## Toolbar call-backs
    #############################

    # Switch to previous image in file list
    # Load the image
    # Load its labels
    # Update the mouse selection
    # View
    def prevImage(self):
        if not self.images:
            return
        if self.idx > 0:
            self.idx -= 1
            self.imageChanged()
        else:
            message = "Already at the first image"
            self.statusBar().showMessage(message)
        return

    # Switch to next image in file list
    # Load the image
    # Load its labels
    # Update the mouse selection
    # View
    def nextImage(self):
        if not self.images:
            return
        if self.idx < len(self.images)-1:
            self.idx += 1
            self.imageChanged()
        elif self.playState:
            self.playState = False
            self.playAction.setChecked(False)
        else:
            message = "Already at the last image"
            self.statusBar().showMessage(message)
        if self.playState:
            QtCore.QTimer.singleShot(0, self.nextImage)
        return

    # Play images, i.e. auto-switch to next image
    def playImages(self, status):
        self.playState = status
        if self.playState:
            QtCore.QTimer.singleShot(0, self.nextImage)


    # Switch to a selected image of the file list
    # Ask the user for an image
    # Load the image
    # Load its labels
    # Update the mouse selection
    # View
    def selectImage(self):
        if not self.images:
            return

        dlgTitle = "Select image to load"
        self.statusBar().showMessage(dlgTitle)
        items = QtCore.QStringList( [ os.path.basename(i) for i in self.images ] )
        (item, ok) = QtGui.QInputDialog.getItem(self, dlgTitle, "Image", items, self.idx, False)
        if (ok and item):
            idx = items.indexOf(item)
            if idx != self.idx:
                self.idx = idx
                self.imageChanged()
        else:
            # Restore the message
            self.statusBar().showMessage( self.defaultStatusbar )


    # Toggle zoom
    def zoomToggle(self, status):
        self.zoom = status
        if status :
            self.mousePosOnZoom = self.mousePosOrig
        self.update()

    # Toggle disparity visu
    def dispToggle(self, status):
        self.showDisparity = status
        self.imageChanged()


    # Increase label transparency
    def minus(self):
        self.transp = max(self.transp-0.1,0.0)
        self.update()


    def displayFilepath(self):
        self.statusBar().showMessage("Current image: {0}".format( self.currentFile ))
        self.update()

    def displayHelpMessage(self):

        message = self.applicationTitle + "\n\n"
        message += "INSTRUCTIONS\n"
        message += " - select a city from drop-down menu\n"
        message += " - browse images and labels using\n"
        message += "   the toolbar buttons or the controls below\n"
        message += "\n"
        message += "CONTROLS\n"
        message += " - select city [o]\n"
        message += " - highlight objects [move mouse]\n"
        message += " - next image [left arrow]\n"
        message += " - previous image [right arrow]\n"
        message += " - toggle autoplay [space]\n"
        message += " - increase/decrease label transparency\n"
        message += "   [ctrl+mousewheel] or [+ / -]\n"
        if self.enableDisparity:
            message += " - show disparity/depth overlay (if available) [d]\n"

        message += " - open zoom window [z]\n"
        message += "       zoom in/out [mousewheel]\n"
        message += "       enlarge/shrink zoom window [shift+mousewheel]\n"
        message += " - select a specific image [i]\n"
        message += " - show path to image below [f]\n"
        message += " - exit viewer [esc]\n"

        QtGui.QMessageBox.about(self, "HELP!", message)
        self.update()


    # Decrease label transparency
    def plus(self):
        self.transp = min(self.transp+0.1,1.0)
        self.update()

    # Close the application
    def closeEvent(self,event):
         event.accept()


    #############################
    ## Custom events
    #############################

    def imageChanged(self):
        # Load the first image
        self.loadImage()
        # Load its labels if available
        self.loadLabels()
        # Load disparities if available
        self.loadDisparities()
        # Update the object the mouse points to
        self.updateMouseObject()
        # Update the GUI
        self.update()

    #############################
    ## File I/O
    #############################

    # Load the currently selected city if possible
    def loadCity(self):
        # Search for all *.pngs to get the image list
        self.images = []
        if os.path.isdir(self.city):
            self.images = glob.glob( os.path.join( self.city , '*' + self.imageExt ) )
            self.images.sort()
            if self.currentFile in self.images:
                self.idx = self.images.index(self.currentFile)
            else:
                self.idx = 0

    # Load the currently selected image
    # Does only load if not previously loaded
    # Does not refresh the GUI
    def loadImage(self):
        success = False
        message = self.defaultStatusbar
        if self.images:
            filename = self.images[self.idx]
            filename = os.path.normpath( filename )
            if not self.image.isNull() and filename == self.currentFile:
                success = True
            else:
                self.image = QtGui.QImage(filename)
                if self.image.isNull():
                    message = "Failed to read image: {0}".format( filename )
                else:
                    message = "Read image: {0}".format( filename )
                    self.currentFile = filename
                    success = True

        # Update toolbar actions that need an image
        for act in self.actImage:
            act.setEnabled(success)
        for act in self.actImageNotFirst:
            act.setEnabled(success and self.idx > 0)
        for act in self.actImageNotLast:
            act.setEnabled(success and self.idx < len(self.images)-1)

        self.statusBar().showMessage(message)

    # Load the labels from file
    # Only loads if they exist
    # Otherwise the filename is stored and that's it
    def loadLabels(self):
        filename = self.getLabelFilename()
        if not filename:
            self.clearAnnotation()
            return

        # If we have everything and the filename did not change, then we are good
        if self.annotation and filename == self.currentLabelFile:
            return

        # Clear the current labels first
        self.clearAnnotation()

        try:
            self.annotation = Annotation(self.gtType)
            self.annotation.fromJsonFile(filename)
        except IOError as e:
            # This is the error if the file does not exist
            message = "Error parsing labels in {0}. Message: {1}".format( filename, e.strerror )
            self.statusBar().showMessage(message)

        # Remember the filename loaded
        self.currentLabelFile = filename

        # Remeber the status bar message to restore it later
        restoreMessage = self.statusBar().currentMessage()

        # Restore the message
        self.statusBar().showMessage( restoreMessage )


    # Load the disparity map from file
    # Only loads if they exist
    def loadDisparities(self):
        if not self.enableDisparity:
            return
        if not self.showDisparity:
            return

        filename = self.getDisparityFilename()
        if not filename:
            self.dispImg = None
            return

        # If we have everything and the filename did not change, then we are good
        if self.dispImg and filename == self.currentDispFile:
            return

        # Clear the current labels first
        self.dispImg = None

        try:
            self.dispImg = Image.open(filename)
        except IOError as e:
            # This is the error if the file does not exist
            message = "Error parsing disparities in {0}. Message: {1}".format( filename, e.strerror )
            self.statusBar().showMessage(message)
            self.dispImg = None

        if self.dispImg:
            dispNp = np.array( self.dispImg )
            dispNp /= 128
            dispNp.round()
            dispNp = np.array( dispNp , dtype=np.uint8 )

            dispQt = QtGui.QImage( dispNp.data , dispNp.shape[1] , dispNp.shape[0] , QtGui.QImage.Format_Indexed8 )

            colortable = []
            for i in range(256):
                color = self.colormap.to_rgba(i)
                colorRgb = ( int(color[0]*255) , int(color[1]*255) , int(color[2]*255) )
                colortable.append( QtGui.qRgb( *colorRgb ) )

            dispQt.setColorTable( colortable )
            dispQt = dispQt.convertToFormat( QtGui.QImage.Format_ARGB32_Premultiplied )
            self.dispOverlay = dispQt

        # Remember the filename loaded
        self.currentDispFile = filename

        # Remember the status bar message to restore it later
        restoreMessage = self.statusBar().currentMessage()

        # Restore the message
        self.statusBar().showMessage( restoreMessage )

    #############################
    ## Drawing
    #############################

    # This method is called when redrawing everything
    # Can be manually triggered by self.update()
    # Note that there must not be any other self.update within this method
    # or any methods that are called within
    def paintEvent(self, event):
        # Create a QPainter that can perform draw actions within a widget or image
        qp = QtGui.QPainter()
        # Begin drawing in the application widget
        qp.begin(self)
        # Update scale
        self.updateScale(qp)
        # Determine the object ID to highlight
        self.getHighlightedObject(qp)
        # Draw the image first
        self.drawImage(qp)

        if self.enableDisparity and self.showDisparity:
            # Draw the disparities on top
            overlay = self.drawDisp(qp)
        else:
            # Draw the labels on top
            if self.gtType == CsObjectType.POLY:
                overlay = self.drawLabels(qp)
            elif self.gtType == CsObjectType.BBOX:
                overlay = self.drawBboxes(qp)
            # Draw the label name next to the mouse
            self.drawLabelAtMouse(qp)

        # Draw the zoom
        self.drawZoom(qp, overlay)

        # Thats all drawing
        qp.end()

        # Forward the paint event
        QtGui.QMainWindow.paintEvent(self,event)

    # Update the scaling
    def updateScale(self, qp):
        if not self.image.width() or not self.image.height():
            return
        # Horizontal offset
        self.xoff  = self.bordergap
        # Vertical offset
        self.yoff  = self.toolbar.height()+self.bordergap
        # We want to make sure to keep the image aspect ratio and to make it fit within the widget
        # Without keeping the aspect ratio, each side of the image is scaled (multiplied) with
        sx = float(qp.device().width()  - 2*self.xoff) / self.image.width()
        sy = float(qp.device().height() - 2*self.yoff) / self.image.height()
        # To keep the aspect ratio while making sure it fits, we use the minimum of both scales
        # Remember the scale for later
        self.scale = min( sx , sy )
        # These are then the actual dimensions used
        self.w     = self.scale * self.image.width()
        self.h     = self.scale * self.image.height()

    # Determine the highlighted object for drawing
    def getHighlightedObject(self, qp):
        # This variable we want to fill
        self.highlightObj = None

        # Without labels we cannot do so
        if not self.annotation:
            return

        # If available its the selected object
        highlightObjId = -1
        # If not available but the polygon is empty or closed, its the mouse object
        if highlightObjId < 0 and not self.mouseOutsideImage:
            highlightObjId = self.mouseObj
        # Get the actual object that is highlighted
        if highlightObjId >= 0:
            self.highlightObj = self.annotation.objects[highlightObjId]
            self.highlightObjLabel = self.annotation.objects[highlightObjId].label

    # Draw the image in the given QPainter qp
    def drawImage(self, qp):
        # Return if no image available
        if self.image.isNull():
            return

        # Save the painters current setting to a stack
        qp.save()
        # Draw the image
        qp.drawImage(QtCore.QRect( self.xoff, self.yoff, self.w, self.h ), self.image)
        # Restore the saved setting from the stack
        qp.restore()

    def getPolygon(self, obj):
        poly = QtGui.QPolygonF()
        for pt in obj.polygon:
            point = QtCore.QPointF(pt.x,pt.y)
            poly.append( point )
        return poly

    # Draw the labels in the given QPainter qp
    # optionally provide a list of labels to ignore
    def drawLabels(self, qp, ignore = []):
        if self.image.isNull() or self.w == 0 or self.h == 0:
            return
        if not self.annotation:
            return

        # The overlay is created in the viewing coordinates
        # This way, the drawing is more dense and the polygon edges are nicer
        # We create an image that is the overlay
        # Within this image we draw using another QPainter
        # Finally we use the real QPainter to overlay the overlay-image on what is drawn so far

        # The image that is used to draw the overlays
        overlay = QtGui.QImage( self.w, self.h, QtGui.QImage.Format_ARGB32_Premultiplied )
        # Fill the image with the default color
        defaultLabel = name2label[self.defaultLabel]
        col = QtGui.QColor( *defaultLabel.color )
        overlay.fill( col )
        # Create a new QPainter that draws in the overlay image
        qp2 = QtGui.QPainter()
        qp2.begin(overlay)

        # The color of the outlines
        qp2.setPen(QtGui.QColor('white'))
        # Draw all objects
        for obj in self.annotation.objects:

            # The label of the object
            name      = assureSingleInstanceName( obj.label )
            # If we do not know a color for this label, warn the user
            if name not in name2label:
                print("The annotations contain unkown labels. This should not happen. Please inform the datasets authors. Thank you!")
                print("Details: label '{}', file '{}'".format(name,self.currentLabelFile))
                continue

            poly = self.getPolygon(obj)

            # Scale the polygon properly
            polyToDraw = poly * QtGui.QTransform.fromScale(self.scale,self.scale)

            # Default drawing
            # Color from color table, solid brush
            col   = QtGui.QColor( *name2label[name].color     )
            brush = QtGui.QBrush( col, QtCore.Qt.SolidPattern )
            qp2.setBrush(brush)
            # Overwrite drawing if this is the highlighted object
            if self.highlightObj and obj == self.highlightObj:
                # First clear everything below of the polygon
                qp2.setCompositionMode( QtGui.QPainter.CompositionMode_Clear )
                qp2.drawPolygon( polyToDraw )
                qp2.setCompositionMode( QtGui.QPainter.CompositionMode_SourceOver )
                # Set the drawing to a special pattern
                brush = QtGui.QBrush(col,QtCore.Qt.DiagCrossPattern)
                qp2.setBrush(brush)

            qp2.drawPolygon( polyToDraw )

        # Draw outline of selected object dotted
        if self.highlightObj:
            brush = QtGui.QBrush(QtCore.Qt.NoBrush)
            qp2.setBrush(brush)
            qp2.setPen(QtCore.Qt.DashLine)
            polyToDraw = self.getPolygon(self.highlightObj) * QtGui.QTransform.fromScale(self.scale,self.scale)
            qp2.drawPolygon( polyToDraw )

        # End the drawing of the overlay
        qp2.end()
        # Save QPainter settings to stack
        qp.save()
        # Define transparency
        qp.setOpacity(self.transp)
        # Draw the overlay image
        qp.drawImage(self.xoff,self.yoff,overlay)
        # Restore settings
        qp.restore()

        return overlay

    def getBoundingBox(self, obj):
        bbox = QtCore.QRectF(obj.bbox[0], obj.bbox[1], obj.bbox[2], obj.bbox[3])
        bboxVis = QtCore.QRectF(obj.bboxVis[0], obj.bboxVis[1], obj.bboxVis[2], obj.bboxVis[3])
        return bbox, bboxVis

    def scaleBoundingBox(self, bbox):
        bboxToDraw = copy.deepcopy(bbox)
        x,y,w,h = bboxToDraw.getRect()
        bboxToDraw.setTopLeft(QtCore.QPointF(x*self.scale, y*self.scale))
        bboxToDraw.setSize(QtCore.QSizeF(w*self.scale, h*self.scale))
        return bboxToDraw

    # Draw the labels in the given QPainter qp
    # optionally provide a list of labels to ignore
    def drawBboxes(self, qp, ignore = []):
        if self.image.isNull() or self.w == 0 or self.h == 0:
            return
        if not self.annotation:
            return

        # The overlay is created in the viewing coordinates
        # This way, the drawing is more dense and the polygon edges are nicer
        # We create an image that is the overlay
        # Within this image we draw using another QPainter
        # Finally we use the real QPainter to overlay the overlay-image on what is drawn so far

        # The image that is used to draw the overlays
        overlay = QtGui.QImage( self.w, self.h, QtGui.QImage.Format_ARGB32_Premultiplied )
        # Fill the image
        col = QtGui.QColor(0, 0, 0, 0)
        overlay.fill( col )
        # Create a new QPainter that draws in the overlay image
        qp2 = QtGui.QPainter()
        qp2.begin(overlay)

        # Draw all objects
        for obj in self.annotation.objects:
            bbox, bboxVis = self.getBoundingBox(obj)
            bboxToDraw    = self.scaleBoundingBox(bbox)
            bboxVisToDraw = self.scaleBoundingBox(bbox)
            # The label of the object
            name      = obj.label
            # If we do not know a color for this label, warn the user
            if name not in name2labelCp:
                print("The annotations contain unknown labels. This should not happen. Please inform the datasets authors. Thank you!")
                print("Details: label '{}', file '{}'".format(name,self.currentLabelFile))
                continue

            # Reset brush for QPainter object
            qp2.setBrush(QtGui.QBrush())

            # Color from color table
            col   = QtGui.QColor( *name2labelCp[name].color     )

            if name2labelCp[name].hasInstances:
                if self.highlightObj and obj == self.highlightObj:
                    pen = QtGui.QPen(QtGui.QBrush( col ), 5.0)
                else:
                    pen = QtGui.QPen(QtGui.QBrush( col ), 3.0)
                qp2.setPen(pen)
                qp2.setOpacity(1.0)
                qp2.drawRect( bboxToDraw )
            
                if self.highlightObj and obj == self.highlightObj:
                    pen = QtGui.QPen(QtGui.QBrush( col ), 3.0, style=QtCore.Qt.DotLine)
                    qp2.setPen(pen)
                    qp2.setOpacity(1.0)
                    qp2.drawRect( bboxVisToDraw )
                else:
                    pen = QtGui.QPen(QtGui.QBrush( col ), 1.0, style=QtCore.Qt.DashLine)
                    qp2.setPen(pen)
                    qp2.setOpacity(1.0)
                    qp2.drawRect( bboxVisToDraw )
                    
                    qp2.setBrush(QtGui.QBrush( col, QtCore.Qt.SolidPattern ))
                    qp2.setOpacity(0.4)
                    qp2.drawRect( bboxVisToDraw )
            else:
                if self.highlightObj and obj == self.highlightObj:
                    pen = QtGui.QPen(QtGui.QBrush( col ), 3.0)
                    qp2.setPen(pen)
                    qp2.setBrush(QtGui.QBrush( col, QtCore.Qt.NoBrush ))
                else:
                    pen = QtGui.QPen(QtGui.QBrush( col ), 1.0)
                    qp2.setPen(pen)
                    qp2.setBrush(QtGui.QBrush( col, QtCore.Qt.DiagCrossPattern ))
                qp2.setOpacity(1.0)
                qp2.drawRect( bboxToDraw )

        # End the drawing of the overlay
        qp2.end()
        # Save QPainter settings to stack
        qp.save()
        # Define transparency
        qp.setOpacity(self.transp)
        # Draw the overlay image
        qp.drawImage(self.xoff,self.yoff,overlay)
        # Restore settings
        qp.restore()

        return overlay


    # Draw the label name next to the mouse
    def drawLabelAtMouse(self, qp):
        # Nothing to do without a highlighted object
        if not self.highlightObj:
            return
        # Nothing to without a mouse position
        if not self.mousePosOrig:
            return

        # Save QPainter settings to stack
        qp.save()

        # That is the mouse positiong
        mouse = self.mousePosOrig

        # Will show zoom
        showZoom = self.zoom and not self.image.isNull() and self.w and self.h

        # The text that is written next to the mouse
        mouseText = self.highlightObj.label

        # Where to write the text
        # Depends on the zoom (additional offset to mouse to make space for zoom?)
        # The location in the image (if we are at the top we want to write below of the mouse)
        off = 36
        if showZoom:
            off += self.zoomSize/2
        if mouse.y()-off > self.toolbar.height():
            top = mouse.y()-off
            btm = mouse.y()
            vAlign = QtCore.Qt.AlignTop
        else:
            # The height of the cursor
            if not showZoom:
                off += 20
            top = mouse.y()
            btm = mouse.y()+off
            vAlign = QtCore.Qt.AlignBottom

        # Here we can draw
        rect = QtCore.QRect()
        rect.setTopLeft(QtCore.QPoint(mouse.x()-200,top))
        rect.setBottomRight(QtCore.QPoint(mouse.x()+200,btm))

        # The color
        qp.setPen(QtGui.QColor('white'))
        # The font to use
        font = QtGui.QFont("Helvetica",20,QtGui.QFont.Bold)
        qp.setFont(font)
        # Non-transparent
        qp.setOpacity(1)
        # Draw the text, horizontally centered
        qp.drawText(rect,QtCore.Qt.AlignHCenter|vAlign,mouseText)
        # Restore settings
        qp.restore()

    # Draw the zoom
    def drawZoom(self,qp,overlay):
        # Zoom disabled?
        if not self.zoom:
            return
        # No image
        if self.image.isNull() or not self.w or not self.h:
            return
        # No mouse
        if not self.mousePosOrig:
            return

        # Abbrevation for the zoom window size
        zoomSize = self.zoomSize
        # Abbrevation for the mouse position
        mouse = self.mousePosOrig

        # The pixel that is the zoom center
        pix = self.mousePosScaled
        # The size of the part of the image that is drawn in the zoom window
        selSize = zoomSize / ( self.zoomFactor * self.zoomFactor )
        # The selection window for the image
        sel  = QtCore.QRectF(pix.x()  -selSize/2 ,pix.y()  -selSize/2 ,selSize,selSize  )
        # The selection window for the widget
        view = QtCore.QRectF(mouse.x()-zoomSize/2,mouse.y()-zoomSize/2,zoomSize,zoomSize)
        if overlay :
            overlay_scaled = overlay.scaled(self.image.width(), self.image.height())
        else :
            overlay_scaled = QtGui.QImage( self.image.width(), self.image.height(), QtGui.QImage.Format_ARGB32_Premultiplied )

        # Show the zoom image
        qp.save()
        qp.drawImage(view,self.image,sel)
        qp.setOpacity(self.transp)
        qp.drawImage(view,overlay_scaled,sel)
        qp.restore()

    # Draw disparities
    def drawDisp( self , qp ):
        if not self.dispOverlay:
            return

        # Save QPainter settings to stack
        qp.save()
        # Define transparency
        qp.setOpacity(self.transp)
        # Draw the overlay image
        qp.drawImage(QtCore.QRect( self.xoff, self.yoff, self.w, self.h ),self.dispOverlay)
        # Restore settings
        qp.restore()

        return self.dispOverlay



    #############################
    ## Mouse/keyboard events
    #############################

    # Mouse moved
    # Need to save the mouse position
    # Need to drag a polygon point
    # Need to update the mouse selected object
    def mouseMoveEvent(self,event):
        if self.image.isNull() or self.w == 0 or self.h == 0:
            return

        mousePosOrig = QtCore.QPointF( event.x() , event.y() )
        mousePosScaled = QtCore.QPointF( float(mousePosOrig.x() - self.xoff) / self.scale , float(mousePosOrig.y() - self.yoff) / self.scale )
        mouseOutsideImage = not self.image.rect().contains( mousePosScaled.toPoint() )

        mousePosScaled.setX( max( mousePosScaled.x() , 0. ) )
        mousePosScaled.setY( max( mousePosScaled.y() , 0. ) )
        mousePosScaled.setX( min( mousePosScaled.x() , self.image.rect().right() ) )
        mousePosScaled.setY( min( mousePosScaled.y() , self.image.rect().bottom() ) )

        if not self.image.rect().contains( mousePosScaled.toPoint() ):
            print(self.image.rect())
            print(mousePosScaled.toPoint())
            self.mousePosScaled = None
            self.mousePosOrig = None
            self.updateMouseObject()
            self.update()
            return

        self.mousePosScaled    = mousePosScaled
        self.mousePosOrig      = mousePosOrig
        self.mouseOutsideImage = mouseOutsideImage

        # Redraw
        self.updateMouseObject()
        self.update()

    # Mouse left the widget
    def leaveEvent(self, event):
        self.mousePosOrig = None
        self.mousePosScaled = None
        self.mouseOutsideImage = True


    # Mouse wheel scrolled
    def wheelEvent(self, event):
        ctrlPressed = event.modifiers() & QtCore.Qt.ControlModifier

        deltaDegree = event.delta() / 8 # Rotation in degree
        deltaSteps  = deltaDegree / 15 # Usually one step on the mouse is 15 degrees

        if ctrlPressed:
            self.transp = max(min(self.transp+(deltaSteps*0.1),1.0),0.0)
            self.update()
        else:
            if self.zoom:
                # If shift is pressed, change zoom window size
                if event.modifiers() and QtCore.Qt.Key_Shift:
                    self.zoomSize += deltaSteps * 10
                    self.zoomSize = max( self.zoomSize, 10   )
                    self.zoomSize = min( self.zoomSize, 1000 )
                # Change zoom factor
                else:
                    self.zoomFactor += deltaSteps * 0.05
                    self.zoomFactor = max( self.zoomFactor, 0.1 )
                    self.zoomFactor = min( self.zoomFactor, 10 )
                self.update()


    #############################
    ## Little helper methods
    #############################

    # Helper method that sets tooltip and statustip
    # Provide an QAction and the tip text
    # This text is appended with a hotkeys and then assigned
    def setTip( self, action, tip ):
        tip += " (Hotkeys: '" + "', '".join([str(s.toString()) for s in action.shortcuts()]) + "')"
        action.setStatusTip(tip)
        action.setToolTip(tip)

    # Update the object that is selected by the current mouse curser
    def updateMouseObject(self):
        self.mouseObj   = -1
        if self.mousePosScaled is None:
            return
        for idx in reversed(range(len(self.annotation.objects))):
            obj = self.annotation.objects[idx]
            if obj.objectType == CsObjectType.POLY:
                if self.getPolygon(obj).containsPoint(self.mousePosScaled, QtCore.Qt.OddEvenFill):
                    self.mouseObj = idx
                    break
            elif obj.objectType == CsObjectType.BBOX:
                bbox, _ = self.getBoundingBox(obj)
                if bbox.contains(self.mousePosScaled):
                    self.mouseObj = idx
                    break

    # Clear the current labels
    def clearAnnotation(self):
        self.annotation = None
        self.currentLabelFile = ""

    def getCityFromUser(self):
        # Reset the status bar to this message when leaving
        restoreMessage = self.statusBar().currentMessage()

        if 'CITYSCAPES_DATASET' in os.environ:
            csPath = os.environ['CITYSCAPES_DATASET']
        else:
            csPath = os.path.join(os.path.dirname(os.path.realpath(__file__)),'..','..')

        availableCities = []
        annotations = [ "gtFine" , "gtCoarse" , "gtBboxCityPersons" ]
        splits      = [ "train_extra" , "train"  , "val" , "test" ]
        for gt in annotations:
            for split in splits:
                cities = glob.glob(os.path.join(csPath, gt, split, '*'))
                cities.sort()
                availableCities.extend( [ (split,gt,os.path.basename(c)) for c in cities if os.listdir(c) ] )

        # List of possible labels
        items = [split + ", " + gt + ", " + city for (split,gt,city) in availableCities]

        # Specify title
        dlgTitle = "Select new city"
        message = dlgTitle
        question = dlgTitle
        message = "Select city for viewing"
        question = "Which city would you like to view?"
        self.statusBar().showMessage(message)

        if items:
            # Create and wait for dialog
            (item, ok) = QtGui.QInputDialog.getItem(self, dlgTitle, question,
                                                    items, 0, False)

            # Restore message
            self.statusBar().showMessage(restoreMessage)

            if ok and item:
                (split, gt, city) = [str(i) for i in item.split(', ')]
                if split == 'test' and not self.showDisparity:
                    self.transp = 0.1
                else:
                    self.transp = 0.5
                self.city      = os.path.normpath(os.path.join(csPath, "leftImg8bit", split, city))
                self.labelPath = os.path.normpath(os.path.join(csPath, gt           , split, city))
                self.dispPath  = os.path.normpath(os.path.join(csPath, "disparity"  , split, city))
                if gt in [ "gtFine", "gtCoarse" ]:
                    self.gtType = CsObjectType.POLY
                elif gt in [ "gtBboxCityPersons" ]:
                    self.gtType = CsObjectType.BBOX
                self.loadCity()
                self.imageChanged()

        else:

            warning = ""
            warning += "The data was not found. Please:\n\n"
            warning += " - make sure the scripts folder is in the Cityscapes root folder\n"
            warning += "or\n"
            warning += " - set CITYSCAPES_DATASET to the Cityscapes root folder\n"
            warning += "       e.g. 'export CITYSCAPES_DATASET=<root_path>'\n"

            reply = QtGui.QMessageBox.information(self, "ERROR!", warning,
                                                  QtGui.QMessageBox.Ok)
            if reply == QtGui.QMessageBox.Ok:
                sys.exit()

        return

    # Determine if the given candidate for a label path makes sense
    def isLabelPathValid(self, labelPath):
        return os.path.isdir(labelPath)

    # Get the filename where to load labels
    # Returns empty string if not possible
    def getLabelFilename(self):
        # And we need to have a directory where labels should be searched
        if not self.labelPath:
            return ""
        # Without the name of the current images, there is also nothing we can do
        if not self.currentFile:
            return ""
        # Check if the label directory is valid.
        if not self.isLabelPathValid(self.labelPath):
            return ""

        # Generate the filename of the label file
        filename = os.path.basename(self.currentFile)
        filename = filename.replace(self.imageExt, self.gtExt)
        filename = os.path.join(self.labelPath, filename)
        search   = glob.glob(filename)
        if not search:
            return ""
        filename = os.path.normpath(search[0])
        return filename

    # Get the filename where to load disparities
    # Returns empty string if not possible
    def getDisparityFilename( self ):
        # And we need to have a directory where disparities should be searched
        if not self.dispPath:
            return ""
        # Without the name of the current images, there is also nothing we can do
        if not self.currentFile:
            return ""
        # Check if the label directory is valid.
        if not os.path.isdir(self.dispPath):
            return ""

        # Generate the filename of the label file
        filename = os.path.basename( self.currentFile )
        filename = filename.replace( self.imageExt , self.dispExt )
        filename = os.path.join( self.dispPath , filename )
        filename = os.path.normpath(filename)
        return filename

    # Disable the popup menu on right click
    def createPopupMenu(self):
        pass
示例#39
0
def json2labelImg(inJson,outImg,encoding="ids"):
    annotation = Annotation()
    annotation.fromJsonFile(inJson)
    labelImg   = createLabelImage( annotation , encoding )
    labelImg.save( outImg )
示例#40
0
 def store_annotations(self, annotations):
     for annotation in annotations:
         ann = Annotation()
         ann.parse_json(annotation)
         ann.add_to_graph(self.sparql)
     return
def json2instanceImg(inJson,outImg,encoding="ids"):
    annotation = Annotation()
    annotation.fromJsonFile(inJson)
    instanceImg = createInstanceImage( annotation , encoding )
    instanceImg.save( outImg )
 def __init__(self, limit=10000, **options):
     Annotation.__init__(self, **options)
     self.limit = limit
    def __init__(self, description, attributes, inner_attributes=None,
            mode='split_workbooks', single_workbook_name=None,
            min_tokens=2, max_tokens=3000, **options):
        '''
        Classify sentences based on some of their attributes, and write
        them to XLS files. Lists of sentences will be taken from different
        users, distributed as evenly as possible (cf. MixUsers).

        sentences:
            list of sentences (same as Filter.sentences). [Inherited
            from Annotation base class]

        description:
            a textual description of the annotation. Will appear in a
            'meta' sheet of each workbook. Mandatory.

        attributes:
            a single attribute, or a tuple of attributes, by which
            the sentences will be classified into annotation files (the
            exact behavior depends on the mode)
            
        inner_attributes:
            only applicable for the split workbooks mode. Combinations of
            the inner attributes will form the names of sheets within
            each workbook

        mode:
            'single_workbook': one workbook with different sheet for each
                attribute combination
            'split_workbooks': separate workbook for each attribute combination
            'single_sheet': single workbook with a single sheet for all
                attribute combinations (but combination will appear in a
                dedicated spreadsheet column)

        single_workbook_name: 
            name of single workbook, if applicable

        min_tokens:
            if an attribute combination has less than this number of occurences
            discard this combination (do not write it to annotation files)

        max_tokens:
            stop writing sentences with any given attribute combination after
            this amount of tokens of this combination have been written

        Example:
        ByAttributeAnnotation("30 to 40 dative verbs, topicalized",
            sentences=sentences, attributes=['lemma', 'argument'])
        '''

        Annotation.__init__(self, description, **options)
        self.attributes = attributes

        if mode not in ('split_workbooks', 'single_workbook', 'single_sheet'):
            raise ValueError('unknown mode "%s"' % mode)

        if mode != 'split_workbooks' and inner_attributes:
            raise ValueError('inner_attributes can only be set when' \
                    'mode is "split_workbooks"')

        self.mode = mode
        self.inner_attributes = inner_attributes
        self.single_workbook_name = single_workbook_name
        self.min_tokens = min_tokens
        self.max_tokens = max_tokens
        self.workbooks = {}