Exemplo n.º 1
0
 def test_parse_grammar(self):
     filepath = os.path.dirname(os.path.dirname(
         __file__)) + u'/test/test_data/mff-muscima-classes-annot.deprules'
     node_classes_path = os.path.dirname(os.path.dirname(
         __file__)) + u'/test/test_data/mff-muscima-classes-annot.xml'
     node_classes = parse_node_classes(node_classes_path)
     node_classes_dict = {node_class.name for node_class in node_classes}
     dependency_graph = DependencyGrammar(grammar_filename=filepath,
                                          alphabet=node_classes_dict)
     self.assertEqual(646, len(dependency_graph.rules))
Exemplo n.º 2
0
    def test_node_class_parsing(self):
        # Arrange
        expected_number_of_classes = 163

        # Act
        node_classes = parse_node_classes(
            "test/test_data/mff-muscima-classes-annot.xml")

        # Assert
        self.assertEqual(len(node_classes), expected_number_of_classes)
        self.assertEqual(node_classes[0].name, "noteheadFull")
def get_categories(
        node_classes_file_path) -> Tuple[List[Dict[str, str]], Dict[str, str]]:
    node_classes = parse_node_classes(node_classes_file_path)
    categories = []
    for node_class in node_classes:
        categories.append({
            'id': node_class.class_id,
            'name': node_class.name,
            'supercategory': node_class.group_name.split("/")[0],
        })

    class_to_id_mapping = {c.name: c.class_id for c in node_classes}
    return categories, class_to_id_mapping
Exemplo n.º 4
0
    def test_node_class_parsing(self):
        # Arrange
        expected_number_of_classes = 163

        # Act
        test_data_dir = os.path.join(
            os.path.dirname(os.path.dirname(__file__)), 'test', 'test_data')
        classes_file = os.path.join(test_data_dir,
                                    'mff-muscima-classes-annot.xml')

        node_classes = parse_node_classes(classes_file)

        # Assert
        self.assertEqual(len(node_classes), expected_number_of_classes)
        self.assertEqual(node_classes[0].name, "noteheadFull")
Exemplo n.º 5
0
    def render_node_masks(self, raw_data_directory: str,
                          destination_directory: str, mask_type: MaskType):
        """
        Extracts all symbols from the raw XML documents and generates individual symbols from the masks

        :param raw_data_directory: The directory, that contains the xml-files and matching images
        :param destination_directory: The directory, in which the symbols should be generated into.
                                      Per file, one mask will be generated.
        :param mask_type: The type of masks that you want to generate, e.g., masks for each node or staff lines only.
        """
        print("Extracting Masks from Muscima++ Dataset...")

        node_classes = parse_node_classes(
            os.path.join(raw_data_directory, "v2.0", "specifications",
                         "mff-muscima-mlclasses-annot.xml"))
        for index, node_class in enumerate(node_classes):
            self.class_to_color_mapping[node_class.name] = index + 1

        file_paths = self.__get_all_file_paths(raw_data_directory)
        for xml_file, png_file in tqdm(file_paths,
                                       desc="Generating mask images"):
            original_image = Image.open(png_file)  # type: Image.Image
            nodes = read_nodes_from_file(xml_file)
            destination_filename = os.path.basename(xml_file).replace(
                ".xml", ".png")
            if mask_type == MaskType.NODES_SEMANTIC_SEGMENTATION:
                self.__render_masks_of_nodes_for_semantic_segmentation(
                    nodes, destination_directory, destination_filename,
                    original_image.width, original_image.height)
            if mask_type == MaskType.STAFF_LINES_INSTANCE_SEGMENTATION:
                self.__render_masks_of_staff_lines_for_instance_segmentation(
                    nodes, destination_directory, destination_filename,
                    original_image.width, original_image.height)
            if mask_type == MaskType.STAFF_BLOBS_INSTANCE_SEGMENTATION:
                self.__render_masks_of_staff_blob_for_instance_segmentation(
                    nodes, destination_directory, destination_filename,
                    original_image.width, original_image.height)
            original_image.close()
