Skip to content
This repository was archived by the owner on Aug 15, 2019. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions demos/rune_recognition/generate_rune_data_for_model_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import pickle
import os
import numpy as np
import re
from PIL import Image
from os import listdir
from os.path import isfile, join
import json

path_to_images = 'runes/'
output_file_image_collage = 'output.png'
output_file_labels_packed = 'labels'
output_file_label_names = 'labelNames.json'
number_of_channels = 1

def pack(classes, labels):
n_classes = len(classes)
length = len(labels)
result = [np.NaN] * length * n_classes

i = 0
while i < length:
label_candidate = labels[i]
index = classes.index(label_candidate)
offset = (i * n_classes)
result[offset + index] = 1
i += 1
return result

def select_alpha_channel(image_array):
return np.array([image_array[3]])

def determine_image_alpha_channel(image):
# Image represented as tensor (width x height x channels)
image_as_array = np.array(image)
# Select just the alpha channel values from tensor
return np.apply_along_axis(select_alpha_channel, axis=2, arr=image_as_array)

paths_to_images = [f for f in listdir(path_to_images) if
isfile(join(path_to_images, f)) and re.match('.*\.png', f)]
example_file_pattern = r'.*_([^(\s]+)(?: ?\([0-9]+\))?\.png$'


# Determine label from filename
labels = [re.search(example_file_pattern, s).group(1) for s in paths_to_images]
if len(labels) != len(paths_to_images):
raise ValueError('Expected number of labels to be equal to the number of example images!')

# Get array of distinct labels
labels_clear_text = np.unique(np.asarray(labels))
indexed_classes = labels_clear_text.tolist()
labels5 = pack(indexed_classes, labels)
print('...', len(labels_clear_text), 'classes found')

# Pack labels into the uint8 array that demo builder expects
packed_labels = np.asarray(labels5).astype('uint8')
packed_labels.tofile(output_file_labels_packed)
print('...Saved packed labels to:', output_file_labels_packed)

# Also emit a list of the names that we associate with the labels
with open(output_file_label_names, 'w') as outfile:
json.dump(indexed_classes, outfile)
print('...Saved label names to:', output_file_label_names)

# Load all image data into array. Note we load just one channel: transparency (the alpha channel)
loaded_images = [determine_image_alpha_channel(
Image.open(join(path_to_images, path_to_image))) for path_to_image in
paths_to_images]
images_array = np.array(loaded_images)

print('Read', images_array.shape[0], 'images')
print('min/max pixel values: ', images_array.min(), '/', images_array.max())

# Make each image take a single row in the big batch image by flattening the
# width (2nd) and height (3rd) dimension.
# a has shape N x (Width*Height) x Channels.
images_array = images_array.reshape([images_array.shape[0], -1, number_of_channels]).squeeze()
im = Image.fromarray(images_array)
im.save(output_file_image_collage)
print('Saved image with width/height', im.size, 'at', output_file_image_collage)
170 changes: 170 additions & 0 deletions demos/rune_recognition/generate_train_examples_runes.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Generate training examples for Runic character</title>
<link rel="stylesheet" media="screen" href="https://fontlibrary.org/face/runasans" type="text/css"/>
<style>
canvas {
-moz-user-select: -moz-none;
-khtml-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
} </style>
</head>
<body>
<p>Draw the following rune</p>
<div>

<span id="showchar" style="border: 1px solid black;font-size: 124px; font-family: RunaSans">

</span>
</div>
<p>In this canvas</p>
<div>
<input type="button" value="Clear canvas" id="clr" size="23" onclick="clearCanvas()">
</div>

<div>
<canvas id="can" width="32" height="32"
style="width:320px;height:320px;border:2px solid;"></canvas>
<div>
<input type="button" value="Save rune (or press spacebar)" id="btn" size="30" onclick="saveAndSetNewRune()"/>
</div>
</div>

<script type="text/javascript">
var name = prompt("What's your name?") || new Date().toISOString();

var canvas, ctx, flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false;

var x = "black",
y = 2;

var char = "_";

var allChars = [
"ᚠ", "ᚡ", "ᚢ", "ᚣ", "ᚤ", "ᚥ", "ᚦ", "ᚧ", "ᚨ", "ᚩ", "ᚪ", "ᚫ", "ᚬ", "ᚭ", "ᚮ", "ᚯ",
"ᚰ", "ᚱ", "ᚲ", "ᚳ", "ᚴ", "ᚵ", "ᚶ", "ᚷ", "ᚸ", "ᚹ", "ᚺ", "ᚻ", "ᚼ", "ᚽ", "ᚾ", "ᚿ",
"ᛀ", "ᛁ", "ᛂ", "ᛃ", "ᛄ", "ᛅ", "ᛆ", "ᛇ", "ᛈ", "ᛉ", "ᛊ", "ᛋ", "ᛌ", "ᛍ", "ᛎ", "ᛏ",
"ᛐ", "ᛑ", "ᛒ", "ᛓ", "ᛔ", "ᛕ", "ᛖ", "ᛗ", "ᛘ", "ᛙ", "ᛚ", "ᛛ", "ᛜ", "ᛝ", "ᛞ", "ᛟ",
"ᛠ", "ᛡ", "ᛢ", "ᛣ", "ᛤ", "ᛥ", "ᛦ", "ᛧ", "ᛨ", "ᛩ", "ᛪ", "᛫", "᛬", "᛭", "ᛮ", "ᛯ",
"ᛰ", "ᛱ", "ᛲ", "ᛳ", "ᛴ", "ᛵ", "ᛶ", "ᛷ", "ᛸ"
];

var charIndex = 0;

function init() {
canvas = document.getElementById('can');
ctx = canvas.getContext("2d");

canvas.addEventListener("mousemove", function (e) {
findxy('move', e)
}, false);
canvas.addEventListener("mousedown", function (e) {
findxy('down', e)
}, false);
canvas.addEventListener("mouseup", function (e) {
findxy('up', e)
}, false);
canvas.addEventListener("mouseout", function (e) {
findxy('out', e)
}, false);
}

function draw() {
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}

function clearCanvas() {
ctx.clearRect(0, 0, 320, 320);
}

function save() {
var a = document.createElement('a');
a.href = canvas.toDataURL();
a.download = "drawn_by_" + name + "_" + char + ".png";
a.click();
}

function findxy(res, e) {
if (res === 'down') {
prevX = currX;
prevY = currY;
currX = (e.clientX - canvas.offsetLeft) / 10;
currY = (e.clientY - canvas.offsetTop) / 10;

flag = true;
dot_flag = true;
if (dot_flag) {
ctx.beginPath();
ctx.fillStyle = x;
ctx.fillRect(currX, currY, 1, 1);
ctx.closePath();
dot_flag = false;
}
}
if (res === 'up' || res === "out") {
flag = false;
}
if (res === 'move') {
if (flag) {
prevX = currX;
prevY = currY;
currX = (e.clientX - canvas.offsetLeft) / 10;
currY = (e.clientY - canvas.offsetTop) / 10;

ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}
}
}


function setNewRune(setValue) {
clearCanvas();

if (typeof setValue === "number") {
charIndex = setValue;
} else {
charIndex = (charIndex + 1) % allChars.length;
}
char = allChars[charIndex];
document.getElementById("showchar").innerHTML = char;
}

function saveAndSetNewRune() {
save();
setNewRune();
}

window.onkeyup = function (e) {
var key = e.keyCode ? e.keyCode : e.which;

if (key === 32) {
saveAndSetNewRune();
}
};

init();
setNewRune(0);
</script>
</body>
</html>
Loading