自炊した書籍の歪みを補正したい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
XE

自炊した書籍の歪みを補正したい

#1

投稿記事 by XE » 10年前

スキャナやカメラで撮影した書籍の画像の歪みを補正する良い方法はないでしょうか。

現在OpenCVで台形補正は行っているのですが、分厚い書籍の場合中央付近が大きく歪んでしまいます。
大量の画像を処理する必要があるため、OpenCVなどで歪み補正を行えればと思っています。

良い方法やヒントを是非ご教授お願いします。

アバター
usao
記事: 1887
登録日時: 11年前

Re: 自炊した書籍の歪みを補正したい

#2

投稿記事 by usao » 10年前

大量に処理するなら全て自動でやらないとダメということでしょうかね.

目的達成の道のりを

(1)とりあえず「人手で何かしらのオペレーションをしても良い」という条件下で
問題の歪を補正できる方法を考える
 ↓
(2)そのオペレーションに相当する部分を自動化する

という2段階にわけて考えた場合,
(1)と(2)のどちら側で困っている状況なのでしょうか.

kiuri
記事: 20
登録日時: 10年前

Re: 自炊した書籍の歪みを補正したい

#3

投稿記事 by kiuri » 10年前

文字列を曲線として抽出して、それを直線に直す。
次に文字の幅はほとんど等しいからそうなるように補正する。

という風にするのはどうでしょうか?

XE

Re: 自炊した書籍の歪みを補正したい

#4

投稿記事 by XE » 10年前

いろいろと技術書やネットを調べていますが、技術的にどうすれば歪みを補正することができるのかという答えを得ることができていません…。
自炊により電子書籍を作成している人は多いと思いますが、撮影時の歪みを補正しようという人は少ないのでしょうか。

どなたか具体的な方法をアドバイスして頂ければ嬉しいです。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: 自炊した書籍の歪みを補正したい

#5

投稿記事 by h2so5 » 10年前

XE さんが書きました:自炊により電子書籍を作成している人は多いと思いますが、撮影時の歪みを補正しようという人は少ないのでしょうか。
分厚い本を綺麗にスキャンする場合は、画像を補正するのではなくて断裁してスキャンしている人が多いのではないかと思います。
XE さんが書きました:いろいろと技術書やネットを調べていますが、技術的にどうすれば歪みを補正することができるのかという答えを得ることができていません…。
答えがないんだったら研究してみればいいと思います。

XE

Re: 自炊した書籍の歪みを補正したい

#6

投稿記事 by XE » 10年前

非破壊自炊が前提条件なので、裁断はできないのです。
企業の製品には歪み補正機能が搭載されているので、方法はあるようです。

とりあえず現時点ではラベリングを行い輪郭情報の取得はできているので、この情報をもとに長方形に変形させることができないかと悪戦苦闘しています…。

アバター
usao
記事: 1887
登録日時: 11年前

Re: 自炊した書籍の歪みを補正したい

#7

投稿記事 by usao » 10年前

例えば 紙の上に等間隔に点が格子状にならんでいるものをスキャンした場合,
理想的にはスキャン画像上でも等間隔の2次元格子的ならびになってほしいんだけど
実際は並びが歪むわけですよね.
このとき,個々の点の像について,
 現実の座標p → 理想の格子座標q
という対応づけをできたら 補正できますよね.
(要するに,点pでの補正量は (q-p) です.)
(点の無い個所での補正量は近傍の点の補正量から補間するとかして)

で,具体的な方法は
例えば No.3の方がおっしゃっているような方法が考えられますよね.

あと,No.2で私が2段階にわけて考えたらどうの,と言っているのですが,
(1)現実vs理想 の対応を例えばN点分人手で与えたら できるんですか?
という部分をまずクリアするのを目標にされてみてはいかがでしょうか.
その後,
ラベリングだとか輪郭情報だとかいうものを用いて
(2)自動化
をされれば良いと思います.

