Tesseract OCR / pytesseract メモ
Tesseract OCR v4 / pytesseract を使用して日本語 PDF の OCR を行いました。 サンプル PDF として、パブリックドメインの太宰治「走れメロス!」を使用しました。
この投稿のサンプルは、 GitHub リポジトリから取得できます。
Python
PDF は以下の手順で処理されます。
- pdf2image ライブラリを使用して、 PDF を PNG に変換
- Tesseract OCR / pytesseract を使用して変換されたイメージから文字を抽出
- 結果をテキストファイルに保存
import re
from datetime import datetime
import pdf2image
import pytesseract
def to_images(pdf_path: str, first_page: int = None, last_page: int = None) -> list:
""" Convert a PDF to a PNG image.
Args:
pdf_path (str): PDF path
first_page (int): First page starting 1 to be converted
last_page (int): Last page to be converted
Returns:
list: List of image data
"""
print(f'Convert a PDF ({pdf_path}) to a png...')
images = pdf2image.convert_from_path(
pdf_path=pdf_path,
fmt='png',
first_page=first_page,
last_page=last_page,
)
print(f'A total of converted png images is {len(images)}.')
return images
def to_string(image) -> str:
""" OCR an image data.
Args:
image: Image data
Returns:
str: OCR processed characters
"""
print(f'Extract characters from an image...')
return pytesseract.image_to_string(image, lang='jpn')
def normalize(target: str) -> str:
""" Normalize result text.
Applying the following:
- Remove newlines.
- Remove spaces between Japanese characters.
Args:
target (str): Target text to be normalized
Returns:
str: Normalized text
"""
result = re.sub('\n', '', target)
result = re.sub('([あ-んア-ン一-鿐])\s+((?=[あ-んア-ン一-鿐]))', r'\1\2', result)
return result
def save(result: str) -> str:
""" Save the result text in a text file.
Args:
result (str): Result text
Returns:
str: Text file path
"""
path = 'result.txt'
with open(path, 'w') as f:
f.write(result)
return path
def main() -> None:
start = datetime.now()
result = ''
images = to_images('run-melos.pdf', 1, 2)
for image in images:
result += to_string(image)
result = normalize(result)
path = save(result)
end = datetime.now()
duration = end.timestamp() - start.timestamp()
print('----------------------------------------')
print(f'Start: {start}')
print(f'End: {end}')
print(f'Duration: {int(duration)} seconds')
print(f'Result file path: {path}')
print('----------------------------------------')
if __name__ == '__main__':
main()
結果
原文
メロスは激怒した。必ず、かの邪智暴虐(じやちぼうぎやく)の王を除かなければならぬと決意した。メロスには政治がわからぬ。メロスは、村の牧人である。笛を吹き、羊と遊んで暮して來た。けれども邪惡に對しては、人一倍に敏感であつた。けふ未明メロスは村を出發し、野を越え山越え、十里はなれた此のシラクスの市にやつて來た。メロスには父も、母も無い。女房も無い。十六の、内氣な妹と二人暮しだ。この妹は、村の或る律氣(りちぎ)な一牧人を、近々、花婿として迎へる事になつてゐた。結婚式も間近かなのである。メロスは、それゆゑ、花嫁の衣裳(いしやう)やら祝宴の御馳走(ごちそう)やらを買ひに、はるばる市にやつて來たのだ。先(ま)づ、その品々を買ひ集め、それから都の大路をぶらぶら歩いた。メロスには竹馬(ちくば)の友があつた。セリヌンテイウスである。今は此のシラクスの市で、石工をしてゐる。その友を、これから訪ねてみるつもりなのだ。久しく逢(あ)はなかつたのだから、訪ねて行くのが樂しみである。歩いてゐるうちにメロスは、まちの樣子を怪しく思つた。ひつそりしてゐる。もう既に日も落ちて、まちの暗いのは當りまへだが、けれども、なんだか、夜のせゐばかりでは無く、市全體が、やけに寂しい。のんきなメロスも、だんだん不安になつて來た。路(みち)で逢つた若い衆をつかまへて、何かあつたのか、二年まへに此の市に來たときは、夜でも皆が歌をうたつて、まちは賑(にぎ)やかであつた筈(はず)だが、と質問した。若い衆は、首を振つて答へなかつた。しばらく歩いて老爺(らうや)に逢ひ、こんどはもつと、語勢を強くして質問した。老爺は答へなかつた。メロスは兩手で老爺のからだをゆすぶつて質問を重ねた。老爺は、あたりをはばかる低聲で、わづか答へた。「王樣は、人を殺します。」「なぜ殺すのだ。」「惡心を抱いてゐる、といふのですが、誰もそんな、惡心を持つては居りませぬ。」「たくさんの人を殺したのか。」「はい、はじめは王樣の妹婿さまを。それから、御自身のお世嗣(よつぎ)を。それから、妹さまを。それから、妹さまの御子さまを。それから、皇后さまを。それから、賢臣のアレキス樣を。」「おどろいた。國王は亂心か。」「いいえ、亂心ではございませぬ。人を、信ずる事が出來ぬ、といふのです。このごろは、臣下の心をも、お疑ひになり、少しく派手な暮しをしてゐる者には、人質ひとりづつ差し出すことを命じて居ります。御命令を拒めば十字架にかけられて、殺されます。けふは、六人殺されました。」 聞いて、メロスは激怒した。「呆(あき)れた王だ。生かして置けぬ。」 メロスは、單純な男であつた。買ひ物を、背負つたままで、のそのそ王城にはひつて行つた。たちまち彼は、巡邏(じゆんら)の警吏に捕縛された。調べられて、メロスの懷中からは短劍が出て來たので、騷ぎが大きくなつてしまつた。メロスは、王の前に引き出された。「この短刀で何をするつもりであつたか。言へ!」暴君デイオニスは靜かに、けれども威嚴を以て問ひつめた。その王の顏は蒼白(さうはく)で、眉間(みけん)の皺(しわ)は、刻み込まれたやうに深かつた。「市を暴君の手から救ふのだ。」とメロスは惡びれずに答へた。「おまへがか?」王は、憫笑(びんせう)した。「仕方の無いやつぢや。おまへには、わしの孤獨がわからぬ。」「言ふな!」とメロスは、いきり立つて反駁(はんばく)した。「人の心を疑ふのは、最も恥づべき惡徳だ。王は、民の忠誠をさへ疑つて居られる。」「疑ふのが、正當の心構へなのだと、わしに教へてくれたのは、おまへたちだ。人の心は、あてにならない。人間は、もともと私慾のかたまりさ。信じては、ならぬ。」暴君は落着いて呟(つぶや)き、ほつと溜息をついた。「わしだつて、平和を望んでゐるのだが。」「なんの爲の平和だ。自分の地位を守る爲か。」こんどはメロスが嘲笑(てうせう)した。「罪の無い人を殺して、何が平和だ。」「だまれ、下賤(げせん)の者。」王は、さつと顏を擧げて報いた。「口では、どんな清らかな事でも言へる。わしには、人の腹綿の奧底が見え透いてならぬ。おまへだつて、いまに、磔(はりつけ)になつてから、泣いて詫(わ)びたつて聞かぬぞ。」「ああ、王は悧巧(りかう)だ。自惚(うぬぼ)れてゐるがよい。私は、ちやんと死ぬる覺悟で居るのに。命乞(いのちご)ひなど決してしない。ただ、--」と言ひかけて、メロスは足もとに視線を落し瞬時ためらひ、「ただ、私に情をかけたいつもりなら、處刑までに三日間の日限を與へて下さい。たつた一人の妹に、亭主を持たせてやりたいのです。三日のうちに、私は村で結婚式を擧げさせ、必ず、ここへ歸つて來ます。」「ばかな。」と暴君は、嗄(しはが)れた聲で低く笑つた。「とんでもない嘘(うそ)を言ふわい。逃がした小鳥が歸つて來るといふのか。」「さうです。歸つて來るのです。」メロスは必死で言ひ張つた。「私は約束を守ります。私を、三日間だけ許して下さい。妹が、私の歸りを待つてゐるのだ。そんなに私を信じられないならば、よろしい、この市にセリヌンテイウスといふ石工がゐます。私の無二の友人だ。あれを、人質としてここに置いて行かう。私が逃げてしまつて、三日目の日暮まで、ここに歸つて來なかつたら、あの友人を絞め殺して下さい。たのむ。さうして下さい。」 それを聞いて王は、殘虐な氣持で、そつと北叟笑(ほくそゑ)んだ。生意氣なことを言ふわい。どうせ歸つて來ないにきまつてゐる。この嘘つきに騙(だま)された振りして、放してやるのも面白い。さうして身代りの男を、三日目に殺してやるのも氣味がいい。人は、これだから信じられぬと、わしは悲しい顏して、その身代りの男を磔刑(たくけい)に處してやるのだ。世の中の、正直者とかいふ奴輩(やつばら)にうんと見せつけてやりたいものさ。「願ひを、聞いた。その身代りを呼ぶがよい。三目日には日沒までに歸つて來い。おくれたら、その身代りを、きつと殺すぞ。ちよつとおくれて來るがいい。おまへの罪は、永遠にゆるしてやらうぞ。」「なに、何をおつしやる。」「はは。いのちが大事だつたら、おくれて來い。おまへの心は、わかつてゐるぞ。」 メロスは口惜しく、地團駄踏(ぢだんだふ)んだ。ものも言ひたくなくなつた。 竹馬の友、セリヌンテイウスは、深夜、王城に召された。暴君デイオニスの面前で、佳(よ)き友と佳き友は、二年ぶりで相逢うた。メロスは、友に一切の事情を語つた。セリヌンテイウスは無言で首肯(うなづ)き、メロスをひしと抱きしめた。友と友の間は、それでよかつた。セリヌンテイウスは、繩打たれた。メロスは、すぐに出發した。初夏、滿天の星である。 メロスはその夜、一睡もせず十里の路を急ぎに急いで、村へ到着したのは、翌(あく)る日の午前、陽は既に高く昇つて、村人たちは野に出て仕事をはじめてゐた。メロスの十六の妹も、けふは兄の代りに羊群の番をしてゐた。よろめいて歩いて來る兄の、疲勞困憊(ひらうこんぱい)の姿を見つけて驚いた。さうして、うるさく兄に質問を浴びせた。「なんでも無い。」メロスは無理に笑はうと努めた。「市に用事を殘して來た。またすぐ市に行かなければならぬ。あす、おまへの結婚式を擧げる。早いはうがよからう。」 妹は頬(ほほ)をあからめた。「うれしいか。綺麗(きれい)な衣裳(いしやう)も買つて來た。さあ、これから行つて、村の人たちに知らせて來い。結婚式は、あすだと。」 メロスは、また、よろよろと歩き出し、家へ歸つて神々の祭壇を飾り、祝宴の席を調へ、間もなく床に倒れ伏し、呼吸もせぬくらゐの深い眠りに落ちてしまつた。 眼が覺めたのは夜だつた。メロスは起きてすぐ、花婿の家を訪れた。さうして、少し事情があるから、結婚式を明日にしてくれ、と頼んだ。婿の牧人は驚き、それはいけない、こちらには未だ何の仕度も出來てゐない、葡萄(ぶだう)の季節まで待つてくれ、と答へた。メロスは、待つことは出來ぬ、どうか明日にしてくれ
OCR 処理結果
メロスは激怒した。必ず、かの邪智暴上(じゃちぼうぎやく)の王を除かなければならぬと決意した。メロスには政治がわからぬ。メロスは、村の牧人である。笛を吹き、羊と遊んで暮して來たを。けれども那章に半しては、人一倍に敏感であつた。けょ未明メロスは村を出紙し、野を越え山越え、十里はなれた此のシラクスの市にやつて來た。メロスには父も、母も無い。女房も無い。十六の、内気な妹と二人暮しだ。この妹は、村の或る律舞(りちぎ)な一牧人を、近々、花婚として迎へる事になつてゐた。結婚式も間近かなのである。メロスは、それゆる、和花嫁の衣裳(いしゃう)やら祝宴の御馳走(ごちをそう)やらを買ひに、はるばる市にやつて來たのだ。先(ま)づ、その品々を買ひ集め、それから都の大路をぶらぶら歩いた。メロスには竹馬(ちくば)の友があつた。セリヌンテイウスである。 今は此Mのシラクスの市で、石工をしてゐる。その友を、これから訪ねてみるつもりなのだ。 久しく人逢(ぁ)はなかつたのだから、訪ねて行くのが楽しみである。歩いてゐるうちにメロスは、まちの様子を怪しく思つた。ひつそりしてゐる。 もう既に日も落ちて、まちの暗いのは常りまへだが、けれども、なんだか、夜のせるばかりでは無く、市全骨が、やけに外しい。のんきなメロスも、だんだん不安になつて來た。路(みち)で逢つた若い衆をつかまへて、何かあつたのか、二年まへに此の市に來たときは、夜でも皆が歌をうたつて、まちは賑(にぎ)やかであつた管(はず)だが、と質問した。若い衆は、首を振つて答へなかつた。しばらく歩いて老爺(らうゃ)に逢ひ、こんどはもつと、語勢を強くして質問した。老爺は答へなかつた。メロスは了規手で老爺のからだをゆすぶつて質問を重ねた。老谷は、あたりをはばかる低衣で、わづか答へた。「王様は、人を殺します。」「なぜ殺すのだ。」「悪心を抱いてゐる、といふのですが、誰もそんな、悪心を持つては居りませめぬ。」「たくさんの人を殺したのか。」「はい、はじめは王様の妹婚さまを。それから、御自身のお世識(よっぎ)を。それから、妹さまを。それから、妹さまの御子きまを。それから、和皇后さまを。それから、賢到のアレキス様を。」「おどろいた。國王は負心か。」「いいえ、角心ではございませぬ。人を、信ずる事が出来ぬ、といふのです。このごろは、臣下の心をも、お疑ひになり、少しく派手な暮しをしてゐる者には、人質ひとりづつ差し出すことを命じて居ります。御命令を拒めば十字架にかけられて、殺されます。けふは、六人殺されました。 」聞いて、メロスは激怒した。 「果(ぁき)れた王だ。生かして置けめ。」メロスは、晶純な男であつた。買ひ物を、背負つたままで、のそのるそ王城にはひつて行つた。たちまと彼は、巡漏(じゅんら)の警更に捕縛された。調べられて、メロスの居中からは短剣が出て來たので、騒ぎが大きくなつてしまつた。メロスは、王の前に引き出された。「この短刀で何をするつもりであつたか。言へ ! 」暴君デイオニスは静かに、けれども威滅を以て問ひつめた。その王の顔は蒼白(さうはく)で、眉間(みけん)の鐘(しゎ)は、刻み込まれたやうに深かつた。「市を暴君の手から救ふみのだ。」とメロスは悪びれずに答へた。「おまへがか ? 」王は、翼笑(びんをせうぅう)した。 「仕方の無いやつぢや。おまへには、わしの孤狼がわからぬ。」「言ふな! 」とメロスは、いきり立つて反須(はんばく)した。「人の心を疑ふのは、最も恥づべき悪徳だ。ヨは、民の忠誠をさへ疑つて居られる。」「疑ふのが、正常の心構へなのだと、わしに教へてくれたのは、おまへたちだ。人の心は、あてにならなはい。 人間は、もともと私人徐のかたまりさ。信じては、ならぬ。」暴君は落着いて咳(つぶゃや)き、ほつと潤息をついた。「わしだつて、平和を望んでるるのだが。」「なんの久の平和だ。自分の地位を守る師か。」こんどはメロスが喘笑(てうせう)した。 「罪の無い人を殺して、何が平和だ。」「だまれ、下剛(げせん)の者。」王は、さつと顔を撃げて報いた。「品では、どんな清らかな事でも言へる。わしには、人の腹綿の奥底が見え透いてならぬ。おまへだつて、いまに、礎(はりっけ)になつてから、泣いて諸(わ)びたつて聞かぬぞ。」「ああ、王は便巧(りかうぅ)だ。自惚(うぬぼ)れてゐるがよい。 私は、ちやんと死ぬる算悟で居るのに。命婦(ぃのちご)ひなど決してしない。ただ、一一」 と言ひかけて、メロスは足もとに視線を落し瞬時ためらひ、「ただ、私に情をかけたいつもりなら、雇刑までに三日間の日限を異へて下さい。たつた一人の妹に、亭主を持たせてやりたいのです。三日のうちに、私は村で結婚式を軸げさせ、必ず、ここへ包つて來ます。 」「ばかな。」と暴君は、喝(しはが)れた英で低く笑つた。「とんでもない嘘(うそ)を言ふわい。 逃がした小/夕つて來るといふのか。 」「さうです。旋つて來るのです。」メロスは必死で言ひ張つた。「私は約束を守ります。私を、三日間だけ許して下さい。妹が、私の過りを待つてゐるのだ。そんなに私を信じられないならば、よろしい、この市にセリヌンテイウスといふ石工がゐます。私の無二の友人だ。あれを、人質としてここに置いて行かう。私が逃げてしまつて、三日目の日暮まで、ここに騙つて来なかつたら、あの友人を絞め殺して下さい。たのむ。さうして下さい。 」それを聞いて王は、残虐な気持で、そつと北明笑(ほくそる)んだ。生意気なことを言ふわい。どうせ訪つて挫ないにきまつてゐる。この嘘つきに騙(だま)された振りして、放してやるのも面白い。さうして身代りの男を、三日目に殺してやるのも無味がいい。 人は、これだから信じられぬと、わしは悲しい顔して、その身代りの男を秦刑(たくけぃ)に虎してやるのだ。世の中の、正直者とかいふ奴募(やっぱら)にうんと見せつけてやりたいものきさ。「願ひを、聞いた。その身代りを呼ぶがよい。三目日には日浸までに上包つて來い。おくれたら、その身代りを、きつと殺すぞ。ちょつとおくれて來るがいい。おまへの罪は、永遠にゆるしてやらうぞ。」「なに、何をおつしやる。」「はは。いのちが大事だつたら、おくれて來い。おまへの心は、わかつてゐるそぞ。 」メロスは口惜しく、地圏駄踏(なおだんだぉぁ)んだ。ものも言ひたくなくなつた。竹馬の友、セリヌンテイウスは、深夜、王城に召された。 暴君デイオニスの面前で、佳(ょ)き友と佳き友は、二年ぶりで相逢うた。メロスは、友に一切の事情を語つた。セリヌンテイウスは無言で首衣(うなづ)き、メロスをひしと抱きしめた。友と友の間は、それでよかつた。セリヌンテイウスは、細打たれた。メロスは、すぐに出獲した。 初夏、満天の星である。メロスはその夜、一睡もせず十里の路を急ぎに急いで、村へ到着したのは、翌(ぁく)る日の午前、陽は既に高く、昇つて、村人たちは野に出て仕事をはじめてゐた。メロスの十六の妹も、けふは見の代りに壮群の番をしてゐた。よろめいて歩いて來る兄の、疲替困付(ひらうこんばぱい)の姿を見つけて驚いた。さうして、うるさく見に質問を浴びせた。「なんでも無い。、」メロスは無理に括はうと努めた。 「市に用事を残して來た。またすでぐ市に行かなければならぬ。あす、おまへの結婚式を撃げる。早いはうがよからう。 」妹は類(ほほ)をあからめた。「うれしいか。 綺麗(きれぃ)な衣裳(いしゃう)も買つて來たを。さあ、これから行つて、村の人たちに知らせて來い。結婚式は、あすだと。」メロスは、また、よろよろと歩き出し、家へ由つて神々の祭壇を飾り、祝宴の席を調べへ、間もなく床に倒れ伏し、呼吸もせぬくらゐの深い眠りに落ちてしまつた。眼が算めたのは夜だつた。メロスは起きてすぐ、花婚の家を訪れた。さうして、少し事情があるから、結婚式を明日にしてくれ、と頼んだ。婚の牧人は息き、それはいけない、こちらには未だ何の仕度も出來てゐない、和攻略(ぶだうぅ)の季節まで待つてくれ、と答へた。メロスは、待つことは出來ぬ、どうか明日にしてくれが旬
差分
Python スクリプトが改行を削除しているため、 diff
は比較に適していないかもしれません。
代わりに、 Araxis Merge, WinMerge などの GUI diff ツールを使用することをお勧めします。
まとめ
特定のケースにおいては有用で、 Tesseract OCR の精度は時間とともに大幅に向上し続けると思います。 ただし、 PDF に図や表などの複雑なレイアウトが含まれている場合、精度が低下する可能性があります。