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

xatque 发布于 2019-03-09 opencv 最后更新 2019-03-09 14:41 3 浏览

我有一个非白色区域的图像(例如段落,但不涉及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.
我打算做的是挖掘这些地区。 我想到的另一种方法是使用直方图来确定最低点,并以某种方式找到最低点的位置。
已邀请:

noptio

赞同来自:

我不确定这是不是你要找的东西(我不确定你在找什么),所以如果我错了请写更多细节,我会尽力更新我的答案。现在我认为你正在寻找最适合拆分纸张的白色区域,因为你没有削减任何重要的东西。 最容易实现的解决方案是计算每行和下一行的总和,并检查这些值的差异是否为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+1行的最后一个元素中减去i行的最后一个元素。当然,积分图像在openCV - see here中实现