教程:如何生成自己的个性化手写文字?
dailenson opened this issue · 43 comments
1.数据预处理
首先是在白纸上写至少15
个字(我自己抄了一首诗,写了28个字,没有白纸的话用别的颜色的纸应该也行),然后用扫描软件(例如夸克ocr)扫描一下,估计可以自动把背景去掉。以下是扫描后的样子:
然后就是手动裁剪部分啦,我用的是windows自带的画图板,有裁剪功能,直接对着图片,右键点击选择画图
,
打开图片后,选择裁剪
,裁剪的时候注意,大概贴着字裁个差不多的正方形就好(后面代码里面会自动resize成64*64),然后保存成jpg或者png都行。
接着,把这些图片放到一个文件夹下面就行,假设大家放到了style_samples
文件夹里面。
2.代码运行
首先按照readme里面的步骤把环境配置好,然后运行:
python user_generate.py --pretrained_model checkpoint_path --style_path style_samples
checkpoint_path要从网盘里面下载,readme里面有给下载链接,checkpoint在网盘的saved_weights/Chinese/
路径下面。我测了一下,有gpu
的情况下,3分钟左右就可以生成6763个中文字符,生成的字符存放在Generated/Chinese_User
路径。
最后,祝大家使用愉快~如果想在word软件里面使用的话,直接百度“图像转ttf文件”即可。
点赞,我来试试
在Windows系统下可能会出现报错
error: (-215:Assertion failed) !ssize.empty() in function 'cv::resize'
可能是路径中有中文导致的,把生成图片的.jpg改成英文或者数字即可解决
(经过测试,样本中的.jpg文件是否是对应的中文与推演结果无关,即想省事直接随便命名,
想要中文命名不报错的方法在最后)
或者用以下代码来检查哪张图片有问题(有中文路径就会报错)
import os
import cv2
filpath='D:/CVPR2023_SDT/SDT-master/style_samples'
image_list = os.listdir(filpath) # 读取文件夹中所有的图片
print(image_list)
i=0
for picname in image_list:
i += 1
img = cv2.imread((filpath + '/' + picname), 0)
try:
img = cv2.resize(img, (64, 64))
print(i, picname) #打印当前成功处理的图片数量图片名称
except :
print(picname) #打印出有问题的图片名
break
带数字的图片名称是正确的,不带数字的名称是有问题的
以下是改中文的路径又不报错的方法
在loader.py
中大概224行
把style_img = cv2.imread(self.style_path[idx], flags=0)
替换成 style_img = cv2.imdecode(np.fromfile(self.style_path[idx], dtype=np.uint8), cv2.IMREAD_GRAYSCALE)
在中文下运行不会报错
兼容中英文的检查程序就是
把 img = cv2.imread((filpath + '/' + picname), 0)
替换成 img = cv2.imdecode(np.fromfile(filpath + '/' + picname,dtype=np.uint8),-1)
点赞,我来试试
试了一下,字体不是太像。。。用了17个字做sample进行生成,会不会微调下效果会好?
点赞,我来试试
试了一下,字体不是太像。。。用了17个字做sample进行生成,会不会微调下效果会好?
可以多喂点字进去先试试,微调一下模型肯定是最好的
点赞,我来试试
试了一下,字体不是太像。。。用了17个字做sample进行生成,会不会微调下效果会好?
可以多喂点字进去先试试,微调一下模型肯定是最好的
OK
研究了一个晚上发现了几个问题 第一,使用
user_generate.py
生成的单位是106,而用test.py
生成的单位却是468,都是引用了同一个.pth文件为何会这样![]()
第二,使用
user_generate.py
生成的字十分的潦草,即使尽力把预处理做好,虽能看出与‘test.py'确实不同 该如何达到readme
中的效果![]()
我尝试过给了30个去推演,结果风格都是一笔划写的字,因为预训练模型不是同一个吗?
![]()
user_generate.py
生成的自己写的
感谢你的反馈,我这边大概分析了一下。原因感觉还是数据差异的问题,具体来说的话:我们训练时候的数据是使用的公开数据集,笔画宽度是均匀的,你的数据似乎是平板采集的,具有更加真实的笔画宽度,由于跟训练数据的分布差异过大,导致模型倾向于给出一个平均化的风格,这个平均化的风格指的是训练集所有的风格的平均。想要提高效果的话,fine-tune一下应该会好很多,可以让模型适应一下你的数据。
另外,你的第一个问题,因为user_generate.py
只生成你一个人的6733个文字,所以iteration是6733/64=105.2
(64是batchsize)的大小。test.py
是生成测试集中60个书写者的6733个文字,然后每个书写者采样生成500个所以iteration是60×500/64=468.75
。
你贴的最后一张图是SDT的一个拓展,我们引入了一个额外的装饰网络,为SDT生成的均匀笔画的文字增加了笔画宽度和颜色。
提问:按照作者给出的python user_generate.py --pretrained_model checkpoint_path --style_path style_samples运行后,再添加图片生成出来的字和原来所生成的字的字一模一样是什么原因:)
提问:按照作者给出的python user_generate.py --pretrained_model checkpoint_path --style_path style_samples运行后,再添加图片生成出来的字和原来所生成的字的字一模一样是什么原因:)
原来生成的字指的是什么?
(base) C:\Windows\System32>python user_generate.py --pretrained_model checkpoint_path --style_path style_samples
python: can't open file 'C:\Windows\System32\user_generate.py': [Errno 2] No such file or directory
下载的文件里没找到有user_generate.py诶
(base) C:\Windows\System32>python user_generate.py --pretrained_model checkpoint_path --style_path style_samples python: can't open file 'C:\Windows\System32\user_generate.py': [Errno 2] No such file or directory 下载的文件里没找到有user_generate.py诶
重新下载最新版的文件
G:\python38\python.exe C:\desktop\SDT-master(new)\SDT-master\user_generate.py --pretrained_model C:\desktop\CVPR2023_SDT\saved_weights\Chinese\checkpoint-iter199999.pth
load pretrained model from C:\desktop\CVPR2023_SDT\saved_weights\Chinese\checkpoint-iter199999.pth
0%| | 0/106 [00:00<?, ?it/s]
Traceback (most recent call last):
File "C:\desktop\SDT-master(new)\SDT-master\user_generate.py", line 83, in
main(opt)
File "C:\desktop\SDT-master(new)\SDT-master\user_generate.py", line 55, in main
preds = model.inference(img_list, char_img, 120)
File "C:\desktop\SDT-master(new)\SDT-master\models\model.py", line 152, in inference
batch_size, num_imgs, in_planes, h, w = style_imgs.shape
ValueError: not enough values to unpack (expected 5, got 3)
ChatGPT回答:根据错误信息,看起来问题出现在模型的 inference
方法中的 style_imgs.shape
。错误信息表明期望的形状是 (batch_size, num_imgs, in_planes, h, w)
,但实际的形状是 (3,)
。
这个问题可能是由于样式图片的数量不足导致的。请确保 style_samples
文件夹中至少有5张样式图片。如果没有足够的样式图片,你可以添加更多的样式图片到该文件夹中。
如果你已经确认样式图片的数量足够,并且问题仍然存在,那么可能需要检查模型的代码,确保在 inference
方法中对 style_imgs
进行正确的处理,以适应不同数量的样式图片。
我是直接在user_generate.py相同的根目录里新建的style_samples文件夹,里面放了86张png格式的图片,是哪里弄错了吗
没有英伟达显卡有办法用吗
请问您3分钟可以执行一遍的gpu
配置是?我用T4跑一遍需要12分钟
checkpoint_path要从网盘里面下载,readme里面有给下载链接,checkpoint在网盘的
saved_weights/Chinese/
路径下面。我测了一下,有gpu
的情况下,3分钟左右就可以生成6763个中文字符,生成的字符存放在Generated/Chinese_User
路径。
没有英伟达显卡有办法用吗
没有显卡的话就用Cpu啦,会慢一点。
请问您3分钟可以执行一遍的
gpu
配置是?我用T4跑一遍需要12分钟checkpoint_path要从网盘里面下载,readme里面有给下载链接,checkpoint在网盘的
saved_weights/Chinese/
路径下面。我测了一下,有gpu
的情况下,3分钟左右就可以生成6763个中文字符,生成的字符存放在Generated/Chinese_User
路径。
我的是RTX 3090
没有英伟达显卡有办法用吗
没有显卡的话就用 Cpu 啦,会慢一点。
能讲一下怎么用CPU吗
没有英伟达显卡有办法用吗
没有显卡的话就用 Cpu 啦,会慢一点。
能讲一下怎么用CPU吗
我抽空整理一个cpu版本
FileNotFoundError: [Errno 2] No such file or directory: 'data\CASIA_CHINESE\Chinese_content.pkl'
大佬这又是因为什么a
FileNotFoundError: [Errno 2] No such file or directory: 'data\CASIA_CHINESE\Chinese_content.pkl' 大佬这又是因为什么a
你下载好了Chinese_content.pkl
这个文件吗?
没有英伟达显卡有办法用吗
没有显卡的话就用 Cpu 啦,会慢一点。
能讲一下怎么用 CPU 吗
我抽空整理一个 cpu 版本
大佬弄好了回个话哈
没有英伟达显卡有办法用吗
没有显卡的话就用 Cpu 啦,会慢一点。
能讲一下怎么用CPU吗
我抽空整理一个cpu版本
催更哈哈
没有英伟达显卡有办法用吗
没有显卡的话就用 Cpu 啦,会慢一点。
能讲一下怎么用 CPU 吗
我抽空整理一个 cpu 版本
大佬弄好了回个话哈
#55
没有英伟达显卡有办法用吗
没有显卡的话就用 Cpu 啦,会慢一点。
能讲一下怎么用CPU吗
我抽空整理一个cpu版本
催更哈哈
#55
没有英伟达显卡有办法用吗
没有显卡的话就用 Cpu 啦,会慢一点。
能讲一下怎么用 CPU 吗
我抽空整理一个 cpu 版本
大佬弄好了回个话哈
#56 我写了个教程
没有英伟达显卡有办法用吗
没有显卡的话就用 Cpu 啦,会慢一点。
能讲一下怎么用CPU吗
我抽空整理一个cpu版本
催更哈哈
哈哈哈 这两天在弄CVPR的rebuttal,31号以后弄一下
没有英伟达显卡有办法用吗
没有显卡的话就用 Cpu 啦,会慢一点。
能讲一下怎么用CPU吗
我抽空整理一个cpu版本
催更哈哈
哈哈哈 这两天在弄CVPR的rebuttal,31号以后弄一下
大佬,我自己等不及已经写了一个cpu的版本哈哈
提了pr,大佬可以看看我写的还有什么问题吗
使用如下脚本切割获取了200多手写字体(图1、图2),249个字体训练后生成的字体(图3)和手写字体差别很大,跟手写字体文件名是否有关?
import argparse
import os
import cv2
import shutil
def main(opt):
# 膨胀腐蚀大小 即将笔画膨胀 避免将偏旁单独分割 根据图片请况自行设置
rect_size = 16
# 字体小于该值忽略 20*20
ignore_min_size = 20
# 字体大于该值忽略 100*100
ignore_max_size = 100
# 需要切分的图片 input/input.jpg
input_file = opt.input_path
# 输出文件夹 output
output_path = opt.output_path + os.path.sep
if not os.path.exists(output_path):
os.makedirs(output_path)
else:
shutil.rmtree(output_path)
os.makedirs(output_path)
img = cv2.imread(input_file)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化 根据图片情况调节灰度阈值 第二个参数灰度值表示小于该值就将其变为0
ret, thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
cv2.imwrite(output_path + "thresh.jpg", thresh)
thresh_rgb = cv2.cvtColor(thresh, cv2.COLOR_GRAY2BGR)
# 待切分的图片 img原图 gray灰度图 thresh二值化后的灰度图 thresh_rgb二值化后转RGB
result = thresh.copy()
# 膨胀腐蚀 将字体笔画扩大15像素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (rect_size, rect_size))
eroded = cv2.erode(thresh, kernel)
cv2.imwrite(output_path + "eroded.jpg", eroded)
# 轮廓检测
contours, hierarchy = cv2.findContours(eroded, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 膨胀间距
spacing = rect_size // 2 - 1
cut_frame_color = (0, 255, 0)
font_frame_color = (255, 0, 0)
for c in contours:
x, y, w, h = cv2.boundingRect(c)
if w < ignore_min_size or h < ignore_min_size or w > ignore_max_size or h > ignore_max_size:
continue
font_w = w - spacing - spacing
font_h = h - spacing - spacing
frame_size = font_w if font_w > font_h else font_h
# 正方形切割偏移量
x_offset = int((frame_size - font_w) / 2)
y_offset = int((frame_size - font_h) / 2)
start_x = x + spacing - x_offset
start_y = y + spacing - y_offset
end_x = x + w - spacing + x_offset
end_y = y + h - spacing + y_offset
# 字体框线
cv2.rectangle(thresh_rgb, (x + spacing, y + spacing), (x + w - spacing, y + h - spacing), font_frame_color, 1)
# 切割框线
cv2.rectangle(thresh_rgb, (start_x, start_y), (end_x, end_y), cut_frame_color, 1)
# 切割
temp = result[start_y:end_y, start_x:end_x]
path = opt.output_path + os.path.sep + "result" + os.path.sep
if not os.path.exists(path):
os.makedirs(path)
cv2.imwrite(path + str(x) + "_" + str(y) + ".jpg", temp)
cv2.imwrite(output_path + "result.jpg", thresh_rgb)
if __name__ == '__main__':
"""Parse input arguments"""
parser = argparse.ArgumentParser()
parser.add_argument('--input', dest='input_path', default='input/input.jpg',
help='Please set the input path')
parser.add_argument('--output', dest='output_path', default='output',
help='Please set the output path')
opt = parser.parse_args()
main(opt)
生成效果不满意,出现“狂草”现象的朋友,可以试试将收集的参考图像做个二值化处理再输入模型中,应该可以提升生成效果#59 (comment)
用文心一言写了个图片二值化的代码(
https://github.com/CreeperAWA/Binary-Image
PermissionError: [Errno 13] Permission denied: 这个报错一直解决不了
解决了谢谢
这位兄弟复现的应该是目前效果最好的。详情见#75 (comment)
额外的装饰网络,为SDT生成的均匀笔画的文字增加了笔画宽度和颜色
作者大佬,这个可以解释一下吗?
额外的装饰网络,为SDT生成的均匀笔画的文字增加了笔画宽度和颜色
PermissionError: [Errno 13] 权限被拒绝:这个报错一直解决不了
同问,请问怎么解决呢
额外的装饰网络,为SDT生成的均匀笔画的文字增加了笔画宽度和颜色
作者大佬,这个可以解释一下吗?
额外的装饰网络,为SDT生成的均匀笔画的文字增加了笔画宽度和颜色
这个可以直接看论文的补充材料Section A.4.简单来说就是我们的SDT生成的是在线字符,是没有笔画宽度和颜色的,如果想要加上宽度和颜色,需要插入一个GAN方法来增加上去。
如何生成离线的手写汉字,user_generate.py生成的是在线的类型的