#ハンドスキャナ(?)みたいなのを使えば歪まずにスキャンできたりするのかな

XE

Re: 自炊した書籍の歪みを補正したい

#8

投稿記事 by XE » 10年前

アドバイスありがとうございます。
画像の補正に関して最終的には自動化を目標としていますが、
まず補正する方法を調べてもわからないため、何か具体的な方法を教えていただければと思い質問させていただいています。

(1)現実vs理想 の対応を例えばN点分人手で与えたら できるんですか?

という問いの、まず方法がわからないため、暗礁に乗り上げているような状況です。

現時点でわかったことは、OpenCVのcvRemap()を利用すれば可能なのかもしれないということだけです。
これも推測にしか過ぎないため、実際に可能かどうかは不明です。

そのため、cvRemap()をとりあえず動かしてみようと使い方やサンプルを探していますが、そもそも手持ちの参考書2種にはこの関数自体載っていないことや、
ネット上のサンプルも、cameraキャリブレーションぐらいしか見つからず、悪戦苦闘しています。
簡単なcvRemap()によるサンプルなどあれば是非教えてください。

また、そもそもこの考えが根本的に間違っているのなら、是非指摘していただきたいです。
よろしくおねがします。

アバター
usao
記事: 1887
登録日時: 11年前

Re: 自炊した書籍の歪みを補正したい

#9

投稿記事 by usao » 10年前

cvRemapを使うだけのサンプルがあるのかどうか知りませんが,
OpenCVのドキュメントを見れば使い方が自明な類の関数だと思いますよ.

最終的な補正処理=入力画像から出力画像を作る処理 に関してcvRemapを使うことは妥当だと思います.
画素値補間や領域外参照時処理等をこの関数に任せることで楽ができるでしょう.

しかし,それ以前に「どう補正するのか?」という処理内容はあなたが決めねばなりません.

ここで言う 補正 とは,入力画像から出力画像を作ることであり,より具体的に言えば,
「出力画像のすべての位置(x,y)に関して,画素値を入力画像の位置(x',y')からひっぱってくる」という処理です.
この (x,y) vs (x',y') の対応関係を出力画像上の全箇所で決めればいいわけですね.
(その結果がcvRemapに渡すテーブル内容になります)

私の一個前の書き込みで言えば, q=(x,y) であり,p=(x',y') です.
全てのqに関してpを決めればいいわけです.

で,その決め方が問題なわけですが……ここはあなたが頑張るしかありません.
ただ,結構難しいだろうな,とは思います.
オフトピック
本の真ん中みたいに,スキャン時に 浮き上がってる 場所って,スキャン画像ではどう写るのかな?
Perspective(カメラで撮った場合みたいな)じゃなくてOrthogonalな感じの絵になるのか??

たいちう
記事: 418
登録日時: 13年前

Re: 自炊した書籍の歪みを補正したい

#10

投稿記事 by たいちう » 10年前

> 企業の製品には歪み補正機能が搭載されているので、方法はあるようです。

http://scansnap.fujitsu.com/jp/product/ ... html#step2

このようなやつでしょうか?
使いこなせていないせいかもしれませんが、あまり満足できるレベルではないですね。
曲がったままよりは、幾分マシかもしれませんが、手間がかかる割にはきれいにならないです。
見開きで6点しか指定できないのはどうなのかと。もっとソフトウェアも頑張ってほしいものです。


巨大な図書館などでは本当に貴重な資料の電子化も進めているらしいので、
もっとかしこいソフトもあるとは思いますが、それを自作するのは相当大変だと思いますよ。

アバター
usao
記事: 1887
登録日時: 11年前

Re: 自炊した書籍の歪みを補正したい

#11

投稿記事 by usao » 10年前

たいちうさんが示されたリンク先の絵を見たところ,

スキャン画像中に本の上下輪郭が写っている.
しかも背景が黒で,紙が白なので超はっきりしてる.

