101 lines
2.7 KiB
Python
Executable File
101 lines
2.7 KiB
Python
Executable File
#! /usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
from fontTools.ttLib import TTFont
|
|
from PIL import Image, ImageFont, ImageDraw
|
|
import cv2, numpy as np, uuid, argparse, os, codecs
|
|
|
|
def crop_image(img):
|
|
height = img.shape[0]
|
|
width = img.shape[1]
|
|
v_sum = np.sum(img, axis=0)
|
|
h_sum = np.sum(img, axis=1)
|
|
left = 0
|
|
right = width - 1
|
|
top = 0
|
|
bottom = height - 1
|
|
# 从左往右扫描,遇到非零像素点就以此为字体的左边界
|
|
for i in range(width):
|
|
if v_sum[i] > 0:
|
|
left = i
|
|
break
|
|
# 从右往左扫描
|
|
for i in range(width - 1, -1, -1):
|
|
if v_sum[i] > 0:
|
|
right = i
|
|
break
|
|
# 从上往下扫描
|
|
for i in range(height):
|
|
if h_sum[i] > 0:
|
|
top = i
|
|
break
|
|
# 从下往上扫描
|
|
for i in range(height - 1, -1, -1):
|
|
if h_sum[i] > 0:
|
|
bottom = i
|
|
break
|
|
|
|
return img[top: bottom + 1, left: right + 1]
|
|
|
|
# 规范化图像
|
|
def normalize_image_size(img, width, height):
|
|
img = cv2.resize(img, (width, height))
|
|
return img
|
|
|
|
def load_label(filename):
|
|
f = codecs.open(filename, 'r', encoding='utf-8')
|
|
i = 0
|
|
dic = {}
|
|
for char in f:
|
|
dic[i] = str(char).rstrip('\n')
|
|
i = i + 1
|
|
return dic
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("-f", required=True)
|
|
parser.add_argument("-o", required=True)
|
|
parser.add_argument("-l", required=True)
|
|
args = parser.parse_args()
|
|
|
|
font_dir = args.f
|
|
out_dir = args.o
|
|
label_file = args.l
|
|
image_width = 30
|
|
|
|
if not os.path.isdir(out_dir):
|
|
os.makedirs(out_dir)
|
|
|
|
print("Reading charactor label file")
|
|
label = load_label(label_file)
|
|
|
|
font_list = []
|
|
for d in os.listdir(font_dir):
|
|
font_file = os.path.join(font_dir, d)
|
|
font = ImageFont.truetype(font_file, int(image_width * 0.9),)
|
|
ttfont = TTFont(font_file)
|
|
chars = { c[0] for c in ttfont.getBestCmap().items() }
|
|
font_list.append({'font': font, 'chars': chars})
|
|
|
|
nchars = len(label)
|
|
for cid, ch in label.items():
|
|
image_list = []
|
|
print ("%s %d" % (ch, cid))
|
|
for font in font_list:
|
|
if ord(ch) not in font['chars']:
|
|
continue
|
|
img_file = os.path.join(out_dir, "%0.4d" % cid, os.path.basename(font['font'].path) + ".png")
|
|
img = Image.new("L", (image_width, image_width))
|
|
draw = ImageDraw.Draw(img)
|
|
draw.text((0, 0), ch, 255, font=font['font'])
|
|
data = list(img.getdata())
|
|
np_img = np.asarray(data, dtype='uint8')
|
|
np_img = np_img.reshape((image_width, image_width, 1))
|
|
if not os.path.isdir(os.path.dirname(img_file)):
|
|
os.mkdir(os.path.dirname(img_file))
|
|
ret, np_img = cv2.threshold(np_img, 80, 255, cv2.THRESH_BINARY);
|
|
np_img = crop_image(np_img)
|
|
np_img = normalize_image_size(np_img, image_width, image_width)
|
|
ret, np_img = cv2.threshold(np_img, 127, 255, cv2.THRESH_BINARY);
|
|
|
|
cv2.imwrite(img_file, np_img)
|