计算机视觉:如何通过最少熵的线水平分割图像?

时间:2013-04-11 16:42:02

标签: opencv simplecv

我有一个非白色区域的图像(例如段落但不处理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.

我打算做的是裁剪这些区域。

我想到的另一种方法是使用直方图来识别最低点并以某种方式找到最低点的位置。

1 个答案:

答案 0 :(得分: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}。 当然,这不是一个非常有效的解决方案,因为你必须两次计算每个(几乎每一行)的总和,这是浪费时间。更快的解决方案是记住变量中行的总和,或者如果你想稍后使用它们,甚至可以将所有总和放在vector / array / etc中。

最有效的计算方法可能是使用integral images - 计算整个图像的总和,然后从i行的最后一个元素中减去i+1行的最后一个元素。当然,整体图像是在openCV中实现的 - see here