私は、私はこれらの線に沿って進むと思います...共有するためのいくつかのアイデアを持っている:
ステップ1 - 黒と白のしきい値
私は私はOpenCVのの大津のしきい値を使用すると思うがこの。
ステップ2から
垂直黒線を探すIは画像のすべての列の画素を平均化し、最小平均有するものを見つけ、それが中央まで垂直線であるべきであろう。出力以下のコード:
Centreline at column: 1635
ステップ3 - 2で分割画像とトリム過剰な空白
ステップ4 - ボックスは、フィルタリング
私はフィルタをボックスでしょう各段落の開始時にインデントと一致する55x45ボックスがあり、すべての段落の開始が黒でマークされるようにしますボックス。
私は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);
}
として扱い、より堅牢で、より効率的に作ることができる確信しています
は、念のためにあなたは、このコードをビルドするために手を必要とする - それは非自明なようだとしてコンパイルし、それに対して何かをリンクするために - 私はこのように私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})
@Miki:それから私は中「アウト・オブ・ソース」ビルドを行うために
build
と呼ばれるサブディレクトリを作成し、ビルドプロセスがあります* Not ** ImageMagick ;-) –うわー、ありがとう! :)私はまだOpenCVの基本を試していますが、これは行く方法と思われ、できるだけ早くテストします。私はまた、四角形の左上隅を座標として考えました。私は最後の部分は、実際の四角形にトリムする方法を見つけると分割線を設定するために使用する必要がありますね。 – MrVocabulary
これはVisual Studio/C++で行いましたか? – MrVocabulary