tesseractでのOCR(横書きの資料 縦書きの資料)

目次

1. tesseractとは
2. Tesseractの特上
3. Tesseractの出力品質向上
4. tesseractの実験(コード)
4.1 横書きの資料
4.2 縦書きの資料
5. まとめ

 

1. tesseractとは

Tesseractは、オープンソースの光学文字認識(OCR)エンジンであり、文字を含む画像データからテキストデータを抽出するために使用されます。Tesseractは、元々ヒューレット・パッカード(HP)研究所で開発され、その後Googleによって取得され、オープンソースプロジェクトとしてリリースされました。Tesseractは高い精度で様々な言語のテキストを認識でき、印刷されたテキストや手書きのテキスト、さまざまなフォントやスタイルのテキストなどを処理する能力を持っています。

 

2. Tesseractの特上

– オープンソース: Tesseractはオープンソースプロジェクトであり、誰でも無料で使用できる上に、カスタマイズや拡張も可能です。

– 多言語サポート: Tesseractは多くの言語をサポートし、さまざまなテキストの書体や表現を認識できます。

– 高度な画像処理: Tesseractは内部で画像処理アルゴリズムを使用して、画像の前処理を行います。これにより、劣悪な画像品質でも比較的良好なOCR結果を得ることができます。

– コマンドラインツールとライブラリ: Tesseractはコマンドラインツールとしても使用できるほか、ライブラリとして他のアプリケーションに統合することも可能です。

– 学習とカスタマイズ: Tesseractは一般的なフォントやスタイルに対する事前学習がされており、特定のフォントや言語に適応させることも可能です。

– 活発なコミュニティ: Tesseractは大規模なコミュニティに支えられており、新機能の追加やバグ修正が継続的に行われています。

 

3. Tesseractの出力品質向上

OCRの結果を向上させるために画像の改善が重要です。

リスケーリング、2値化、ノイズ除去、膨張、収縮などの操作を適用します。

 

リスケーリング:

– 少なくとも300 DPIの画像を使用して最適な結果を得ます。

– 大文字の高さの最適なピクセル値が解像度に影響します。

 

2値化:

– 画像を白黒に変換して明瞭さを向上させます。

– Tesseractの組み込みメソッドが必ずしも適切でない場合、代替方法を試します。

 

ノイズ除去:

– ノイズはOCRの精度を低下させる可能性があります。

– ノイズ除去テクニックを使用して結果を改善します。

 

膨張と収縮:

– 太字や細字は認識に影響を与える可能性があります。

– 膨張は文字を拡大し、収縮は縮小します。

 

回転/歪み補正:

– 歪んだ画像を修正して行のセグメンテーションを改善します。

 

枠線:

– 認識の問題を防ぐために小さな白い枠線を追加します。

– スキャンされたページの枠線を取り除いて誤認識を防ぎます。

 

透明性/アルファチャンネル:

– OCRの前にアルファチャンネルを削除します。

– Tesseract 4.00はアルファチャンネルを自動的に削除しますが、手動で削除する場合もあります。

 

4. tesseractの実験(コード)

Google colabでpytesseractを実験します。

 

横書き資料と縦書き資料ファイルをダウンロードします。

%%capture

!wget https://github.com/jingwora/data/blob/main/ocr_ja/sample_h.png?raw=true -O sample_h.png

!wget https://github.com/jingwora/data/blob/main/ocr_ja/sample_v.png?raw=true -O sample_v.png

横書き資料

縦書き資料

 

環境構築

縦書き資料のOCRはtesseract-ocr-jpn-vertが必要です。

%%capture

!apt-get install -y tesseract-ocr

!apt-get install -y libtesseract-dev

!pip install pytesseract

!apt-get install tesseract-ocr-jpn-vert

!pip install mojimoji

 

Tesseractの言語を確認します。

別の言語を利用する場合は、下記のgithubで調べることができます。

https://github.com/tesseract-ocr/tessdata_best/tree/main

!tesseract –list-langs

List of available languages (4):

eng

jpn

jpn_vert

osd

 

4.1 横書きの資料

# ライブラリのインポート

import cv2

import pytesseract

from PIL import Image