こんな感じの絵であれば,少なくともY方向の補正はわりと簡単にできるんじゃないのコレ?とか思った.
本を閉じてる部分付近でのX方向の縮みの補正に関しても,その輪郭の傾斜量をヒントにできそうな予感.
オフトピック
全自動ではないにしろ,なんとなく「夢の中ではできた」感w
現実はそううまくはいかないのだろうけど.

ところで,この話って安易に
「スキャンした絵の例を示す」とかすると著作権的な問題が発生したりしそうですね.
そういった点でも 他人の助力を得にくい問題なのかもしれない.

XE

Re: 自炊した書籍の歪みを補正したい

#12

投稿記事 by XE » 10年前

とりあえず、ただカメラで撮影しただけの画像を、可能な限り見易くすることを目標にやっていこうと思います。
最初の目標は、自動台形補正処理をしたいと思っています。

何か思いつくアドバイスがあれば是非お願いします。
今の開発環境はPython + OpenCVで行っています。

たいちう
記事: 418
登録日時: 13年前

Re: 自炊した書籍の歪みを補正したい

#13

投稿記事 by たいちう » 10年前

No. 1
> 現在OpenCVで台形補正は行っているのですが、分厚い書籍の場合中央付近が大きく歪んでしまいます。

No. 12
> 最初の目標は、自動台形補正処理をしたいと思っています。

という2つの書き込みから、台形補正はできていて、それを自動でできるようにしたいということですか?
でも、↓の書き込みでは、輪郭も取得できている。輪郭を四角形に近似できない?

No. 6
> とりあえず現時点ではラベリングを行い輪郭情報の取得はできているので、
> この情報をもとに長方形に変形させることができないかと悪戦苦闘しています…。


どこまでできていて、何ができないのか。
現段階で躓いているという「自動台形補正処理」とは何を指しているのか。特に「自動」の部分。
cvRemapの使い方が判らないそうだが、今できている台形補正はどのように実装しているのか。

現状や問題点を整理してみませんか。
「自動」の定義によっては私だと殆どアドバイスはできませんんが、他の回答者は別でしょう。

XE

Re: 自炊した書籍の歪みを補正したい

#14

投稿記事 by XE » 10年前

このトピックを投稿した日からOpenCVやPythonの勉強を始めたので、自分の中でも整理がついていない部分があり申し訳ありません。

最初の投稿の中の台形補正を行っているということは、目視で(手作業で)求めた四角の座標を用いて台形補正を行っているという意味でした。
自動台形補正とは、四角の座標をプログラムで導き出して台形補正を自動的に掛けたいという意味です。

現在は書籍の輪郭をcvFindContours()により抽出し、その座標軍の中から適切な四角の座標をどうにか抽出しようとしているところです。
しかし書籍は大抵、輪郭が山なりになるため、単純に右上と左上の座標を結ぶ線では台形補正に利用することができず、
別の方法を考えているところです。

とりあえず現在は輪郭の座標群からどのように四角の座標だけを取り出すかということに苦労しています。

アバター
usao
記事: 1887
登録日時: 11年前

Re: 自炊した書籍の歪みを補正したい

#15

投稿記事 by usao » 10年前

スキャナではなくてカメラで撮影されているのですね.
(とりあえず台形が気にならない程度に真正面方向から撮影する という選択肢は無いのだろうか?)

画像の状況を知らないので,ちょっとずれたことを言っているかもしれませんが,
カメラ視点位置が本の上空(カメラ位置から 本表面を含む平面 に垂線を下ろしたときに,垂線と面との交点が本領域内にある)
な形で取れば…
撮影対象ページの4辺に関して,
(1)ページの上下エッジは,撮影対象ページの下に重なる他ページの影響を受けずに取れると思うのです.
(2)背表紙側のエッジはおそらく照明を調整できれば ほぼ直線として観測できる.
 あるいは陰ができて直接観測できないが,最も暗い場所 として推定はできる.
