diff --git a/src/ImageGenerator.py b/src/ImageGenerator.py new file mode 100644 index 0000000..c5e4ec3 --- /dev/null +++ b/src/ImageGenerator.py @@ -0,0 +1,351 @@ +#from IPython.core.completer import back_latex_name_matches +#from PIL import Image, ImageDraw, ImageFont +# get an image +#base = Image.open('Pillow/Tests/images/hopper.png').convert('RGBA') + +# make a blank image for the text, initialized to transparent text color +#img = Image.new('RGB', (30, 30), (255,255,255)) +# +# # get a font +# fnt = ImageFont.truetype('resources\HelveticaNeueLight.ttf', 40) +# # get a drawing context +# d = ImageDraw.Draw(img) +# +# +# # draw text +# d.text((0,0), "T", font=fnt, fill=(0,0,0)) +# text_width, text_height = d.textsize('T') +# print("width {:d} - height {:d}".format(text_width, text_height)) + +# ------------------------------ Generate Characters ----------------------------# +# Import python imaging libs +from PIL import Image +from PIL import ImageDraw +from PIL import ImageFont, ImageFilter +#from skimage.util import random_noise +#from scipy.misc import toimage +import numpy as np +# Import operating system lib +import os, errno + +# Import random generator +from random import randint +import shutil +import csv +import pickle + + +# ------------------------------------ Cleanup ----------------------------------# + +def cleanup(): + # Delete ds_store file + if os.path.isfile(font_dir+ '.DS_Store'): + os.unlink(font_dir + '.DS_Store') + + if os.path.exists(out_dir): + shutil.rmtree(out_dir, ignore_errors=True) + # Delete all files from output directory + #for file in os.listdir('results'): + # file_path = os.path.join('results', file) + # if os.path.isfile(file_path): + # os.unlink(file_path) + return + +def generateCharacters(mode ='image', sample = True): + if(mode == 'image'): + myoffsetsX = offsetsX_sample if sample else offsetsX + myoffsetsY = offsetsY_sample if sample else offsetsY + mydegrees = degrees_sample if sample else degrees + mycharacters = characters_sample if sample else characters + cleanup() + # Counter + k = 1 + i= 0 + for dirname, dirnames, filenames in os.walk(font_dir): + # For each font do + for filename in filenames: + # Get font full file path + font_resource_file = os.path.join(dirname, filename) + # For each character do + for char in mycharacters: + # For each font size do + for font_size in font_sizes: + if font_size > 0: + # For each background color do + for background_color in background_colors: + for offsetx in myoffsetsX: + for offsety in myoffsetsY: + for degree in mydegrees: + print("image size: {} \t " + "character: {}\t" + "font size: {}\t" + "degree: {}\t \t" + "offsetX: {}\t" + "offsetY: {}".format(image_size, char, font_size, degree,offsetx, offsety)) + + try: + dir = out_dir+char+'/' + os.makedirs(dir) + except OSError as e: + if e.errno != errno.EEXIST: + raise + createImage(dir, background_color, char, font_size, k, font_resource_file, degree, offsetx, offsety,0) + createImage(dir, background_color, char, font_size, k, font_resource_file, degree, offsetx, offsety,1) + createImage(dir, background_color, char, font_size, k, font_resource_file, degree, offsetx, offsety,2) + k = k + 1 + return + if(mode == 'csv'): + GenerateCSVData(sample) + +def GenerateCSVData(sample = True): + myoffsetsX = offsetsX_sample if sample else offsetsX + myoffsetsY = offsetsY_sample if sample else offsetsY + mydegrees = degrees_sample if sample else degrees + mycharacters = characters_sample if sample else characters + print("image size: {} \t " + "characters: {}\t" + "backgrounds: {}\t" + "font sizes: {}\t" + "degree: {}\t" + "offsetX: {}\t" + "offsetY: {}".format(image_size, mycharacters, background_colors, font_sizes, mydegrees,myoffsetsX, myoffsetsY)) + k = 0 + i = 0 + path, dirs, files = next(os.walk(font_dir)) + file_count = len(files) + + height = file_count*len(mycharacters)*len(font_sizes)*len(background_colors)*len(myoffsetsX)*len(myoffsetsY)*len(mydegrees)*3 + print(height) + width = image_size*image_size+1 + output = np.ones((height,width), dtype=object) + mapDic = {} + for dirname, dirnames, filenames in os.walk(font_dir): + # For each font do + for filename in filenames: + # Get font full file path + font_resource_file = os.path.join(dirname, filename) + + # For each character do + for char in mycharacters: + mapDic[char] = i + # For each font size do + for font_size in font_sizes: + if font_size > 0: + # For each background color do + for background_color in background_colors: + for offsetx in myoffsetsX: + for offsety in myoffsetsY: + for degree in mydegrees: + #createImage((255, 255, 255), 'A', 16, 1, + # './resources/fonts\\HelveticaNeueLight.ttf', 30) + # print("image size: {} \t " + # "character: {}\t" + # "font size: {}\t" + # "degree: {}\t" + # "offsetX: {}\t" + # "offsetY: {}".format(image_size, char, font_size, degree,offsetx, offsety)) + + resultImage1 = createImage(dir, background_color, char, font_size, k, font_resource_file, degree, offsetx, offsety,0, False) + resultImage1 = resultImage1.convert('L') + width = resultImage1.size[0] + height = resultImage1.size[1] + imageArray = np.array(resultImage1) + value = np.asarray(resultImage1, dtype=np.int) + value = value.flatten() + value = np.append(i, value) + output[k] = value + resultImage2 = createImage(dir, background_color, char, font_size, k, font_resource_file, degree, offsetx, offsety,1, False) + width = resultImage1.size[0] + height = resultImage1.size[1] + imageArray = np.array(resultImage1) + value = np.asarray(resultImage1, dtype=np.int) + value = value.flatten() + value = np.append(i, value) + output[k+1] = value + resultImage2 = createImage(dir, background_color, char, font_size, k, + font_resource_file, degree, offsetx, offsety, 2, + False) + width = resultImage1.size[0] + height = resultImage1.size[1] + imageArray = np.array(resultImage1) + value = np.asarray(resultImage1, dtype=np.int) + value = value.flatten() + value = np.append(i, value) + output[k + 2] = value + #print(k) + k = k + 3 + print(i) + i = i + 1 + + print("dimensions {}".format(output.shape)) + np.savetxt(out_dir+"foo.csv", output,fmt='%5s', delimiter=",") + pickle_out = open(out_dir+"mapDic.pickle", "wb") + pickle.dump(mapDic, pickle_out) + pickle_out.close() + print(output[:,0]) + + #np.savetxt(out_dir+"mapDic.csv", mapDic,delimiter=",") + return + +def getMapDic(): + pickle_in = open(out_dir+"mapDic.pickle", "rb") + return pickle.load(pickle_in) + + +def createImageTemplate(background_color, char, font_size, k, font_filename, degree = 0, offsetX = 0, offsetY = 0, noise = 0): + # Create character image : + # Grayscale, image size, background color + char_image = Image.new('RGBA', (image_size, image_size), \ + background_color) + # Draw character image + draw = ImageDraw.Draw(char_image) + # Specify font : Resource file, font size + font = \ + ImageFont.truetype(font_filename, font_size) + # Get character width and height + (font_width, font_height) = font.getsize(char) + # Calculate x position + x = (image_size - font_width) / 2 + offsetX*image_size + # Calculate y position + y = (image_size - font_height) / 2 + offsetY*image_size + # Draw text : Position, String, + # Options = Fill color, Font + draw.text((x, y), char,(0,0,0), font=font) + char_image = char_image.rotate(degree) + fontname = os.path.split(font_filename)[1].split('.')[0] + # Final file name + file_name = "{}_f_{}_fs_{}_bc_{}_n_{}_r_{}_ox_{}_oy_{}_{}.png".\ + format(char,fontname, font_size,background_color,noise,degree,offsetX,offsetY,k) + #str(font_size) + '_bc_' + \ + # str(background_color) + '_r_' + \ + # str(background_color) + '_r_' + \ + # str(background_color) + '_r_' + \ + # str(k) + '.png' + + # Save image + #char_image.save('results/' + file_name) + return (char_image, file_name) + + +def createImage(directory, background_color, char, font_size, k, font_filename, degree = 0, offsetX = 0, offsetY = 0, noise = 0, save = True): + blankImage, file_name = createBlankImage() + blankImage.save('blankIamge.png') + image2, file_name2 = createImageTemplate(background_color, char, font_size, k, font_filename, degree, offsetX, offsetY, noise) + #image2.save('./results/'+str(k)+'.png') + px, py = 0, 0 + sx, sy = image2.size + blankImage.paste(image2, (px, py, px + sx, py + sy), image2) + #resultImage = addNoise(blankImage,noise) + resultImage = blankImage + if resultImage.mode != 'RGB': + resultImage = resultImage.convert('RGB') + if(save): + resultImage.save(directory+file_name2) + return resultImage + +def addNoise(image, noise = 0): + pix = np.array(image) + if noise == 2: + #print("noise gaussian") + pix = noisy('gauss', pix) + + #pix = random_noise(pix, mode='gaussian', clip=True) + elif noise == 1: + pix = noisy('s&p',pix) + #print("noise s and p") + #pix = random_noise(pix, mode='pepper', clip=True, amount = 0.1) + else: + pix = np.array(image) + result =Image.fromarray(pix.astype('uint8')) + #result.show() + return result + +def createBlankImage(): + # Create character image : + # Grayscale, image size, background color + char_image = Image.new('RGBA', (image_size, image_size), \ + (255,255,255)) + + # w = char_image.rotate(45.5, expand=1) + #char_image.rotate(45).show() + # Final file name + file_name = 'blankoImage {}x{}.png'.format(image_size, image_size) + #print(file_name) + # Save image + #char_image.save('results/' + file_name) + return (char_image, file_name) + + +#---------------------------------- Input and Output ---------------------------# + +# Directory containing fonts +font_dir = './resources/fonts' + +# Output +out_dir = './results/' + +k = 0 + +# ------------------------------------ Characters -------------------------------# +# Numbers +numbers = ['0', '1', '2'] + +# Small letters +small_letters = ['a', 'b', 'c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] +small_letters_limited = ['k', 'b', 'c','e'] +capital_letters = [x.capitalize() for x in small_letters_limited] +#print(big_letters) +# Capital letters +#capital_letters = ["A", 'B', 'C'] + +# Select characters +characters = small_letters +characters_sample = small_letters_limited +#------------------------------------- Colors ----------------------------------# + +# Background color +white_colors = [(255,255,255),(220,220,220)] +white_colors_sample = [(255,255,255)] +black_colors = (0, 10, 20, 30) +gray_colors = [(135, 145, 155)] + +#background_colors = white_colors +background_colors = white_colors_sample + +# -------------------------------------- Sizes ----------------------------------# + +# Character sizes +small_sizes = (10, 14, 16) +medium_sizes = (20, 24, 28) +medium_sizes = (20, 24, 28) +large_sizes = (30,36,40) +large_sizes_sample = (24,30) + +font_sizes = large_sizes_sample + +# Image size +image_size = 32 + +offsetsX = [-0.3,-0.1,0,0.1,0.3] +offsetsY = [-0.3,-0.1,0,0.1,0.3] +degrees = [-0.1,-0.5,0,0.5,0.1] +offsetsX_sample = [-0.1,0,0.1] +offsetsY_sample = [-0.3,-0.1,0,0.1,0.3] +degrees_sample = [-0.1,-0.5,0,0.5,0.1] + + +# -------------------------------------- rotation and offset ----------------------------------# + + + + +def main(): + generateCharacters('image', True) + #printMapDic() + #GenerateCharacters() + +if __name__ == "__main__": + main() + #image1.save('results/blank.png') + #createMovedImage() + diff --git a/src/MyImageHelper.py b/src/MyImageHelper.py new file mode 100644 index 0000000..fdef7fd --- /dev/null +++ b/src/MyImageHelper.py @@ -0,0 +1,57 @@ +''' +Parameters +---------- +image : ndarray +Input image data. Will be converted to float. +mode : str +One of the following strings, selecting the type of noise to add: + + 'gauss' Gaussian-distributed additive noise. + 'poisson' Poisson-distributed noise generated from the data. + 's&p' Replaces random pixels with 0 or 1. + 'speckle' Multiplicative noise using out = image + n*image,where +''' + +import numpy as np +import os +#import cv2 + +def noisy(noise_typ, image): + if noise_typ == "gauss": + row, col, ch = image.shape + mean = 0 + var = 0.1 + sigma = var ** 0.5 + gauss = np.random.normal(mean, sigma, (row, col, ch)) + gauss = gauss.reshape(row, col, ch) + noisy = image + gauss + return noisy + elif noise_typ == "s&p": + row, col, ch = image.shape + s_vs_p = 0.5 + amount = 0.01 + out = np.copy(image) + #out = np.asarray(image) + blackTreshold = 3 + whiteTreshold = 253 + # Salt mode + #num_salt = np.ceil(amount * image.size * s_vs_p) + rmatrix = np.random.randint(0,255,(row,col)) + for x, y in np.ndenumerate(out): + if(rmatrix[x[0]][x[1]] < blackTreshold): + out[x[0]][x[1]] = (0,0,0,255) + if(rmatrix[x[0]][x[1]] > whiteTreshold): + out[x[0]][x[1]] = (255, 255, 255,255) + + return out + elif noise_typ == "poisson": + vals = len(np.unique(image)) + vals = 2 ** np.ceil(np.log2(vals)) + noisy = np.random.poisson(image * vals) / float(vals) + return noisy + elif noise_typ == "speckle": + row, col, ch = image.shape + gauss = np.random.randn(row, col, ch) + gauss = gauss.reshape(row, col, ch) + noisy = image + image * gauss + return noisy \ No newline at end of file