import matplotlib.pyplot as plt

 

# OpenCVで画像を読み込みます。

image_path = ‘sample_h.png’

image = cv2.imread(image_path)

 

# grayscaleに変換

gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

 

PytesseractでOCRを行います。

pytesseractは、Pythonプログラミング言語向けのTesseract OCRエンジンのラッパーライブラリです。

# pytesseract

text_japanese = pytesseract.image_to_string(gray_image, lang=’jpn’)

 

# OCRの結果

print(“Extracted Japanese Text:”)

print(text_japanese)

 

# 画像の確認

plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))

plt.axis(‘off’)

plt.show()

Extracted Japanese Text:

サンマ初水揚げ、破格の最高値

1キロ 1 3万円…北海道・根室

サンマの棒受け網漁の小型船が北海道根室市の花咲港などで初水揚げ

し、1 9 日に行われた同湊の初競りでは、1 キロあたり1 3万円 (税

抜き) と破格の最高値をつけた。

1 9 日朝、歯舞漁協所属の「第5 5錦降丸」(1 9トン) が公海で

を終え、約4 6 9キロのサンマを同港に水揚げした。最高値は昨年の

同5万円を大幅に上回った。

花咲港に水揚げされたサンマ (1 9日午前4時4 9分、北海道根室市

で)

水産研究・教育機構 (横浜市) によると、今季のサンマ漁は過去最

低だった昨季並みの不六    るとみられている。

実際のテキストとOCRの結果を比較のために、テストデータを加工します。

# テストデータを加工

import mojimoji

import re

 

# 正解データ(actual)

actual_text = “””サンマ初水揚げ、破格の最高値

1キロ13万円…北海道・根室

サンマの棒受け網漁の小型船が北海道根室市の花咲港などで初水揚げし、19日に行われた同港の初競りでは、1キロあたり13万円(税抜き)と破格の最高値をつけた。

19日朝、歯舞漁協所属の「第55錦隆丸」(19トン)が公海での漁を終え、約469キロのサンマを同港に水揚げした。最高値は昨年の同5万円を大幅に上回った。

花咲港に水揚げされたサンマ(19日午前4時49分、北海道根室市で)

水産研究・教育機構(横浜市)によると、今季のサンマ漁は過去最低だった昨季並みの不漁になるとみられている。”””

 

stop_word = [“ ”, ” “, “\n”, “.”, “、”, “。”, “…”, “・”]

 

# 正解データの加工

actual_text = mojimoji.han_to_zen(actual_text, kana=True, digit=True)

