帝國圖書館 AppStoreで公開 & 境界認識アルゴリズム

1月ごろから作り始めて、1ヶ月以上前に完成していたものの、公開するか迷っていたアプリ「帝國圖書館」ですが無事ダウンロードできるようになりました。使い慣れた?Objective-CではなくSwiftで100%書いてみました(そもそも練習のために作ったようなアプリです)。Swiftは使いやすい面が多々ありますが、Swift ver1.1から1.2への移行でも色々と変更がありまだ言語仕様が安定していません。NSString と String, NSArray と Array型などの互換性があるのかないのか微妙です。それでも、次のアプリもできればSwiftで開発してみたいと思います。SAARTのようにCoreAudioをガンガン使っている場合は、そこだけObj-Cにしなければいけなさそうですが。


さて、帝国図書館では狭いiPhoneの画面をなるべく有効活用するように、本の余白を認識してなるべく本文のみを表示するようにしてみました。いわゆる画像認識の領域ですが、まじめに組もうと思ったらものすごく大変なところです。アプリの性質上、サクサク動くことが条件なので「ほぼ瞬時に」計算できることが必要条件です。

また、認識する境界について、図の赤枠が本来の「本」の境界ですが、画面を有効利用するために本文の周囲の枠(図の青枠)を認識することを目指しました。

名称未設定 2

1)まず、画像全体を縮小します。文字の一画一画などを認識するのではなく、行単位でおおまかに見れれば良いので、とりあえず64×64に縮小することにしました。ビットマップ縮小のAPIを使ったので、おそらくいろんな最適化がなされていると思いますしほとんど時間はかかりません。ついでにここで白黒にしておきます。

名称未設定 5

2)境界を認識するために隣り合ったピクセルの明るさの差をとります。横方向で認識する際には、本文は画面の上1/3, 下1/3にはないことが多いので真ん中2分の1だけを取って、縦の差分は全部加算しておきます。縦方向の境界認識でも同様の操作をしています。ページの真ん中の線など白と黒のコントラストが強いところに引っ張られすぎないように、閾値以上のものは一定の値にしておきます。

3)単純にピクセルの明るさの差が大きいところを境界と認識すると、ページの真ん中の線などに強く影響されていまいます。また、本文が1,2行しかなく残りが余白になっているようなページでおかしくなることがあります。一方で、ページのレイアウトは大体の本で大きな変わりはなく、どのへんに余白が来るかなどはある程度固定しています。そこで、「このへんに本文の境界がありそうだ」という元々の知識(=ベイズ統計学でいう事前情報)を確率関数化して、先ほどのピクセルの明るさの差に掛けあわせます。確率関数は本文の上下左右にそれぞれ1つずつの4つ用意します。こうすると、認識結果が多少外れたとしても大ハズレにはならない?

4)確率関数を掛けあわせた明暗の変化が最も大きい点が境界として選ばれます。

プログラム上ではおおよそ100行程度ですんでいます。縦、横ともにだいたい同様の計算をして境界を見つけていますが、レイアウトの特殊な本などではうまくいかないと思います。確率関数も、ある程度チューニングしましたが最適とはとても言えないと思います。もし認識に大きな不具合があるようでしたら、ここのコメントでも良いのでお知らせください。なるべく対処します。

広告