(3)残った開き側エッジは本によってはページが重なっている面が見えているかもしれないが,
 それでも最も外側の輪郭線を取ればいいんじゃないかな?

撮影環境をある程度自由にできるなら,背景に黒い紙を敷くなどして,本の輪郭を得やすくすれば,
(2),(3)はほぼ直線として写る.
(1)は背表紙側とかでそれなりに曲線になるだろうけど,それでもY方向の輝度1次微分程度で取得できそう.
…といった感じで
これらの線をわりと簡単に取れると思うのですが,実際の状況はそう簡単でもないのでしょうか.

XE

Re: 自炊した書籍の歪みを補正したい

#16

投稿記事 by XE » 10年前

cvRemap()渡す必要のあるMapについての理解ができていないため、ネットで公開されていたPythonのプログラムを少しお借りして調べてみました。

このような内側に枠のある5px * 5pxの画像を

コード:

[0][0][0][0][0]
[0][1][1][1][0]
[0][1][0][1][0]
[0][1][1][1][0]
[0][0][0][0][0]
このように枠が一番外側になるようにcvRemap()により変形させる場合

コード:

[1][1][1][1][1]
[1][0][0][0][1]
[1][0][0][0][1]
[1][0][0][0][1]
[1][1][1][1][1]
cvRemap()に渡す2つのMapは

コード:

[ 1.          1.50000012  2.00000024  2.5         3.        ]
[ 1.          1.50000012  2.00000024  2.50000024  3.        ]
[ 1.          1.50000012  2.00000024  2.50000024  3.        ]
[ 1.          1.50000012  2.00000024  2.5         3.        ]
[ 1.          1.50000012  2.00000024  2.5         3.        ]

[ 1.  1.  1.  1.  1.]
[ 1.50000012  1.50000012  1.50000012  1.50000012  1.50000012]
[ 2.00000024  2.00000024  2.00000024  2.00000024  2.00000024]
[ 2.5         2.50000024  2.50000024  2.5         2.5       ]
[ 3.  3.  3.  3.  3.]
となっていました。
正直どういう意味かよく分かっていません。

各ピクセル毎の移動前と移動後の座標かと思いましたが、そうでもないようです。
どなたかMapについて教えて頂けないでしょうか。

この値を出すのに使用したプログラムは下記の通りです。

コード:

import cv2
from scipy.interpolate import griddata
import numpy as np

grid_x, grid_y = np.mgrid[0:4:5j, 0:4:5j]

destination = np.array([[0,0], [0,4],[4,0],[4,4]])
source = np.array([[1,1],[1,3],[3,1],[3,3]])

grid_z = griddata(destination, source, (grid_x, grid_y), method='cubic')

map_x = np.append([], [ar[:,1] for ar in grid_z]).reshape(5,5)
map_y = np.append([], [ar[:,0] for ar in grid_z]).reshape(5,5)

map_x_32 = map_x.astype('float32')
map_y_32 = map_y.astype('float32')

print map_x_32
print map_y_32

アバター
usao
記事: 1887
登録日時: 11年前

Re: 自炊した書籍の歪みを補正したい

#17

投稿記事 by usao » 10年前

なぜリファレンスを見ないのでしょうか.
dst(x,y)<-src(mapx(x,y),mapy(x,y))
という感じでわかりやすく説明されているのですが.

XE

Re: 自炊した書籍の歪みを補正したい

#18

投稿記事 by XE » 10年前

コード:

[ 1.          1.50000012  2.00000024  2.5         3.        ]
[ 1.          1.50000012  2.00000024  2.50000024  3.        ]
[ 1.          1.50000012  2.00000024  2.50000024  3.        ]
[ 1.          1.50000012  2.00000024  2.5         3.        ]
[ 1.          1.50000012  2.00000024  2.5         3.        ]
このコードのどこがmapx(x,y)のxとyにあたるのか、理解できていません…。
たぶん根本的に理解を間違っていると思いますが、是非教えて頂ければ嬉しいです。