actual_text = re.sub(r'[^\w\s]’, ”, actual_text)

for sw in stop_word:

actual_text = actual_text.replace(sw, “”)

 

# 予測データの加工

predicted_text = mojimoji.han_to_zen(text_japanese, kana=True, digit=True)

predicted_text = re.sub(r'[^\w\s]’, ”, predicted_text)

for sw in stop_word:

predicted_text = predicted_text.replace(sw, “”)

 

print(“predicted:”, predicted_text)

print(“actual   :”, actual_text)

predicted: サンマ初水揚げ破格の最高値1キロ13万円北海道根室サンマの棒受け網漁の小型船が北海道根室市の花咲港などで初水揚げし19日に行われた同湊の初競りでは1キロあたり13万円税抜きと破格の最高値をつけた19日朝歯舞漁協所属の第55錦降丸19トンが公海でを終え約469キロのサンマを同港に水揚げした最高値は昨年の同5万円を大幅に上回った花咲港に水揚げされたサンマ19日午前4時49分北海道根室市で水産研究教育機構横浜市によると今季のサンマ漁は過去最低だった昨季並みの不六るとみられている

actual   : サンマ初水揚げ破格の最高値1キロ13万円北海道根室サンマの棒受け網漁の小型船が北海道根室市の花咲港などで初水揚げし19日に行われた同港の初競りでは1キロあたり13万円税抜きと破格の最高値をつけた19日朝歯舞漁協所属の第55錦隆丸19トンが公海での漁を終え約469キロのサンマを同港に水揚げした最高値は昨年の同5万円を大幅に上回った花咲港に水揚げされたサンマ19日午前4時49分北海道根室市で水産研究教育機構横浜市によると今季のサンマ漁は過去最低だった昨季並みの不漁になるとみられている

 

SequenceMatcherで精度を計算します。

精度は98%くらいです。間違い結果は下記になります。
Unmatched Predicted Words: [‘湊’, ‘降’, ‘六’, ‘\x0c’]

Unmatched Actual Words:    [‘港’, ‘隆’, ‘の’, ‘漁’, ‘漁’, ‘に’, ‘な’]

import difflib

 

# Tokenize the strings into words

predicted_words = list(predicted_text)

actual_words = list(actual_text)

 

# Calculate the word similarity using the SequenceMatcher

matcher = difflib.SequenceMatcher(None, predicted_words, actual_words)

 

similarity_ratio = matcher.ratio()

matching_blocks = matcher.get_matching_blocks()

opcodes = matcher.get_opcodes()

 

# find unmatched words

unmatched_predicted_words = []

unmatched_actual_words = []

for tag, i1, i2, j1, j2 in opcodes:

if tag == ‘replace’ or tag == ‘delete’:

unmatched_predicted_words.extend(predicted_words[i1:i2])

if tag == ‘replace’ or tag == ‘insert’:

unmatched_actual_words.extend(actual_words[j1:j2])

 

print(“predicted_words: “, predicted_words)

print(“actual_words   : “, actual_words)

print(f”Word Similarity: {similarity_ratio:.4f}”)

print(“Unmatched Predicted Words:”, unmatched_predicted_words)

print(“Unmatched Actual Words:   “, unmatched_actual_words)

predicted_words:  [‘サ’, ‘ン’, ‘マ’, ‘初’, ‘水’, ‘揚’, ‘げ’, ‘破’, ‘格’, ‘の’, ‘最’, ‘高’, ‘値’, ‘1’, ‘キ’, ‘ロ’, ‘1’, ‘3’, ‘万’, ‘円’, ‘北’, ‘海’, ‘道’, ‘根’, ‘室’, ‘サ’, ‘ン’, ‘マ’, ‘の’, ‘棒’, ‘受’, ‘け’, ‘網’, ‘漁’, ‘の’, ‘小’, ‘型’, ‘船’, ‘が’, ‘北’, ‘海’, ‘道’, ‘根’, ‘室’, ‘市’, ‘の’, ‘花’, ‘咲’, ‘港’, ‘な’, ‘ど’, ‘で’, ‘初’, ‘水’, ‘揚’, ‘げ’, ‘し’, ‘1’, ‘9’, ‘日’, ‘に’, ‘行’, ‘わ’, ‘れ’, ‘た’, ‘同’, ‘湊’, ‘の’, ‘初’, ‘競’, ‘り’, ‘で’, ‘は’, ‘1’, ‘キ’, ‘ロ’, ‘あ’, ‘た’, ‘り’, ‘1’, ‘3’, ‘万’, ‘円’, ‘税’, ‘抜’, ‘き’, ‘と’, ‘破’, ‘格’, ‘の’, ‘最’, ‘高’, ‘値’, ‘を’, ‘つ’, ‘け’, ‘た’, ‘1’, ‘9’, ‘日’, ‘朝’, ‘歯’, ‘舞’, ‘漁’, ‘協’, ‘所’, ‘属’, ‘の’, ‘第’, ‘5’, ‘5’, ‘錦’, ‘降’, ‘丸’, ‘1’, ‘9’, ‘ト’, ‘ン’, ‘が’, ‘公’, ‘海’, ‘で’, ‘を’, ‘終’, ‘え’, ‘約’, ‘4’, ‘6’, ‘9’, ‘キ’, ‘ロ’, ‘の’, ‘サ’, ‘ン’, ‘マ’, ‘を’, ‘同’, ‘港’, ‘に’, ‘水’, ‘揚’, ‘げ’, ‘し’, ‘た’, ‘最’, ‘高’, ‘値’, ‘は’, ‘昨’, ‘年’, ‘の’, ‘同’, ‘5’, ‘万’, ‘円’, ‘を’, ‘大’, ‘幅’, ‘に’, ‘上’, ‘回’, ‘っ’, ‘た’, ‘花’, ‘咲’, ‘港’, ‘に’, ‘水’, ‘揚’, ‘げ’, ‘さ’, ‘れ’, ‘た’, ‘サ’, ‘ン’, ‘マ’, ‘1’, ‘9’, ‘日’, ‘午’, ‘前’, ‘4’, ‘時’, ‘4’, ‘9’, ‘分’, ‘北’, ‘海’, ‘道’, ‘根’, ‘室’, ‘市’, ‘で’, ‘水’, ‘産’, ‘研’, ‘究’, ‘教’, ‘育’, ‘機’, ‘構’, ‘横’, ‘浜’, ‘市’, ‘に’, ‘よ’, ‘る’, ‘と’, ‘今’, ‘季’, ‘の’, ‘サ’, ‘ン’, ‘マ’, ‘漁’, ‘は’, ‘過’, ‘去’, ‘最’, ‘低’, ‘だ’, ‘っ’, ‘た’, ‘昨’, ‘季’, ‘並’, ‘み’, ‘の’, ‘不’, ‘六’, ‘る’, ‘と’, ‘み’, ‘ら’, ‘れ’, ‘て’, ‘い’, ‘る’, ‘\x0c’]

actual_words   :  [‘サ’, ‘ン’, ‘マ’, ‘初’, ‘水’, ‘揚’, ‘げ’, ‘破’, ‘格’, ‘の’, ‘最’, ‘高’, ‘値’, ‘1’, ‘キ’, ‘ロ’, ‘1’, ‘3’, ‘万’, ‘円’, ‘北’, ‘海’, ‘道’, ‘根’, ‘室’, ‘サ’, ‘ン’, ‘マ’, ‘の’, ‘棒’, ‘受’, ‘け’, ‘網’, ‘漁’, ‘の’, ‘小’, ‘型’, ‘船’, ‘が’, ‘北’, ‘海’, ‘道’, ‘根’, ‘室’, ‘市’, ‘の’, ‘花’, ‘咲’, ‘港’, ‘な’, ‘ど’, ‘で’, ‘初’, ‘水’, ‘揚’, ‘げ’, ‘し’, ‘1’, ‘9’, ‘日’, ‘に’, ‘行’, ‘わ’, ‘れ’, ‘た’, ‘同’, ‘港’, ‘の’, ‘初’, ‘競’, ‘り’, ‘で’, ‘は’, ‘1’, ‘キ’, ‘ロ’, ‘あ’, ‘た’, ‘り’, ‘1’, ‘3’, ‘万’, ‘円’, ‘税’, ‘抜’, ‘き’, ‘と’, ‘破’, ‘格’, ‘の’, ‘最’, ‘高’, ‘値’, ‘を’, ‘つ’, ‘け’, ‘た’, ‘1’, ‘9’, ‘日’, ‘朝’, ‘歯’, ‘舞’, ‘漁’, ‘協’, ‘所’, ‘属’, ‘の’, ‘第’, ‘5’, ‘5’, ‘錦’, ‘隆’, ‘丸’, ‘1’, ‘9’, ‘ト’, ‘ン’, ‘が’, ‘公’, ‘海’, ‘で’, ‘の’, ‘漁’, ‘を’, ‘終’, ‘え’, ‘約’, ‘4’, ‘6’, ‘9’, ‘キ’, ‘ロ’, ‘の’, ‘サ’, ‘ン’, ‘マ’, ‘を’, ‘同’, ‘港’, ‘に’, ‘水’, ‘揚’, ‘げ’, ‘し’, ‘た’, ‘最’, ‘高’, ‘値’, ‘は’, ‘昨’, ‘年’, ‘の’, ‘同’, ‘5’, ‘万’, ‘円’, ‘を’, ‘大’, ‘幅’, ‘に’, ‘上’, ‘回’, ‘っ’, ‘た’, ‘花’, ‘咲’, ‘港’, ‘に’, ‘水’, ‘揚’, ‘げ’, ‘さ’, ‘れ’, ‘た’, ‘サ’, ‘ン’, ‘マ’, ‘1’, ‘9’, ‘日’, ‘午’, ‘前’, ‘4’, ‘時’, ‘4’, ‘9’, ‘分’, ‘北’, ‘海’, ‘道’, ‘根’, ‘室’, ‘市’, ‘で’, ‘水’, ‘産’, ‘研’, ‘究’, ‘教’, ‘育’, ‘機’, ‘構’, ‘横’, ‘浜’, ‘市’, ‘に’, ‘よ’, ‘る’, ‘と’, ‘今’, ‘季’, ‘の’, ‘サ’, ‘ン’, ‘マ’, ‘漁’, ‘は’, ‘過’, ‘去’, ‘最’, ‘低’, ‘だ’, ‘っ’, ‘た’, ‘昨’, ‘季’, ‘並’, ‘み’, ‘の’, ‘不’, ‘漁’, ‘に’, ‘な’, ‘る’, ‘と’, ‘み’, ‘ら’, ‘れ’, ‘て’, ‘い’, ‘る’]

Word Similarity: 0.9771

Unmatched Predicted Words: [‘湊’, ‘降’, ‘六’, ‘\x0c’]

Unmatched Actual Words:    [‘港’, ‘隆’, ‘の’, ‘漁’, ‘漁’, ‘に’, ‘な’]

 

4.2 縦書きの資料

縦書きの資料

# ライブラリのインポート

import cv2

import pytesseract

from PIL import Image

import matplotlib.pyplot as plt

 

# OpenCVで画像を読み込みます

image_path = ‘sample_v.png’

image = cv2.imread(image_path)

 

# grayscaleに変換

gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

 

PytesseractでOCRを行います。

# pytesseract

text_japanese = pytesseract.image_to_string(gray_image, lang=’jpn’)

 

# OCRの結果

print(“Extracted Japanese Text:”)

print(text_japanese)

 

# 画像の確認

plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))