Exemplo n.º 6
0
def load_grammar(filename):
    mungo_classes_file = os.path.splitext(filename)[0] + '.xml'
    mlclass_dict = {m.name: m for m in parse_node_classes(mungo_classes_file)}
    g = DependencyGrammar(grammar_filename=filename,
                          alphabet=set(mlclass_dict.keys()))
    return g
Exemplo n.º 7
0
def main(args):
    logging.info('Starting main...')
    _start_time = time.clock()

    ###############################################################
    # Preparation: loading the parsing apparatus

    with open(args.vectorizer) as hdl:
        vectorizer = pickle.load(hdl)
    feature_extractor = PairwiseClassificationFeatureExtractor(
        vectorizer=vectorizer)

    with open(args.parser) as hdl:
        classifier = pickle.load(hdl)

    mlclass_list = parse_node_classes(args.mlclasses)
    mlclasses = {m.name for m in mlclass_list}

    grammar = DependencyGrammar(grammar_filename=args.grammar,
                                alphabet=mlclasses)

    parser = PairwiseClassificationParser(grammar=grammar,
                                          classifier=classifier,
                                          feature_extractor=feature_extractor)

    #################################################################
    logging.info('Load graph')
    nodes = read_nodes_from_file(args.input_mung)

    logging.info('Filter very small')
    very_small_nodes = find_very_small_nodes(nodes,
                                             bbox_threshold=40,
                                             mask_threshold=35)
    very_small_nodes = set(very_small_nodes)
    nodes = [c for c in nodes if c not in very_small_nodes]

    logging.info('Parsing')
    nodes = do_parse(nodes, parser=parser)

    # Filter contained here.
    if args.filter_contained:
        logging.info('Finding contained Nodes...')
        contained = find_contained_nodes(nodes, mask_threshold=0.95)
        NEVER_DISCARD_CLASSES = ['key_signature', 'time_signature']
        contained = [
            c for c in contained if c.class_name not in NEVER_DISCARD_CLASSES
        ]

        _contained_counts = collections.defaultdict(int)
        for c in contained:
            _contained_counts[c.class_name] += 1
        logging.info('Found {} contained Nodes'.format(len(contained)))
        logging.info('Contained counts:\n{0}'.format(
            pprint.pformat(dict(_contained_counts))))
        nodes = remove_contained_nodes(nodes, contained)
        logging.info('Removed contained Nodes: {}...'.format(
            [m.id for m in contained]))

    logging.info('Inferring staffline & staff objects, staff relationships')
    nodes = process_stafflines(nodes)

    if args.add_key_signatures:
        nodes = add_key_signatures(nodes)

    logging.info('Filter invalid edges')
    graph = NotationGraph(nodes)
    # Operatng on the graph changes the Nodes
    #  -- the graph only keeps a pointer
    wrong_edges = find_wrong_edges(nodes, grammar)
    for f, t in wrong_edges:
        graph.remove_edge(f, t)

    logging.info('Add precedence relationships, factored only by staff')
    prec_edges = infer_precedence_edges(nodes)
    nodes = add_precedence_edges(nodes, prec_edges)

    logging.info('Ensuring MIDI can be built')
    mf = build_midi(nodes,
                    retain_pitches=True,
                    retain_durations=True,
                    retain_onsets=True,
                    tempo=180)

    logging.info('Save output')
    docname = os.path.splitext(os.path.basename(args.output_mung))[0]
    xml = export_node_list(nodes, document=docname, dataset='FNOMR_results')
    with open(args.output_mung, 'w') as out_stream:
        out_stream.write(xml)
        out_stream.write('\n')

    _end_time = time.clock()
    logging.info(
        'baseline_process_symbols.py done in {0:.3f} s'.format(_end_time -
                                                               _start_time))