Summary
- RustでOpenCVが使える!
- OpenCVのHough変換を使うことによって,表を構成する直線をある程度検出できる
- とはいえ,検出結果にはかなりノイズがのっている
GiHub -> https://github.com/akitenkrad/rsrpp
crates.io -> https://crates.io/crates/rsrpp
ToDo
-
pdftotextで論文から単語単位のテキストと位置情報を取得する (
Word
,Line
,Block
,Page
) -
テキストの属性 (本文, タイトル, 脚注, etc.) を判定する
-
テキストが含まれるエリアを抽出する
- 2段組みを扱えるようにする
- セクションのタイトルを識別する
-
テキストが含まれるエリアを抽出する
-
図表に含まれるテキストを除外する
-
表を除外する
- PDFを画像に変換
- 画像処理で表の位置を特定
-
表を除外する
今日のファイル
rsrpp
├── Cargo.toml
├── rsrpp
│ ├── Cargo.toml
│ └── src
│ ├── lib.rs
│ └── parser
│ ├── mod.rs <-- today
│ ├── structs.rs <-- today
│ └── tests.rs
└── rsrpp-cli
├── Cargo.toml
└── src
└── main.rs
前回までのあらすじ
表を検出するにあたって,PDFの画像に対してHough変換を適用することで表領域の検出を試みることにしました.
まずはHough変換を使い倒すところから.
OpenCVの導入
Rustによる画像処理のためにOpenCVを使います.
クレートの追加だけではなく,事前にOpenCV本体のインストールが必要です.
> sudo apt install libopencv-dev clang libclang-dev
> cargo add opencv
詳しい説明はできませんが,OpenCVは画像処理を行うためのライブラリの代表格の一つです.
様々な言語でラップされていて,Pythonでも使えます.
Rustでも使えるようになっているとは1.
Rustはコアライブラリが薄い言語なのですが,最近は周辺が充実してきて楽しくなってきてますね.
OpenCVによるHough変換の手順は以下の通りです.
// read the image
let _src = imgcodecs::imread(image_path, imgcodecs::IMREAD_COLOR).unwrap();
let mut src = Mat::zeros(width, height, _src.typ()).unwrap().to_mat().unwrap();
let dst_size = opencv::core::Size::new(width, height);
// reshape
imgproc::resize(&_src, &mut src, dst_size, 0.0, 0.0, imgproc::INTER_LINEAR).unwrap();
// convert the image to grayscale
let mut src_gray = Mat::default();
imgproc::cvt_color_def(&src, &mut src_gray, imgproc::COLOR_BGR2GRAY).unwrap();
// apply Canny edge detector
let mut edges = Mat::default();
imgproc::canny_def(&src_gray, &mut edges, 50.0, 200.0).unwrap();
// apply Hough Line Transform
let min_line_length = src.size().unwrap().width as f64 / 10.0;
let mut s_lines = Vector::<Vec4f>::new();
imgproc::hough_lines_p(
&edges,
&mut s_lines,
2.,
PI / 180.,
100,
min_line_length,
3.,
)
.unwrap();
上記はそれぞれのパラメータを調整した後のものになりますが,正直この辺りは手探りだったので,何か上手い調整方法があれば追々アップデートをかけたいところです.
この設定でHough変換を実行した結果がこちら.
検出した直線を緑色のラインで表示しています.
ターゲットの表に関しては,一番外側のラインは取れていますが,中のラインに関しては短いものを落としていたりします.
また,表でない箇所を直線として誤検知箇所がたくさんあります.
パラメータを変えることによって,特定の画像に対してはある程度最適化が可能なのですが,論文のPDFはどんな品質で上がってくるか未知数なので,Hough変換の最適化を極めるよりは,ノイズが乗った図のようなアウトプットからいかにして表領域を抽出するか,という方向に注力した方が生産的かなと判断しました.
これくらいのノイズに収めるためにめちゃくちゃ試行錯誤したのでその辺りもぜひ記事にしたいところなのですが,全く面白みがないので泣く泣くカットすることにしました.
話がさらに脱線しますが,Rustで画像を扱えることがわかったので,やれることの幅が大きく広がりました.
どうしてもテキストだけで解決できない課題は思い切って画像処理を挟んでみると意外とうまくハマることがあるようなないような.
次回
Hough変換である程度表を構成する直線を検出できることがわかったので,次は検出結果をもとにして表領域を確定させに行きます.