たいちう
記事: 418
登録日時: 13年前

Re: 自炊した書籍の歪みを補正したい

#19

投稿記事 by たいちう » 10年前

> このコードのどこがmapx(x,y)のxとyにあたるのか、理解できていません…。

先は長そうですね。

OpenCVは使ったことがないですが、リファレンスと現象からの推測ですが、
C++で書くと、こんな感じではないかと。

コード:

float src[5][5], dst[5][5];
float mapx[5][5], mapy[5][5];
// ...
for (int i = 0; i < 5; i++)
	for (int j = 0; j < 5; j++)
		dst[i][j] = src[mapx[i][j]][mapy[i][j]];

たいちう
記事: 418
登録日時: 13年前

Re: 自炊した書籍の歪みを補正したい

#20

投稿記事 by たいちう » 10年前

> 現在は書籍の輪郭をcvFindContours()により抽出し、
> その座標軍の中から適切な四角の座標をどうにか抽出しようとしているところです。

例えば、Y座標上向きの座標系で話をすると、x+yが最小の点を左下の頂点とみなすことができます。
後で改善するにしても、手始めとしては妥当ではないでしょうか。


No.10でも書きましたが、ハードウェアのおまけのソフトウェアという位置付けかもしれませんが、
市販の製品で手動で点を設定しても、私には十分満足のいくレベルの補正ではありません。
具体的には、文字列が波打ちます。

kiuriさんやusaoさんの書いているようなアイデアをどこまで実装しているかどうかは判りませんが、
それでもプロが仕事として作ったはずのソフトウェアです。
(プロにもピンからキリまでありますが、一応大企業の製品の付属ではある)

大人の事情で、補正の精度をわざと下げているかもしれないし、
素人が玄人の遥か上を行くことも珍しいことではないですが、
難易度は相当高いと思いますよ。

XE

Re: 自炊した書籍の歪みを補正したい

#21

投稿記事 by XE » 10年前

アドバイスありがとうございます。
とりあえずNo:12で述べたように、可能な限りましになるように努力してみようと考えています。
どのような形でも最終的に出来上がったものをパソコンで閲覧しなければならないので、今何が可能なのか考えていきたいと思います。

たいちうさんのC++のソースを当てはめてみると以下の結果が出力されました。
1ピクセル毎の座標を指定している…という認識ができました。
cvReamp()について少し理解できた気がします。ありがとうございます。

コード:

src = [[0],[0],[0],[0],[0]], \
      [[0],[1],[1],[1],[0]], \
      [[0],[1],[0],[1],[0]], \
      [[0],[1],[1],[1],[0]], \
      [[0],[0],[0],[0],[0]]

dest =[[1],[1],[1],[1],[1]], \
      [[1],[0],[0],[0],[1]], \
      [[1],[0],[0],[0],[1]], \
      [[1],[0],[0],[0],[1]], \
      [[1],[1],[1],[1],[1]]

mapx =[[1],[1.5],[2],[2.5],[3]], \
      [[1],[1.5],[2],[2.5],[3]], \
      [[1],[1.5],[2],[2.5],[3]], \
      [[1],[1.5],[2],[2.5],[3]], \
      [[1],[1.5],[2],[2.5],[3]]

mapy =[[1],[1],[1],[1],[1]], \
      [[1.5],[1.5],[1.5],[1.5],[1.5]], \
      [[2],[2],[2],[2],[2]], \
      [[2.5],[2.5],[2.5],[2.5],[2.5]], \
      [[3],[3],[3],[3],[3]]

for i in xrange(5):
    print '\n'
    for j in xrange(5):
        print '%s = src[%s,%s]' % (dest[i][j],mapx[i][j],mapy[i][j])

コード:

[1] = src[[1],[1]]
[1] = src[[1.5],[1]]
[1] = src[[2],[1]]
[1] = src[[2.5],[1]]
[1] = src[[3],[1]]


