2013-04-11 11 views
9

私は白ではない領域を持つ画像を持っています(例えば、段落はOCRを扱っていません)。これらの領域の間のスペースはやや規則的で、画像を見る人はこれらの領域の間に空白があることを見ることができます。コンピュータビジョン:最小のエントロピーでイメージを水平に分割する方法は?

すべての領域の上端と下端を見つけ、下端から次の領域の上端まで検索し、各水平線のエントロピーを取り、最も低い値の線を取り、その線を返しますY位置。私はするつもり何 enter image description here

[region] <--- maximum corner coordinates identified 
[line with lowest entropy] <--- return Y position starting from above region's bottom corner's Y coordinate. 
[region]<--- stop at Y coordinate of this region's top corner. 

これらの領域のうち作物です。

私が考えた別のアプローチは、ヒストグラムを使って最低点を特定し、その最低点の位置を何とか見つけることでした。

+0

サンプル画像を表示することができれば、あなたのお役に立てるようになります。 –

+0

楽譜はこれの完璧な例になります – KJW

+0

私は例を見つけました – KJW

答えて

4

あなたが探しているものがわからない(私はあなたが探しているものが分からない)ので、私が間違っている場合は、詳細を書いてください。私は私の答えを更新しようとします。今、私はあなたが何か重要なものを切っていないので、あなたは紙を分割するのに最適な白い領域を探していると思います。

ソリューションを実装するのが最も簡単なのは、各行と次の行の合計を計算し、それらの値の差が0(またはその他の小さな値)であるかどうかを確認することです。ここでは簡単なコードは次のとおりです。

Mat m = imread(pathToFile); 
cvtColor(m, m, CV_BGR2GRAY); //just to make sure 
for (int i = 0; i < m.rows - 1; i++) 
{ 
    Scalar s = sum(Mat(m, Rect(0, i, m.cols - 1, 1))); 
    Scalar s2 = sum(Mat(m, Rect(0, i + 1, m.cols - 1, 1))); 
    Scalar s3 = s - s2; 
    if ((int)s3[0] == 0) 
     printf("Empty line: %d\n", i); 
} 

実際には - あなたはまた、このラインが白であるかどうかを確認する必要がありますまたは多分あなただけの2非常によく似た非白線を発見した - これだけif ((int)s[0] < someValue) {//it's ok} else {//it's bad}のように、このコードにいくつかのテストを追加します。 もちろん、それは非常に効率的な解決法ではありません。なぜなら、(それぞれの)各行の合計を2回計算する必要があり、それは時間の無駄です。より速い解決策は、変数の行の総和を覚えることです。あるいは、後でそれらを使いたい場合は、ベクトル/配列/ etcにすべての合計を入れることもできます。画像全体の和を計算し、i+1行の最後の要素からi行のsubstract最後の要素よりも - これはおそらくintegral imagesを使用して計算する

最も効率的な方法。もちろん、積分画像はopenCVで実装されています - see here

関連する問題