zi2zi 超過框框的字要如何處理?

常見會出血的字: gjpqyýÿ¿¡{}Q

這些字和中文字一起訓練會幾個問題, 首先是偏移在不同位置, 會出現不同的大小, 例如 “H” 這個符號, 一模一模的輸入, 設定不同的 y offset, 出現在晝面上/中/下 不同的位置, 推論出來的結果會不一樣大, 形狀也會有差異.

  • 解法1:
    使用 x offet / y offset 來解決, 但這個只能解決一小部份的字, 因為加了 offset 會讓部份的字掛掉, 例如為了讓 g/p/q/y 等字向上, 就會讓很多大寫字或符號的字因為 offset 造成被crop.
  • 解法2:
    先讓畫布寬高乘2, 原本為 256 就讓畫布為 512, 然後在 x offset / y offset 各設為原本的 1/2, 就是 128, 晝上原本 256×256 的字, 然後把這個圖轉成 svg 之後, 進入 fontforge 把這個glyph x offset / y offset 各設 -128 就可以拿到正常的圖片, 要使用這一個解法, 在訓練的時候, 就要資料都用 512 的大小去訓練,
  • 解法3: (建議)
    原本應該使用 font size=256 情況下, 在 infer 時改使用 font size=217 (=256 x 0.85), 也可以試著調整為 font size=205(=256 x 0.80), 由於推論前 font size 就縮小了, 所以在取得推論結果之後, 再 resize 回去.
    例如: 如果font size使用 217 是原本的 0.85, resize canvas size 設為 294 (=256 x 1.15) 就可以取得放大後的結果.

說明: 紅字是直接推論, 會被 crop 到, 藍色是使用先縮小後放大, 黑色部份是二個推論重疊的部份, 解法3有符合預期的效果.

正常 infer script:

python infer.py --experiment_dir=experiments ^
                --checkpoint_dir=experiments/checkpoint-maruko-regular-384 ^
                --input_nc=1 ^
                --gpu_ids=cuda:0 ^
                --resume=231 ^
                --self_attention ^
                --from_txt ^
                --filename_rule=unicode_int ^
                --src_font=source/font/SweiGothicCJKjp-DemiLight.ttf ^
                --src_font_y_offset=0 ^
                --src_txt_file=charset/charset_maruko_alpha.txt ^
                --canvas_size=384 ^
                --char_size=384 ^
                --label=16

修改後:

python infer.py --experiment_dir=experiments ^
                --checkpoint_dir=experiments/checkpoint-maruko-regular-alpha ^
                --input_nc=1 ^
                --gpu_ids=cuda:0 ^
                --resume=232 ^
                --self_attention ^
                --from_txt ^
                --filename_rule=unicode_int ^
                --canvas_size=384 ^
                --char_size=307 ^
                --resize_canvas=460 ^
                --src_font=source/font/SweiGothicCJKjp-DemiLight.ttf ^
                --src_font_y_offset=28 ^
                --src_txt_file=charset/charset_maruko_alpha.txt ^
                --crop_src_font ^
                --label=20

說明: char_size = 307 (=384 * 0.8) , resize_canvas=460 (=384 * 1.2)


在一開始的產生訓練的字集也有相同的問題.

1:1 的訓練, 在 384×384 的script:

python font2img.py --src_font=source/font/SweiGothicCJKjp-DemiLight.ttf ^
                   --dst_font=source/font/ZenMaruGothic-Regular.ttf ^
                   --charset=charset/charset_maruko_alpha.txt ^
                   --canvas_size=384 ^
                   --char_size=384 ^
                   --sample_dir=source/paired_images-maruko-alpha ^
                   --label=0 ^
                   --dst_y_offset=-113 ^
                   --mode=font2font

說明: 384×384中文字的情況下, noto sans 不用 offset, ZenMaruGothic offset y=-113 會剛好對齊.

python font2img.py --src_font=source/font/SweiGothicCJKjp-DemiLight.ttf ^
                   --dst_font=source/font/ZenMaruGothic-Regular.ttf ^
                   --charset=charset/charset_maruko_alpha.txt ^
                   --canvas_size=384 ^
                   --char_size=319 ^
                   --sample_dir=source/paired_images-maruko-alpha ^
                   --label=0 ^
                   --dst_y_offset=-113 ^
                   --mode=font2font

384 * 0.80 = 307, 新的 char size=307

384 – 307 = 77, offset = 77, 這是上+下=77, 所以 x,y offset=77 / 2=38.5

隨意微調後的 script:

python font2img.py --src_font=source/font/SweiGothicCJKjp-DemiLight.ttf ^
                   --dst_font=source/font/ZenMaruGothic-Regular.ttf ^
                   --sample_dir=source/paired_images-maruko-regular-384-alpha ^
                   --charset=charset/charset_maruko_alpha.txt ^
                   --canvas_size=384 ^
                   --char_size=307 ^
                   --label=0 ^
                   --src_x_offset=38 ^
                   --src_y_offset=28 ^
                   --dst_x_offset=38 ^
                   --dst_y_offset=-58 ^
                   --disable_auto_fit ^
                   --mode=font2font

主要就 gy 這2個字, 畫的位置很低, 所以讓 y_offset 高一點, 讓下半部可以完整顯示出來.


另一個解法是在繪圖時就置中, 參考看看:

程式碼範例:

image2 = Image.new('RGB', (100, 100), 'white')
draw2 = ImageDraw.Draw(image2)
draw2.text((50 + font2_x_offset, 50 + font2_y_offset), char, font=font2, fill='black', anchor='mm')

完整程式碼:
https://github.com/max32002/MaxFontScripts/blob/master/compare_fonts.py

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *