Ejemplo n.º 1
0
def get_glyphs(chars, font, size, coords=None):
    coords_serial = None if (coords is None
                             or len(coords) == 0) else json.dumps(coords)
    chars_serial = json.dumps(chars)

    # Check if glyphs already exist
    glyph_sets = (GlyphSet.select().where(
        GlyphSet.font_id == font.id, GlyphSet.size == size,
        GlyphSet.coords == coords_serial,
        GlyphSet.chars == chars_serial).execute())
    if len(glyph_sets) > 0:
        return glyph_sets[0].id

    renderer = shapes.GlyphRenderer(io.BytesIO(font.font_file))
    bitmaps = renderer.bitmaps(chars, size, coords)

    glyph_set = GlyphSet(font=font,
                         size=size,
                         coords=coords_serial,
                         chars=chars_serial)
    glyph_set.save()

    glyphs = []
    for i in range(len(chars)):
        glyph = Glyph(glyph_set_id=glyph_set.id,
                      character=chars[i],
                      bitmap=bitmaps[i])
        glyphs.append(glyph)

    with data.db.atomic():
        Glyph.bulk_create(glyphs, batch_size=100)

    return glyph_set.id
Ejemplo n.º 2
0
def render_hausdorff_distance(shape_distance_id):
    Glyph1 = Glyph.alias()
    Glyph2 = Glyph.alias()
    query = (ShapeDistance
                    .select()
                    .join(Glyph1, on=ShapeDistance.glyph1)
                    .switch(ShapeDistance)
                    .join(Glyph2, on=ShapeDistance.glyph2)
                    .where(
                        ShapeDistance.id == shape_distance_id))
    result = query[0]
    points1 = json.loads(result.points1)
    points2 = json.loads(result.points2)
    bitmap1 = result.glyph1.bitmap
    bitmap2 = result.glyph2.bitmap
    
    bitmap = visualization.render_distance_overlay(
        result.glyph1.character, 
        result.glyph2.character, 
        bitmap1,
        bitmap2,
        points1,
        points2,
        result.distance,
        result.distance)
    
    return bitmap
Ejemplo n.º 3
0
    def test_preprocess_sample(self):
        raw_dict, prep_dict = np.array(list(raw_glyphs_dict(mapping))), preprocessed_glyphs_dict(mapping)

        zipped_dicts = list(zip(raw_dict, prep_dict))
        zipped_dicts = random.sample(list(zipped_dicts), 50)

        raw_sample = [Glyph(**pair[0]) for pair in zipped_dicts]
        prep_sample = [Glyph(**pair[1]) for pair in zipped_dicts]

        plt.figure(figsize=(14, 10))

        zipped = []
        for i in range(len(raw_sample)):
            zipped.append(raw_sample[i])
            zipped.append(prep_sample[i])
        draw_chars(zipped)
Ejemplo n.º 4
0
def get_correlation(glyph_set_id, sound_metric, shape_metric):
    # Fetch from db if it's already calculated
    query = (Correlation.select().where(
        (Correlation.glyph_set_id == glyph_set_id)
        & (Correlation.sound_metric == sound_metric)
        & (Correlation.shape_metric == shape_metric)))
    if len(query) > 0:
        return query.first()

    sound_query = (SoundDistance.select().where(
        SoundDistance.metric == sound_metric).order_by(SoundDistance.char1,
                                                       SoundDistance.char2))

    Glyph1 = Glyph.alias()
    Glyph2 = Glyph.alias()
    shape_query = (ShapeDistance.select().join(
        Glyph1, on=ShapeDistance.glyph1).switch(ShapeDistance).join(
            Glyph2, on=ShapeDistance.glyph2).where(
                (Glyph1.glyph_set_id == glyph_set_id)
                & (Glyph2.glyph_set_id == glyph_set_id)
                & (ShapeDistance.metric == shape_metric)).order_by(
                    Glyph1.character, Glyph2.character))

    sound_distances = [s.distance for s in sound_query]
    shape_distances = [s.distance for s in shape_query]

    if (len(sound_distances) != len(shape_distances)):
        raise Exception(
            "Numer of shape ({0}) and sound ({1}) distances are not equal for glyph set {2}, sound metric {3}, shape metric {4}"
            .format(len(shape_distances), len(sound_distances), glyph_set_id,
                    sound_metric, shape_metric))

    if np.std(shape_distances) == 0:
        raise Exception(
            "Unable to calculate correlation for glyph set {0}: standard deviation of shape distances is zero."
            .format(glyph_set_id))

    corr_value = pearsonr(shape_distances, sound_distances)

    correlation = Correlation(glyph_set=glyph_set_id,
                              shape_metric=shape_metric,
                              sound_metric=sound_metric,
                              r_value=corr_value[0],
                              p_value=corr_value[1])
    correlation.save()

    return correlation
