dailenson / SDT

This repository is the official implementation of Disentangling Writer and Character Styles for Handwriting Generation (CVPR23).
MIT License
956 stars 81 forks source link

真的有能复现出理想结果,不狂草的吗?作者大大还能复现出不? #75

Open bye-mr-jia opened 5 months ago

bye-mr-jia commented 5 months ago
      有没有大佬能正常复现出不狂草的字体的。我已经试过二值化了,我是通过夸克扫描王扫描之后,用的lssues区的一段代码二值化,还是没什么用,就是一狂到底,根本没有不狂草的例子,有没有什么解决办法,微调是微调代码还是微调输入的图片?
     小白选手,真心求学,真的想拥有一套自己的字体,假如你那边你那边能复现也行,可有偿。
bye-mr-jia commented 4 months ago

Hello?有人在吗?

YZcat2023 commented 4 months ago

现在我复现了,还不错

YZcat2023 commented 4 months ago

我是sai ver.2,使用了关闭压感的数位板输入的,128x128px,宽2.7px,写了一个代码处理输入数据(二值化),跑出来挺正

YZcat2023 commented 4 months ago

image

YZcat2023 commented 4 months ago

from PIL import Image  
import os  
# 设置二值化阈值  
threshold = 128  
current_dir = os.getcwd()  

for filename in os.listdir(current_dir):  
    if filename.endswith(('.jpg', '.png')):  
        img = Image.open(filename)  
        gray_img = img.convert('L')  
        binary_img = gray_img.point(lambda x: 255 if x > threshold else 0, '1')  
        binary_filename = filename.rsplit('.', 1)[0] + '_binary.' + filename.rsplit('.', 1)[1]  
        binary_img.save(binary_filename)  

        print(f"保存为:{binary_filename}")
        try:  
            os.remove(filename)  
            print(f"已删除:{filename}")  
        except OSError as e:  
            print(f"无法删除 {filename}.{e.strerror}") 
dailenson commented 4 months ago

image

厉害。应该是目前为止复现结果最好的了,你关掉了压力输入这一点很重要,这样笔画就是均匀的了。

YZcat2023 commented 4 months ago

image

厉害。应该是目前为止复现结果最好的了,你关掉了压力输入这一点很重要,这样笔画就是均匀的了。

对了,没有英文输入怎么办,我还指望它给我写实验报告呜呜呜

YZcat2023 commented 4 months ago

英文字符自己写应该也不是不行,那样的话就只差转成svg和转成ttf了吧

YZcat2023 commented 4 months ago

https://www.bilibili.com/video/BV1ri4y1o7hj/?vd_source=16ed56ce6ce6d7c53438afb279557d9d 这个似乎是可行的转ttf方案

YZcat2023 commented 4 months ago

@dailenson 现在有一个难受的事情:potrace太老了,而且win上难用,如何转化成svg成为极大的问题,vectormagic也许是解决方案,但是这是付费软件。

YZcat2023 commented 4 months ago

补充目前使用的情况:有几个字就是写不好,比如“双”字总是会自己跑到上面去;输入数据太多(我这里是12400+3070本子)超过200个左右就好像不正常出图了,第一批64个出完就不动了,感觉90个输入左右可能是合适的

YZcat2023 commented 4 months ago

没时间研究了,我拿vectormagic办完了。然后注意,先要写个脚本把图片转成透明背景的,不然导进去就是反色的

dailenson commented 4 months ago

没时间研究了,我拿vectormagic办完了。然后注意,先要写个脚本把图片转成透明背景的,不然导进去就是反色的 把你的效果贴上来看下?

kernelwangxuan commented 4 months ago

可能 ostu 这些算法直接处理更好? 另外提一个思路:作者有没有考虑过一些类似Xiaolin Wu,或者一些 dithering 方法(Floyd Steinberg),以支持在二值化图像中类似笔画粗细和一些复杂手写字符的表示?还有一个麻烦就是连字处理,英文只用支持一些常见的连字,比如 tt,fi,ff,中文就麻烦了

bye-mr-jia commented 4 months ago

现在我复现了,还不错

你好,能加一下联系方式吗?我想深入请教你一下,这是我的邮箱bye_mr_pai@163.com

gudaoxongdi commented 4 months ago
from PIL import Image  
import os  
# 设置二值化阈值  
threshold = 128  
current_dir = os.getcwd()  

for filename in os.listdir(current_dir):  
    if filename.endswith(('.jpg', '.png')):  
        img = Image.open(filename)  
        gray_img = img.convert('L')  
        binary_img = gray_img.point(lambda x: 255 if x > threshold else 0, '1')  
        binary_filename = filename.rsplit('.', 1)[0] + '_binary.' + filename.rsplit('.', 1)[1]  
        binary_img.save(binary_filename)  

        print(f"保存为:{binary_filename}")
        try:  
            os.remove(filename)  
            print(f"已删除:{filename}")  
        except OSError as e:  
            print(f"无法删除 {filename}.{e.strerror}") 

小白,请问一下这段代码是放在哪个py文件里面吗,具体怎么使用呢?

