0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

EasyOCRで日本人だけが読めないフォント「Electroharmonix」を認識させてみた

Last updated at Posted at 2021-10-07

はじめに

EasyOCR

そもそもOCRとは?

  • Optical Character Recognitionの略
  • ざっくり画像から文字を抽出して認識する技術と理解している

Electroharmonix

  • 日本人だけが読めないフォントと言われているフォント
  • ちなみに、下記の画像はモレモコヤロカムヤ巾ロウエメElectroharmonixと書いてある
  • 記号とかはあるけど、大文字だけで小文字はなさそう
electorharmonix

(出典: Electroharmonix)

検証方法

  1. 下記のフォント使って「Hello, Wolrd」と書かれた画像を生成する
    • electroharmonix
    • IPAex明朝
    • IPAexゴシック
  2. EasyOCRで以下の言語を指定して文字認識を実行する
    • 英語
    • 日本語
    • 日本語&英語
  3. EasyOCRの出力した文字列から考察を行う

実装

実装といってもテキスト画像生成がメイン

事前準備

  • electroharmonixを含むいくつかのフォントを比較用にインストールしておく
  • 必要パッケージのインストール
    • 画像生成にpillowを用いるがEasyOCRに含まれていたため、EasyOCRのインストールのみで事足りた
    • パッケージ管理にはPoetryを利用している

Pillowを用いた画像生成

主な処理は以下の通り

  1. フォントサイズ: 48, 文字色: 黒, 背景色: 白に設定
  2. 指定したフォントでテキストを書いた時の領域(幅、高さ)を算出
  3. パディングが全体のテキスト領域の10%になるように画像サイズ、テキスト表示位置を設定
@dataclass
class TextImageGenerator:
    font_filepath: str = "fonts/ipaexg.ttf"
    fontsize: int = 48
    px_ratio: float = 0.1
    py_ratio: float = 0.1

    def generate(
        self,
        text: str,
        color: Color = (0, 0, 0),
        bg_color: Color = (255, 255, 255),
    ) -> Image:
        # fontを取得
        font = self._get_font()
        
        # 生成画像のサイズ、テキストの左上位置を取得
        canvas_size, text_tl = self._get_canvas_size(text, font)
        
        # 下地となるImageを作成
        img = self._get_canvas(bg_color, canvas_size)
        
        # 文字を描画
        draw = ImageDraw.Draw(img)
        draw.text(text_tl, text, fill=color, font=font)

        return img

    def _get_canvas_size(self, text: str, font: ImageFont.FreeTypeFont) -> Tuple[Tuple[int, int], Tuple[int, int]]:
        text_width, text_height = ImageDraw.Draw(Image.new("RGB", (200, 200))).textsize(text, font)
        width = int(text_width * (1 + 2 * self.px_ratio))
        height = int(text_height * (1 + 2 * self.py_ratio))

        text_top_left_x = int(width * self.px_ratio / (1 + 2 * self.px_ratio))
        text_top_left_y = int(height * self.py_ratio / (1 + 2 * self.py_ratio))
        return (width, height), (text_top_left_x, text_top_left_y)

    def _get_canvas(self, bg_color: Color, canvas_size: Tuple[int, int]) -> Image:
        return Image.new("RGB", canvas_size, bg_color)

    def _get_font(self) -> ImageFont.FreeTypeFont:
        return ImageFont.truetype(self.font_filepath, self.fontsize)

EasyOCRを用いた各フォント、言語での文字認識

主な処理は以下の通り

  • 生成画像に対してEasyOCRで文字認識を実行する
    • 認識した領域ごとに分割されてしまうため、全ての領域の結果を抽出する
  • 上記の処理をフォントごと、言語ごとに行う

結果

画像生成結果とOCRの認識結果は下記の通り

画像生成結果

electroharmonix

gen_electroharmonix_HELLO, WORLD!.png

IPAex明朝

gen_ipaexm_HELLO, WORLD!.png

IPAexゴシック

gen_ipaexg_HELLO, WORLD!.png

OCR認識結果

フォント 言語 結果
electroharmonix 英語 bELLA; WARlDi
electroharmonix 日本語 カモレレロ,山口ポレワ』
electroharmonix 英語&日本語 カモレレロ,山口ポレワ』
IPAex明朝 英語 HELLO, WORLDI'
IPAex明朝 日本語 チ__0, 0♪_」
IPAex明朝 英語&日本語 HELLO,VORLD」
IPAexゴシック 英語 HELLO, WORLDI
IPAexゴシック 日本語 んヒ__0一0二_!
IPAexゴシック 英語&日本語 HELLOWORLD!

考察

  • electroharmonix
    • 英語としても結構外れてる...
    • 日本人らしい認識だなぁ、一点気になるはヤじゃなくてポって読むのね
    • ロ(ろ)と口(くち)を分けてるところも日本人らしくて個人的にビックリした
    • 英語入れても日本語と一緒
  • IPAex系
    • 日本語として読めないのはまぁ分かる
    • 英語でも惜しいけど100点ではない「!」と「I」の違いって確かに結構難しい

まとめ

  • 他の記事でもみられるように、そもそも英語圏の人でも読みやすいフォントではなさそう
  • ただ、思ったよりも日本人寄りの認識結果だった
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?