0

基本上,我有这样的图像 在此处输入图像描述

或者在同一图像中有多个矩形。矩形是完全黑色和白色的,有“脏”的边缘和凹槽,但很容易判断它们是矩形。更准确地说,它们是图像掩码。白色区域是图像的“单独”部分,但黑色部分是双色调的。

我的问题是,我如何从这个退化的矩形中制作一个漂亮而清晰的矩形?我是一个 Python 人,但我必须使用 Qt 和 C++ 来完成这项任务。最好不使用其他库。

谢谢!

4

3 回答 3

1

通常你会通过反复扩张和侵蚀面具来做到这一点。我认为 qt 没有为此提供预制功能,因此如果您不想使用库,您可能必须自己实现它们 - http://ostermiller.org/dilate_and_erode.html提供了有关如何实现这些功能的信息。

于 2011-01-30T04:16:30.463 回答
1

目前,我们假设它们都应该是没有旋转的矩形。在这种情况下,您应该能够使用一种非常简单的方法。从位图边缘的每个像素开始,开始向内采样像素,直到遇到过渡。记录每个过渡到边缘的距离(如果有的话)。一旦你从每条边完成了这项工作,你基本上就“投票”了——从那个边最常发生的距离就是你认为矩形的那个边。如果矩形真的是对齐的,那应该构成大部分距离。

相反,如果您看到许多距离几乎相等的频率,则可能是矩形旋转(或至少一个边缘)。在这种情况下,您可以将一侧分成两半(例如)并重复。一旦您在每个区域中达到了大部分同意距离的点,您可以(尝试)在它们之间进行线性插值以给出一条直线(并且限制最小区域大小将限制最大旋转 - 如果您得到在没有达成一致的情况下达到某种尺寸,你看到的是凿子,而不是矩形边缘)。同样,如果您有一个区域(或多个区域)与其他区域不完全吻合,也不适合一条线,您可能也应该忽略它——同样,您可能正在查看凿孔,而不是预期的边缘。

于 2011-01-30T04:33:27.467 回答
1

如果包含所有非黑色像素的边界框可以做你想做的事,这应该可以解决问题:

int boundLeft = INT_MAX;
int boundRight = -1;
int boundTop = INT_MAX;
int boundBottom = -1;
for(int y=0;y<imageHeight;++y) {
    bool hasNonMask = false;
    for(int x=0;x<imageWidth;++x) {
        if(isNotMask(x, y)) {
            hasNonMask = true;
            if(x < boundLeft) boundLeft = x;
            if(x > boundRight) boundRight = x;
        }
    }
    if(hasNonMask) {
        if(y < boundTop) boundTop = y;
        if(y > boundBottom) boundBottom = y
    }
}

如果结果大小为负,则图像中没有非掩码像素。代码可以更优化,但我还没有喝足够的咖啡。:)

于 2011-01-30T16:13:59.757 回答