C++ 如何修复腐蚀的矩形?

C++ 如何修复腐蚀的矩形?,c++,qt,image-processing,qt4,masking,C++,Qt,Image Processing,Qt4,Masking,基本上,我有一个这样的形象 或在同一图像中具有多个矩形的图像。矩形是完全黑色和白色的,有“脏”边和凿痕,但很容易辨别它们是矩形。更准确地说,它们是图像遮罩。白色区域是图像中“不受影响”的部分,而黑色部分是双色的 我的问题是,如何用这个退化的矩形制作出一个漂亮而清晰的矩形?我是一个Python人,但是我必须使用Qt和C++来完成这个任务。最好不要使用其他库 谢谢 通常你会通过反复扩张和腐蚀面具来达到这个目的。我认为qt没有为此而预先制作的函数,因此如果您不想使用库,您可能必须自己实现它们-有关于

基本上,我有一个这样的形象

或在同一图像中具有多个矩形的图像。矩形是完全黑色和白色的,有“脏”边和凿痕,但很容易辨别它们是矩形。更准确地说,它们是图像遮罩。白色区域是图像中“不受影响”的部分,而黑色部分是双色的

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


谢谢

通常你会通过反复扩张和腐蚀面具来达到这个目的。我认为qt没有为此而预先制作的函数,因此如果您不想使用库,您可能必须自己实现它们-有关于如何实现函数的信息。

通常您会通过反复扩展和腐蚀遮罩来实现。我认为qt没有为此预先制作的函数,所以如果你不想使用库,你可能必须自己实现它们-有关于如何实现这些函数的信息。

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


相反,如果您看到许多频率几乎相等的距离,则矩形可能会旋转(或至少有一条边旋转)。在这种情况下,您可以将边一分为二(例如)并重复。一旦你到达了每个区域中的大多数点,在距离上达成一致,你就可以(尝试)在它们之间进行线性插值,以得到一条直线(并且限制最小区域大小将限制最大旋转——如果你在没有达成一致的情况下达到某个大小,你看到的是凿槽,而不是矩形边)。类似地,如果你有一个区域(或多个区域)与其他区域不完全匹配,并且与直线不匹配,你可能也应该忽略它——同样,你可能看到的是一个凿槽,而不是一条边。

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


相反,如果您看到许多频率几乎相等的距离,则矩形可能会旋转(或至少有一条边旋转)。在这种情况下,您可以将边一分为二(例如)并重复。一旦你到达了每个区域中的大多数点,在距离上达成一致,你就可以(尝试)在它们之间进行线性插值,以得到一条直线(并且限制最小区域大小将限制最大旋转——如果你在没有达成一致的情况下达到某个大小,你看到的是凿槽,而不是矩形边)。同样,如果您有一个区域(或多个区域)与其他区域不完全匹配,并且与直线不匹配,那么您可能也应该忽略它——同样,您可能看到的是一个凿槽,而不是作为边缘的凿槽。

如果包含所有非黑色像素的边界框可以执行您想要的操作,那么应该执行以下操作:

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
    }
}
int boundLeft=int_MAX;
int boundRight=-1;
int boundTop=int_MAX;
int boundBottom=-1;
对于(int y=0;y boundBottom)boundBottom=y
}
}

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

如果包含所有非黑色像素的边界框可以执行您想要的操作,则应执行以下操作:

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
    }
}
int boundLeft=int_MAX;
int boundRight=-1;
int boundTop=int_MAX;
int boundBottom=-1;
对于(int y=0;y boundBottom)boundBottom=y
}
}

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