bianyangT commented 4 months ago
from PIL import Image  
import os  
# 设置二值化阈值  
threshold = 128  
current_dir = os.getcwd()  

for filename in os.listdir(current_dir):  
    if filename.endswith(('.jpg', '.png')):  
        img = Image.open(filename)  
        gray_img = img.convert('L')  
        binary_img = gray_img.point(lambda x: 255 if x > threshold else 0, '1')  
        binary_filename = filename.rsplit('.', 1)[0] + '_binary.' + filename.rsplit('.', 1)[1]  
        binary_img.save(binary_filename)  

        print(f"保存为:{binary_filename}")
        try:  
            os.remove(filename)  
            print(f"已删除:{filename}")  
        except OSError as e:  
            print(f"无法删除 {filename}.{e.strerror}") 

小白,请问一下这段代码是放在哪个py文件里面吗,具体怎么使用呢?

编辑成单独的.py文件,放在要处理的图片的目录下面,运行就可以了

YZcat2023 commented 3 months ago

没时间研究了,我拿vectormagic办完了。然后注意,先要写个脚本把图片转成透明背景的,不然导进去就是反色的 把你的效果贴上来看下?

好的 image

YZcat2023 commented 3 months ago

现在我复现了,还不错

你好,能加一下联系方式吗?我想深入请教你一下,这是我的邮箱bye_mr_pai@163.com

yzkitten2023@gmail.com

YZcat2023 commented 3 months ago

或者Qq2803839524

coling0 commented 3 months ago

用window自带的画图板写了30个字,跑出来效果还能可以 Snipaste_2024-05-15_22-12-24

这个是用扫描仪扫描的40个手写,用#62 的代码切割出来的,一般环境倒也能接受,目前正在寻找标点符号的解决办法 Snipaste_2024-05-15_22-12-42

aceliuchanghong commented 3 months ago

我是sai ver.2,使用了关闭压感的数位板输入的,128x128px,宽2.7px,写了一个代码处理输入数据(二值化),跑出来挺正

大佬,有没有你的style_samples可以发个压缩包吗,我想看看到底哪儿有问题,我的

gudaoxongdi commented 2 months ago

简单说一下规律,这个模型对笔画的宽度有着十分严格的限制,只要笔画宽了,就容易出“草书” 解决方法和楼主说的一样,笔宽12,画面100% 我是拿鼠标画的,就调整成,笔宽6,画面50%,这样就方便画一点

确实,跟画笔的粗细关系很大。 二值笔-粗 第1张是按照说明,在sai里用二值笔,关闭压感,粗细为12,结果生成的还是很潦草的。 二值笔-细 第2张,其它条件一样,就是把粗细调成3,生成的就不怎么潦草了。 ai-细 第3张是在AI里,用相对细的线条写的,生成的也不怎么潦草了。

yicone commented 2 months ago

感谢 @YZcat2023 分享经验。

也分享一张生成结果。效果没有那么好,但也不算飞线飞得太厉害。

image

图中上半部分是二值化处理后的图片。

笔画的线条可能还是偏粗,不确定是不是这个因素,导致推理结果还是往草书的方向去演化了? @dailenson

另外,私人化的一些步骤是:

  1. 手写是在iPad上用 Notes 和 Apple Pencil(一代) 完成的,屏幕上选第3种笔,因为它的笔画粗细一致,不受压感影响;设置网格背景,选较大的那个方格。
  2. 在iPad上截屏,然后沿着网格线裁剪,只保留包含文字的整片区域。
  3. 在电脑上,用代码将第2步产生的单张图片,一次性切分为每个字一张图片。
    
    from PIL import Image
    # import pytesseract
    # from pypinyin import lazy_pinyin
    import os

def split_images_by_word(image_path: str, output_dir: str):

加载图像

img = Image.open(image_path)

# 假设图像已经按网格对齐,并且网格大小相同
num_rows = 5  # 图中汉字行数
num_cols = 9  # 图中汉字列数
grid_width, grid_height = 161, 161

# 创建输出目录
os.makedirs(output_dir, exist_ok=True)

for row in range(num_rows):
    for col in range(num_cols):
        # 裁剪图像
        left = col * grid_width
        top = row * grid_height
        right = left + grid_width
        bottom = top + grid_height
        cropped_img = img.crop((left, top, right, bottom))

        # 使用 OCR 识别图像中的汉字
        # character = pytesseract.image_to_string(cropped_img, lang='chi_sim', config='--psm 10')

        # 转换汉字到拼音
        # pinyin = ''.join(lazy_pinyin(character))
        # print([row, col], pinyin)

        filename = f"{row}{col}.png"

        # 保存图像
        cropped_img.save(os.path.join(output_dir, filename))

print("图像处理完成")
dailenson commented 2 months ago

感谢 @YZcat2023 分享经验。

也分享一张生成结果。效果没有那么好,但也不算飞线飞得太厉害。

image

图中上半部分是二值化处理后的图片。

笔画的线条可能还是偏粗,不确定是不是这个因素,导致推理结果还是往草书的方向去演化了? @dailenson