plt.axis(‘off’)

plt.show()

Extracted Japanese Text:

サン マ 初 水揚げ 、 破 格 の 最高 値

1 キロ 13 万 円 … 北 海道 ・ 根 室

サン マ の 棒 受 け 綱 漁 の 小型 船 が 北海 道 根室 市 の 花咲 港 な ど で 初 水揚げ

し 、19 日 に 行わ れ た 同 港 の 初 競り で は 、1 キ ロ あ た り 13 万 円 ( 税

拡 き ) と 破格 の 最高 値 を つけ た 。

19 日 朝 、 歯 舞 漁 協 所 属 の 「 第 55 錦 隆 丸 」(19 ト ン ) が 公海 で の 漁

を 終え 、 約 469 キ ロ の サン マ を 同 港 に 水揚げ し た 。 最 高値 は 昨年 の

同 5 万 円 を 大 幅 に 上 回 っ た 。

花 順 港 に 水揚げ され た サン マ (19 日 午前 4 時 49 分 、 北 海道 根室 店

で )

水産 研究 ・ 教 育 機構 (横浜 市 ) に よる と 、 今 季 の サン マ 漁 は 過去 最

低 だ っ た 昨 手 並み の 不 汰 に な る と み ら れ て いる 。

精度の計算のために、テキストの前処理です。

