2017-02-11 6 views
2

私はこのテーマについていくつかの研究を行ってきましたが、私の質問はこれまでに聞いたこととは大きく異なっていると思います。画像からテキストのブロック(段落)を検出してトリミングする簡単な方法はありますか?

私の博士論文は、古い辞書をOCR処理し、結果を自動的にXMLのようなデータベースに変換します。私はこの部分を理解しました。しかし、私は、各エントリ/見出しに使用されるスキャンの断片を表示することによって、最終結果を豊かにしたいと思います。辞書の長さが9000ページになるので、手動で行うのは問題になりません。

これはランダムなページがどのように見えるかです:http://i.imgur.com/X2mPZr0.png

を各エントリは、常に1つのパラグラフに等しいように、私は次のように、別々のファイルとして(何のOCRは必要ありません)テキストを長方形にすべての画像を分割する方法を見つけるしたいと思いますこれは(矩形を描いていない): http://i.imgur.com/CWtQD6Q.png

良いことは、私が持っているスキャンの形状とサイズが同じで、マージン/テキストの配置が同じであることです。すべてのパラグラフには常に同一性があります。

悪い点は、私はほとんど言語学者であり、プログラマーの多くではないということです。私の経験のほとんどは、Ruby、XML、およびCSSです。そして、いくつかのパラグラフは1行だけです。

が、彼らはかなりの時間のために必要とされています。私はいくつかの方法を認識してい

は、同じようなことをやります私は学ぶ(特に、私はPythoで0の知識を持っているn)、テキストの検出だけでなく段落の検出も許可しているかどうかわかりません。

この件に関するご意見は、特に初心者には親切です。

答えて

2

私は、私はこれらの線に沿って進むと思います...共有するためのいくつかのアイデアを持っている:

ステップ1 - 黒と白のしきい値

私は私はOpenCVのの大津のしきい値を使用すると思うがこの。

ステップ2から

垂直黒線を探すIは画像のすべての列の画素を平均化し、最小平均有するものを見つけ、それが中央まで垂直線であるべきであろう。出力以下のコード:

Centreline at column: 1635 

ステップ3 - 2で分割画像とトリム過剰な空白

enter image description hereenter image description here

ステップ4 - ボックスは、フィルタリング

私はフィルタをボックスでしょう各段落の開始時にインデントと一致する55x45ボックスがあり、すべての段落の開始が黒でマークされるようにしますボックス。

enter image description here

私はOpenCVのにはかなり新しいですが、以下のようなアイデアをコード化している - 私はそれの多くはそう概念;-)

#include <iostream> 
#include <opencv2/opencv.hpp> 

using namespace cv; 
using namespace std; 

int 
main(int argc,char*argv[]) 
{ 
    // Load image 
    Mat orig=imread("page.png",IMREAD_COLOR); 

    vector<int> PNGwriteOptions; 
    PNGwriteOptions.push_back(CV_IMWRITE_PNG_COMPRESSION); 
    PNGwriteOptions.push_back(9); 

    // Get greyscale and Otsu-thresholded version 
    Mat bw,grey; 
    cvtColor(orig,grey,CV_RGB2GRAY); 
    threshold(grey,bw,0,255,CV_THRESH_BINARY|CV_THRESH_OTSU); 

    // Find vertical centreline by looking for lowest column average - i.e. darkest vertical bar 
    Mat colsums; 
    reduce(bw,colsums,0,CV_REDUCE_AVG); 
    double min,max; 
    Point min_loc, max_loc; 
    minMaxLoc(colsums,&min,&max,&min_loc,&max_loc); 
    cout << "Centreline at column: " << min_loc.x << endl; 

    namedWindow("test",CV_WINDOW_AUTOSIZE); 

    // Split image into left and right 
    Rect leftROI(0,0,min_loc.x,bw.rows); 
    Mat leftbw=bw(leftROI); 
    Rect rightROI(min_loc.x+8,0,bw.cols-min_loc.x-8,bw.rows); 
    Mat rightbw=bw(rightROI); 
    imshow("test",leftbw); 
    waitKey(0); 
    imshow("test",rightbw); 
    waitKey(0); 

    // Trim surrounding whitespace off 
    Mat Points; 
    Mat inverted = cv::Scalar::all(255) - leftbw; 
    findNonZero(inverted,Points); 
    Rect bRect=boundingRect(Points); 
    Mat lefttrimmed=leftbw(bRect); 

    inverted = cv::Scalar::all(255) - rightbw; 
    findNonZero(inverted,Points); 
    bRect=boundingRect(Points); 
    Mat righttrimmed=rightbw(bRect); 

    imwrite("lefttrimmed.png",lefttrimmed,PNGwriteOptions); 
    imwrite("righttrimmed.png",righttrimmed,PNGwriteOptions); 

    // Box filter with 55x45 rectangle to match size of paragraph indent on left 
    Mat lBoxFilt,rBoxFilt; 
    boxFilter(lefttrimmed,lBoxFilt,-1,Size(55,45)); 
    normalize(lBoxFilt,lBoxFilt,0,255,NORM_MINMAX,CV_8UC1); 
    threshold(lBoxFilt,lBoxFilt,254,255,THRESH_BINARY_INV); 
    imwrite("leftBoxed.png",lBoxFilt,PNGwriteOptions); 

} 
として扱い、より堅牢で、より効率的に作ることができる確信しています

enter image description here

は、念のためにあなたは、このコードをビルドするために手を必要とする - それは非自明なようだとしてコンパイルし、それに対して何かをリンクするために - 私はこのように私CMakeLists.txtファイルを作り、同じDでそれを保存しますソースファイルとしてディレクトリを作成します。 *

cd build 
cmake .. 
make -j 8 
./demo 

CMakeLists.txt

cmake_minimum_required(VERSION 2.8) 
project(demo) 
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 
find_package(OpenCV) 
add_executable(demo main.cpp) 
target_link_libraries(demo ${OpenCV_LIBS}) 
+0

@Miki:それから私は中「アウト・オブ・ソース」ビルドを行うためにbuildと呼ばれるサブディレクトリを作成し、ビルドプロセスがあります* Not ** ImageMagick ;-) –

+0

うわー、ありがとう! :)私はまだOpenCVの基本を試していますが、これは行く方法と思われ、できるだけ早くテストします。私はまた、四角形の左上隅を座標として考えました。私は最後の部分は、実際の四角形にトリムする方法を見つけると分割線を設定するために使用する必要がありますね。 – MrVocabulary

+0

これはVisual Studio/C++で行いましたか? – MrVocabulary

関連する問題