另外,私人化的一些步骤是:

  1. 手写是在iPad上用 Notes 和 Apple Pencil(一代) 完成的,屏幕上选第3种笔,因为它的笔画粗细一致,不受压感影响;设置网格背景,选较大的那个方格。
  2. 在iPad上截屏,然后沿着网格线裁剪,只保留包含文字的整片区域。
  3. 在电脑上,用代码将第2步产生的单张图片,一次性切分为每个字一张图片。
from PIL import Image
# import pytesseract
# from pypinyin import lazy_pinyin
import os

def split_images_by_word(image_path: str, output_dir: str):
    # 加载图像
    img = Image.open(image_path)

    # 假设图像已经按网格对齐,并且网格大小相同
    num_rows = 5  # 图中汉字行数
    num_cols = 9  # 图中汉字列数
    grid_width, grid_height = 161, 161

    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)

    for row in range(num_rows):
        for col in range(num_cols):
            # 裁剪图像
            left = col * grid_width
            top = row * grid_height
            right = left + grid_width
            bottom = top + grid_height
            cropped_img = img.crop((left, top, right, bottom))

            # 使用 OCR 识别图像中的汉字
            # character = pytesseract.image_to_string(cropped_img, lang='chi_sim', config='--psm 10')

            # 转换汉字到拼音
            # pinyin = ''.join(lazy_pinyin(character))
            # print([row, col], pinyin)

            filename = f"{row}{col}.png"

            # 保存图像
            cropped_img.save(os.path.join(output_dir, filename))

    print("图像处理完成")

笔粗应该是对模型性能有影响的,可以试试不同笔粗的效果。另外,iPad用户可以跟这位童鞋交流一下,他目前用iPad可以得到满意的结果。

yicone commented 2 months ago

针对个人之前的实验方式,做了些改进。

取消了二值化处理,之前用只是为了去除网格线,但二值化处理会导致文字线条不平滑。 image image image

现在改为在裁剪图片前,提供同一组字的有网格和无网格背景的两张图片,先对有网格的选取截图区域,然后再用同样的截图区域,从无网格的图片中截取包含文字的部分。

如此处理后,生成的文字,草书现象基本可以忽略了。


但新问题是,输出与输入相比,真的很不像!特此请教两位,是哪个环节的问题呢,该如何优化? @dailenson @YZcat2023

  1. image 上方是输入,下方是输出。

  2. image

    制作为字体后的输出效果。

dailenson commented 1 month ago

针对个人之前的实验方式,做了些改进。

取消了二值化处理,之前用只是为了去除网格线,但二值化处理会导致文字线条不平滑。 image image image

现在改为在裁剪图片前,提供同一组字的有网格和无网格背景的两张图片,先对有网格的选取截图区域,然后再用同样的截图区域,从无网格的图片中截取包含文字的部分。

如此处理后,生成的文字,草书现象基本可以忽略了。

但新问题是,输出与输入相比,真的很不像!特此请教两位,是哪个环节的问题呢,该如何优化? @dailenson @YZcat2023

image 上方是输入,下方是输出。

image 制作为字体后的输出效果。

我感觉可能是笔画宽度的问题。

yicone commented 1 month ago

针对个人之前的实验方式,做了些改进。 取消了二值化处理,之前用只是为了去除网格线,但二值化处理会导致文字线条不平滑。 image image image 现在改为在裁剪图片前,提供同一组字的有网格和无网格背景的两张图片,先对有网格的选取截图区域,然后再用同样的截图区域,从无网格的图片中截取包含文字的部分。 如此处理后,生成的文字,草书现象基本可以忽略了。 但新问题是,输出与输入相比,真的很不像!特此请教两位,是哪个环节的问题呢,该如何优化? @dailenson @YZcat2023 image 上方是输入,下方是输出。 image 制作为字体后的输出效果。

我感觉可能是笔画宽度的问题。

感谢回复。

笔画宽度已经是均匀的了 https://github.com/dailenson/SDT/issues/78#issuecomment-2063162445

dailenson commented 1 month ago

针对个人之前的实验方式,做了些改进。 取消了二值化处理,之前用只是为了去除网格线,但二值化处理会导致文字线条不平滑。 image image image 现在改为在裁剪图片前,提供同一组字的有网格和无网格背景的两张图片,先对有网格的选取截图区域,然后再用同样的截图区域,从无网格的图片中截取包含文字的部分。 如此处理后,生成的文字,草书现象基本可以忽略了。 但新问题是,输出与输入相比,真的很不像!特此请教两位,是哪个环节的问题呢,该如何优化? @dailenson @YZcat2023 image 上方是输入,下方是输出。 image 制作为字体后的输出效果。

我感觉可能是笔画宽度的问题。

感谢回复。

笔画宽度已经是均匀的了 #78 (comment)

宽度的要求有两方面,一方面是均匀,另一方面不能太细或者太粗,我感觉你输入的参考样本太细了。还有就是参考样本的笔画颜色要求是纯黑的。

ChenxingZhang commented 3 weeks ago

f40e6464ce71905c47cfb67acc54de4 那完了呀,我还想生成我的手写体。纸面手写体和数位板差距还蛮大的,二值化处理之后我的手写体还是不能正常生成。