[1] = src[[1],[1.5]]
[0] = src[[1.5],[1.5]]
[0] = src[[2],[1.5]]
[0] = src[[2.5],[1.5]]
[1] = src[[3],[1.5]]


[1] = src[[1],[2]]
[0] = src[[1.5],[2]]
[0] = src[[2],[2]]
[0] = src[[2.5],[2]]
[1] = src[[3],[2]]


[1] = src[[1],[2.5]]
[0] = src[[1.5],[2.5]]
[0] = src[[2],[2.5]]
[0] = src[[2.5],[2.5]]
[1] = src[[3],[2.5]]


[1] = src[[1],[3]]
[1] = src[[1.5],[3]]
[1] = src[[2],[3]]
[1] = src[[2.5],[3]]
[1] = src[[3],[3]]

たいちう
記事: 418
登録日時: 13年前

Re: 自炊した書籍の歪みを補正したい

#22

投稿記事 by たいちう » 10年前

> たいちうさんのC++のソースを当てはめてみると以下の結果が出力されました。
> 1ピクセル毎の座標を指定している…という認識ができました。
> cvReamp()について少し理解できた気がします。ありがとうございます。

まあ、No.17でusaoさんの書いている内容と同じなんですけどね。

むしろ、配列の添え字は整数値なので、
src[1.5][1] が、(src[1][1] + src[2][1]) / 2
のような意味であることを無視している分、不正確ですので、
注意してください。

XE

Re: 自炊した書籍の歪みを補正したい

#23

投稿記事 by XE » 10年前

お世話になっています。
2点の座標A,Bを結ぶ直線を、A点を基準に任意の角度で回転させた際の回転後の座標A,Bの求め方か、
OpenCVで歪んだ四角形を、その4点の座標から別の画像にコピーする方法があれば、どなたか教えて頂けないでしょうか。

短形の切り出しでは歪んだ画像に対応できないため、他の方法を探しています。

たいちう
記事: 418
登録日時: 13年前

Re: 自炊した書籍の歪みを補正したい

#24

投稿記事 by たいちう » 10年前

> 2点の座標A,Bを結ぶ直線を、A点を基準に任意の角度で回転させた際の回転後の座標A,Bの求め方か、
> OpenCVで歪んだ四角形を、その4点の座標から別の画像にコピーする方法があれば、どなたか教えて頂けないでしょうか。

後者は知りません。前者は質問の意味が判りません。
A点を基準に回転とはどういう意味ですか?
A点が中心ならばA点は変化しないはずだし、原点が中心なら基準の意味が不明だし。

この質問の仕方だけ見ると、XEさんが三角関数を使いこなせないと判断せざるをえないのですが、大丈夫ですか?
XEさんがやりたいことは、ずっと高度な事ですよ?

アバター
usao
記事: 1887
登録日時: 11年前

Re: 自炊した書籍の歪みを補正したい

#25

投稿記事 by usao » 10年前

あなたがどのような歪をどう扱おうとしているかわからないので何とも言えませんが,
簡単なものであればアフィン変換か射影変換で対応できないか検討されると良いかもしれません.
OpenCVの関数名が知りたい場合は 変換名とOpenCV くらいで検索すれば見つかるでしょう.

OpenCVは単なるライブラリであって万能ではありませんから
どういう機能が提供されているのかをざっと把握するためにも
一度リファレンスを眺めてみることを強く推奨します.
そこに在る以上のことをしたい場合には,自分でやるしかありません.
(あったとしても使いにくい場合も多いですし)
やるべき変換処理の内容が決まっているのであれば,それを行える関数などを探すよりも
自前でLUTを作ってcvRemap()で変換したほうが手っ取り早いかもしれません.

座標の回転については掲示板で説明するより「回転行列」とかで検索していただいた方が早いです.

閉鎖

“C言語何でも質問掲示板” へ戻る