# Cleaning output

 

import mojimoji

import re

 

# Ground truth (actual) text

actual_text = “””サンマ初水揚げ、破格の最高値

1キロ13万円…北海道・根室

サンマの棒受け網漁の小型船が北海道根室市の花咲港などで初水揚げし、19日に行われた同港の初競りでは、1キロあたり13万円(税抜き)と破格の最高値をつけた。

19日朝、歯舞漁協所属の「第55錦隆丸」(19トン)が公海での漁を終え、約469キロのサンマを同港に水揚げした。最高値は昨年の同5万円を大幅に上回った。

花咲港に水揚げされたサンマ(19日午前4時49分、北海道根室市で)

水産研究・教育機構(横浜市)によると、今季のサンマ漁は過去最低だった昨季並みの不漁になるとみられている。”””

 

stop_word = [“ ”, ” “, “\n”, “.”, “、”, “。”, “…”, “・”]

 

# Convert actual text to half-width

actual_text = mojimoji.han_to_zen(actual_text, kana=True, digit=True)

actual_text = re.sub(r'[^\w\s]’, ”, actual_text)

for sw in stop_word:

actual_text = actual_text.replace(sw, “”)

 

# Convert actual text to half-width

predicted_text = mojimoji.han_to_zen(text_japanese, kana=True, digit=True)

predicted_text = re.sub(r'[^\w\s]’, ”, predicted_text)

for sw in stop_word:

predicted_text = predicted_text.replace(sw, “”)

 

print(“predicted:”, predicted_text)

print(“actual   :”, actual_text)

predicted: サンマ初水揚げ破格の最高値1キロ13万円北海道根室サンマの棒受け綱漁の小型船が北海道根室市の花咲港などで初水揚げし19日に行われた同港の初競りでは1キロあたり13万円税拡きと破格の最高値をつけた19日朝歯舞漁協所属の第55錦隆丸19トンが公海での漁を終え約469キロのサンマを同港に水揚げした最高値は昨年の同5万円を大幅に上回った花順港に水揚げされたサンマ19日午前4時49分北海道根室店で水産研究教育機構横浜市によると今季のサンマ漁は過去最低だった昨手並みの不汰になるとみられている

actual   : サンマ初水揚げ破格の最高値1キロ13万円北海道根室サンマの棒受け網漁の小型船が北海道根室市の花咲港などで初水揚げし19日に行われた同港の初競りでは1キロあたり13万円税抜きと破格の最高値をつけた19日朝歯舞漁協所属の第55錦隆丸19トンが公海での漁を終え約469キロのサンマを同港に水揚げした最高値は昨年の同5万円を大幅に上回った花咲港に水揚げされたサンマ19日午前4時49分北海道根室市で水産研究教育機構横浜市によると今季のサンマ漁は過去最低だった昨季並みの不漁になるとみられている

 

精度を計算します。

精度は97%になります。

間違いテストは下記になります。

Unmatched Predicted Words: [‘綱’, ‘拡’, ‘順’, ‘店’, ‘手’, ‘汰’, ‘\x0c’]

Unmatched Actual Words:    [‘網’, ‘抜’, ‘咲’, ‘市’, ‘季’, ‘漁’]

import difflib

 

# Tokenize the strings into words

predicted_words = list(predicted_text)

actual_words = list(actual_text)

 

# Calculate the word similarity using the SequenceMatcher

matcher = difflib.SequenceMatcher(None, predicted_words, actual_words)

 

similarity_ratio = matcher.ratio()

matching_blocks = matcher.get_matching_blocks()

opcodes = matcher.get_opcodes()

 

# find unmatched words

unmatched_predicted_words = []

unmatched_actual_words = []

for tag, i1, i2, j1, j2 in opcodes:

if tag == ‘replace’ or tag == ‘delete’:

unmatched_predicted_words.extend(predicted_words[i1:i2])

if tag == ‘replace’ or tag == ‘insert’:

unmatched_actual_words.extend(actual_words[j1:j2])

 

print(“predicted_words: “, predicted_words)

print(“actual_words   : “, actual_words)

print(f”Word Similarity: {similarity_ratio:.4f}”)

print(“Unmatched Predicted Words:”, unmatched_predicted_words)

print(“Unmatched Actual Words:   “, unmatched_actual_words)

predicted_words:  [‘サ’, ‘ン’, ‘マ’, ‘初’, ‘水’, ‘揚’, ‘げ’, ‘破’, ‘格’, ‘の’, ‘最’, ‘高’, ‘値’, ‘1’, ‘キ’, ‘ロ’, ‘1’, ‘3’, ‘万’, ‘円’, ‘北’, ‘海’, ‘道’, ‘根’, ‘室’, ‘サ’, ‘ン’, ‘マ’, ‘の’, ‘棒’, ‘受’, ‘け’, ‘綱’, ‘漁’, ‘の’, ‘小’, ‘型’, ‘船’, ‘が’, ‘北’, ‘海’, ‘道’, ‘根’, ‘室’, ‘市’, ‘の’, ‘花’, ‘咲’, ‘港’, ‘な’, ‘ど’, ‘で’, ‘初’, ‘水’, ‘揚’, ‘げ’, ‘し’, ‘1’, ‘9’, ‘日’, ‘に’, ‘行’, ‘わ’, ‘れ’, ‘た’, ‘同’, ‘港’, ‘の’, ‘初’, ‘競’, ‘り’, ‘で’, ‘は’, ‘1’, ‘キ’, ‘ロ’, ‘あ’, ‘た’, ‘り’, ‘1’, ‘3’, ‘万’, ‘円’, ‘税’, ‘拡’, ‘き’, ‘と’, ‘破’, ‘格’, ‘の’, ‘最’, ‘高’, ‘値’, ‘を’, ‘つ’, ‘け’, ‘た’, ‘1’, ‘9’, ‘日’, ‘朝’, ‘歯’, ‘舞’, ‘漁’, ‘協’, ‘所’, ‘属’, ‘の’, ‘第’, ‘5’, ‘5’, ‘錦’, ‘隆’, ‘丸’, ‘1’, ‘9’, ‘ト’, ‘ン’, ‘が’, ‘公’, ‘海’, ‘で’, ‘の’, ‘漁’, ‘を’, ‘終’, ‘え’, ‘約’, ‘4’, ‘6’, ‘9’, ‘キ’, ‘ロ’, ‘の’, ‘サ’, ‘ン’, ‘マ’, ‘を’, ‘同’, ‘港’, ‘に’, ‘水’, ‘揚’, ‘げ’, ‘し’, ‘た’, ‘最’, ‘高’, ‘値’, ‘は’, ‘昨’, ‘年’, ‘の’, ‘同’, ‘5’, ‘万’, ‘円’, ‘を’, ‘大’, ‘幅’, ‘に’, ‘上’, ‘回’, ‘っ’, ‘た’, ‘花’, ‘順’, ‘港’, ‘に’, ‘水’, ‘揚’, ‘げ’, ‘さ’, ‘れ’, ‘た’, ‘サ’, ‘ン’, ‘マ’, ‘1’, ‘9’, ‘日’, ‘午’, ‘前’, ‘4’, ‘時’, ‘4’, ‘9’, ‘分’, ‘北’, ‘海’, ‘道’, ‘根’, ‘室’, ‘店’, ‘で’, ‘水’, ‘産’, ‘研’, ‘究’, ‘教’, ‘育’, ‘機’, ‘構’, ‘横’, ‘浜’, ‘市’, ‘に’, ‘よ’, ‘る’, ‘と’, ‘今’, ‘季’, ‘の’, ‘サ’, ‘ン’, ‘マ’, ‘漁’, ‘は’, ‘過’, ‘去’, ‘最’, ‘低’, ‘だ’, ‘っ’, ‘た’, ‘昨’, ‘手’, ‘並’, ‘み’, ‘の’, ‘不’, ‘汰’, ‘に’, ‘な’, ‘る’, ‘と’, ‘み’, ‘ら’, ‘れ’, ‘て’, ‘い’, ‘る’, ‘\x0c’]

actual_words   :  [‘サ’, ‘ン’, ‘マ’, ‘初’, ‘水’, ‘揚’, ‘げ’, ‘破’, ‘格’, ‘の’, ‘最’, ‘高’, ‘値’, ‘1’, ‘キ’, ‘ロ’, ‘1’, ‘3’, ‘万’, ‘円’, ‘北’, ‘海’, ‘道’, ‘根’, ‘室’, ‘サ’, ‘ン’, ‘マ’, ‘の’, ‘棒’, ‘受’, ‘け’, ‘網’, ‘漁’, ‘の’, ‘小’, ‘型’, ‘船’, ‘が’, ‘北’, ‘海’, ‘道’, ‘根’, ‘室’, ‘市’, ‘の’, ‘花’, ‘咲’, ‘港’, ‘な’, ‘ど’, ‘で’, ‘初’, ‘水’, ‘揚’, ‘げ’, ‘し’, ‘1’, ‘9’, ‘日’, ‘に’, ‘行’, ‘わ’, ‘れ’, ‘た’, ‘同’, ‘港’, ‘の’, ‘初’, ‘競’, ‘り’, ‘で’, ‘は’, ‘1’, ‘キ’, ‘ロ’, ‘あ’, ‘た’, ‘り’, ‘1’, ‘3’, ‘万’, ‘円’, ‘税’, ‘抜’, ‘き’, ‘と’, ‘破’, ‘格’, ‘の’, ‘最’, ‘高’, ‘値’, ‘を’, ‘つ’, ‘け’, ‘た’, ‘1’, ‘9’, ‘日’, ‘朝’, ‘歯’, ‘舞’, ‘漁’, ‘協’, ‘所’, ‘属’, ‘の’, ‘第’, ‘5’, ‘5’, ‘錦’, ‘隆’, ‘丸’, ‘1’, ‘9’, ‘ト’, ‘ン’, ‘が’, ‘公’, ‘海’, ‘で’, ‘の’, ‘漁’, ‘を’, ‘終’, ‘え’, ‘約’, ‘4’, ‘6’, ‘9’, ‘キ’, ‘ロ’, ‘の’, ‘サ’, ‘ン’, ‘マ’, ‘を’, ‘同’, ‘港’, ‘に’, ‘水’, ‘揚’, ‘げ’, ‘し’, ‘た’, ‘最’, ‘高’, ‘値’, ‘は’, ‘昨’, ‘年’, ‘の’, ‘同’, ‘5’, ‘万’, ‘円’, ‘を’, ‘大’, ‘幅’, ‘に’, ‘上’, ‘回’, ‘っ’, ‘た’, ‘花’, ‘咲’, ‘港’, ‘に’, ‘水’, ‘揚’, ‘げ’, ‘さ’, ‘れ’, ‘た’, ‘サ’, ‘ン’, ‘マ’, ‘1’, ‘9’, ‘日’, ‘午’, ‘前’, ‘4’, ‘時’, ‘4’, ‘9’, ‘分’, ‘北’, ‘海’, ‘道’, ‘根’, ‘室’, ‘市’, ‘で’, ‘水’, ‘産’, ‘研’, ‘究’, ‘教’, ‘育’, ‘機’, ‘構’, ‘横’, ‘浜’, ‘市’, ‘に’, ‘よ’, ‘る’, ‘と’, ‘今’, ‘季’, ‘の’, ‘サ’, ‘ン’, ‘マ’, ‘漁’, ‘は’, ‘過’, ‘去’, ‘最’, ‘低’, ‘だ’, ‘っ’, ‘た’, ‘昨’, ‘季’, ‘並’, ‘み’, ‘の’, ‘不’, ‘漁’, ‘に’, ‘な’, ‘る’, ‘と’, ‘み’, ‘ら’, ‘れ’, ‘て’, ‘い’, ‘る’]

Word Similarity: 0.9732

Unmatched Predicted Words: [‘綱’, ‘拡’, ‘順’, ‘店’, ‘手’, ‘汰’, ‘\x0c’]

Unmatched Actual Words:    [‘網’, ‘抜’, ‘咲’, ‘市’, ‘季’, ‘漁’]

 

5. まとめ

この記事では、オープンソースの光学文字認識(OCR)エンジンであるTesseractについて紹介しました。Tesseractは画像データからテキストを抽出する能力を持ち、多言語対応や高度な画像処理による前処理が特徴です。また、Tesseractはオープンソースであり、カスタマイズが可能であり、多言語のテキスト認識にも優れた性能を示します。さらに、画像処理による前処理を行うことで、様々なフォントやスタイルのテキストに対しても高い精度を保つことができます。精度を向上させるために、リスケーリング、2値化、ノイズ除去、膨張、収縮などの処理が必要です。

 

また、この記事では横書きの資料と縦書きの資料を実験しました。Gray scaleの処理だけでも、97%以上の精度が得られました。これによりTesseractの強力なOCR性能が確認されました。Tesseractは幅広い用途において高いテキスト抽出能力を持つツールと言えるでしょう。

 

参照:

 

担当者:KW
バンコクのタイ出身 データサイエンティスト
製造、マーケティング、財務、AI研究などの様々な業界にPSI生産管理、在庫予測・最適化分析、顧客ロイヤルティ分析、センチメント分析、SaaS、PaaS、IaaS、AI at the Edge の環境構築などのスペシャリスト