added Basic version of Image Generator for generating Char Image Dataset
This commit is contained in:
351
src/ImageGenerator.py
Normal file
351
src/ImageGenerator.py
Normal file
@@ -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()
|
||||
|
||||
57
src/MyImageHelper.py
Normal file
57
src/MyImageHelper.py
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user