C++ 如何修复腐蚀的矩形?
基本上,我有一个这样的形象 或在同一图像中具有多个矩形的图像。矩形是完全黑色和白色的,有“脏”边和凿痕,但很容易辨别它们是矩形。更准确地说,它们是图像遮罩。白色区域是图像中“不受影响”的部分,而黑色部分是双色的 我的问题是,如何用这个退化的矩形制作出一个漂亮而清晰的矩形?我是一个Python人,但是我必须使用Qt和C++来完成这个任务。最好不要使用其他库C++ 如何修复腐蚀的矩形?,c++,qt,image-processing,qt4,masking,C++,Qt,Image Processing,Qt4,Masking,基本上,我有一个这样的形象 或在同一图像中具有多个矩形的图像。矩形是完全黑色和白色的,有“脏”边和凿痕,但很容易辨别它们是矩形。更准确地说,它们是图像遮罩。白色区域是图像中“不受影响”的部分,而黑色部分是双色的 我的问题是,如何用这个退化的矩形制作出一个漂亮而清晰的矩形?我是一个Python人,但是我必须使用Qt和C++来完成这个任务。最好不要使用其他库 谢谢 通常你会通过反复扩张和腐蚀面具来达到这个目的。我认为qt没有为此而预先制作的函数,因此如果您不想使用库,您可能必须自己实现它们-有关于
谢谢 通常你会通过反复扩张和腐蚀面具来达到这个目的。我认为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
}
}
如果结果的大小为负数,则图像中没有非遮罩像素。代码可以更优化,但我还没有喝足够的咖啡。:)矩形是否总是与外部矩形对齐,或者你可能有(例如)一个正方形旋转45度,给出菱形的形状(即使它仍然有正方形的角和直角)?尽管没有C++,一些答案可能与这个问题非常相关。我的目标是单独找到所有形状的边界框(它们大多是矩形和椭圆形,但偶尔会有随机形状),以最大限度地减少图像腐蚀。@Jerry Coffin,它们都是大的、白色的不相交矩形,几乎没有旋转。@Blender关于你最后的评论,不同的几何体需要不同的算法。椭圆形(椭圆)的检测算法与矩形的检测算法不同,至少不是最佳算法。因此,如果您对其他几何图形有要求,我建议您更新此问题!矩形是否始终与外部矩形对齐,或者(例如)您是否可以将一个正方形旋转45度,形成菱形形状(即使它仍然具有方形角和直边)?尽管不是targetti