Ejemplo n.º 5
0
    def test_compare_rotation(self):
        character_ids = ['I', 'H', 'c']
        rotation_sequence = []
        raw_sequence = []

        for character_id in character_ids:
            glyph = test_glyphs[character_id]
            raw_char = Glyph(character_id, "test_sample_123" + character_id, [np.array(stroke) for stroke in glyph['strokes']])

            centre_of_mass = _centre_of_mass(raw_char.strokes)
            slant = _calculate_glyph_slant(raw_char.strokes)
            rotated_strokes = _rotate_strokes(raw_char.strokes, centre_of_mass, slant)
            glyph = Glyph(character_id, "rotated_sample_123" + character_id, [np.array(stroke) for stroke in rotated_strokes])

            raw_sequence.append(raw_char)
            rotation_sequence.append(glyph)

        draw_chars(raw_sequence + rotation_sequence, 3)
Ejemplo n.º 6
0
    def test_slant_correction(self):
        character_id = 'a'
        character_id = 'h'

        glyph = test_glyphs[character_id]
        raw_char = Glyph(character_id, "test_sample_123", [np.array(stroke) for stroke in glyph['strokes']])
        rotation_sequence = [raw_char]

        for i in range(9):
            centre_of_mass = _centre_of_mass(raw_char.strokes)
            slant = _calculate_glyph_slant(raw_char.strokes)
            rotated_strokes = _rotate_strokes(raw_char.strokes, centre_of_mass, slant)
            rotated_char = Glyph(character_id, "rotated_sample_123", [np.array(stroke) for stroke in rotated_strokes])
            rotation_sequence.append(rotated_char)

        # draw_chars(rotation_sequence, 10)
        np.testing.assert_array_equal(rotation_sequence[1].strokes[0], rotation_sequence[-1].strokes[0])
        np.testing.assert_array_equal(rotation_sequence[1].strokes[1], rotation_sequence[-1].strokes[1])
Ejemplo n.º 7
0
def get_and_save_shape_distances(glyph_set_id):
    glyph_query = Glyph.select().where(Glyph.glyph_set_id == glyph_set_id)
    glyphs = [glyph for glyph in glyph_query]

    # Get existing glyph distances
    Glyph1 = Glyph.alias()
    Glyph2 = Glyph.alias()

    shape_query = (ShapeDistance.select().join(
        Glyph1, on=ShapeDistance.glyph1).switch(ShapeDistance).join(
            Glyph2, on=ShapeDistance.glyph2).where(
                (Glyph1.glyph_set_id == glyph_set_id)
                & (Glyph2.glyph_set_id == glyph_set_id)))
    if len(shape_query) > 0:
        # distances already calculated, return existing values
        return [s for s in shape_query]

    shape_distances = get_shape_distances(glyphs)

    with data.db.atomic():
        ShapeDistance.bulk_create(shape_distances, batch_size=100)

    return shape_distances
Ejemplo n.º 8
0
def create_normalized_path(raw_char: Glyph):
    strokes_number = len(raw_char.strokes)
    normalized_path = [[] for _ in range(strokes_number)]
    section_length = _compute_section_length(strokes_number, raw_char.strokes)

    for i in range(strokes_number):
        stroke = raw_char.strokes[i]
        prev_point = stroke[0]
        normalized_path[i].append(prev_point)
        j = 1
        while j < len(stroke):
            prev_point = normalized_path[i][-1]
            point = stroke[j]
            prev_distance = 0
            points_distance = _distance(prev_point, point)

            k = j
            while points_distance < section_length and k + 1 < len(stroke):
                prev_point = stroke[k]
                point = stroke[k + 1]
                prev_distance = points_distance
                points_distance += points_distance(prev_point, point)
                k += 1

            utvec = [point[0] - prev_point[0], point[1] - prev_point[1]]
            norm = points_distance(point, prev_point)

            j = k if k != j else j + 1

            if norm == 0 or j == len(stroke):
                continue
            utvec = [utvec[0] / norm, utvec[1] / norm]
            path_point = (round(prev_point[0] + utvec[0] *
                                (section_length - prev_distance)),
                          round(prev_point[1] + utvec[1] *
                                (section_length - prev_distance)))
            normalized_path[i].append(path_point)

    length = 0
    for i in range(strokes_number):
        length += len(normalized_path[i])
    raw_char.strokes = normalized_path
Ejemplo n.º 9
0
 def setUpClass(cls):
     prep_dict = np.array(preprocessed_glyphs_dict(mapping))
     prep_sample = [Glyph(**g) for g in prep_dict]
     cls.prep_sample = random.sample(prep_sample, 50)