回答
是有一种方法,但它是一个有点乱作为其基于cvFloodFill操作。现在所有这些算法都是用一种颜色填充一个区域,直到达到类似于区域增长算法的边缘。为了有效地使用它,你需要使用一些创新的编码,但是我警告你这个代码只是为了让你开始,它可能需要重新分解以加快速度。因为它的循环遍历每个像素小于255应用cvFloodFill检查区域是什么大小,然后如果它在某个区域下面填充它。
重要的是要注意的副本当使用指针时,图像由提供给cvFloodFill操作的原始图像组成。如果提供了直接图像,则最终会出现白色图像。
OpenFileDialog OpenFile = new OpenFileDialog();
if (OpenFileDialog.ShowDialog() == DialogResult.OK)
{
Image<Bgr, byte> image = new Image<Bgr, byte>(OpenFile.FileName);
for (int i = 0; i < image.Width; i++)
{
for (int j = 0; j < image.Height; j++)
{
if (image.Data[j, i, 0] != 255)
{
Image<Bgr, byte> image_copy = image.Copy();
Image<Gray, byte> mask = new Image<Gray, byte>(image.Width + 2, image.Height + 2);
MCvConnectedComp comp = new MCvConnectedComp();
Point point1 = new Point(i, j);
//CvInvoke.cvFloodFill(
CvInvoke.cvFloodFill(image_copy.Ptr, point1, new MCvScalar(255, 255, 255, 255),
new MCvScalar(0, 0, 0),
new MCvScalar(0, 0, 0), out comp,
Emgu.CV.CvEnum.CONNECTIVITY.EIGHT_CONNECTED,
Emgu.CV.CvEnum.FLOODFILL_FLAG.DEFAULT, mask.Ptr);
if (comp.area < 10000)
{
image = image_copy.Copy();
}
}
}
}
}
“新MCvScalar(0,0,0),新MCvScalar(0,0,0),” 不是在这种情况下,真正重要的,因为你只是在一个二进制图像的结果填充。 YOu可以与其他设置一起玩,看看你能达到什么效果。 “如果(comp.area < 10000)”是键不断更改是您要更改该方法将填充的大小洞。
这些是可以预期的结果:
原始
结果
这种方法的问题,我它的内存密集程度非常高,它能够在200x200的图像上吞噬6GB的内存,当我尝试200x300时,它会吞噬所有8GB的内存,并将所有内容都瘫痪。除非你的图像的大部分是白色的,你想填补微小的空白,或者你可以尽量减少你应用的方法,我会避免它。我会建议编写自己的类来检查每个不是255的像素,并添加围绕它的像素数。然后,您可以记录不是255的每个像素的位置(在简单列表中),并且如果您的计数低于阈值,则将图像中的这些位置设置为255(通过迭代列表)。
如果你不想自己写,那么我会坚持使用Aforge FillHoles类,因为它是专门为此目的而设计的。
干杯
克里斯
想到的问题是有点老了,我想贡献一个替代解决问题的办法。
可以得到相同的结果,克里斯没有记忆的问题,如果您使用以下命令:
private Image<Gray,byte> FillHoles(Image<Gray,byte> image)
{
var resultImage = image.CopyBlank();
Gray gray = new Gray(255);
using (var mem = new MemStorage())
{
for (var contour = image.FindContours(
CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
RETR_TYPE.CV_RETR_CCOMP,
mem); contour!= null; contour = contour.HNext)
{
resultImage.Draw(contour, gray, -1);
}
}
return resultImage;
}
关于上述方法的好处是,你可以选择性地填充孔,以满足您的标准。例如,您可能要补,孔,其像素数(BLOB中的黑色像素的数量)低于50等
private Image<Gray,byte> FillHoles(Image<Gray,byte> image, int minArea, int maxArea)
{
var resultImage = image.CopyBlank();
Gray gray = new Gray(255);
using (var mem = new MemStorage())
{
for (var contour = image.FindContours(
CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
RETR_TYPE.CV_RETR_CCOMP,
mem); contour!= null; contour = contour.HNext)
{
if ((contour.Area < maxArea) && (contour.Area > minArea))
resultImage.Draw(contour, gray, -1);
}
}
return resultImage;
}
我认为这是最好的答案。 – Rick2047
我也是。以前经常会导致OutOfMemory问题 –
可以使用FillConvexPoly
image.FillConvexPoly(externalContours.ToArray(), new Gray(255));
- 1. Emgu CV SURFFeature Error
- 2. 使用emgu cv
- 3. 使用emgu CV
- 4. 矩形 - Emgu CV
- 5. Emgu CV ColorConversion.RGB2GRAY/BGR2GRAY
- 6. EMGU CV异常
- 7. Emgu CV中的Matrix.Reshape()函数
- 8. Emgu CV中的Alpha混合
- 9. Emgu CV显示GpuImage
- 10. Emgu CV Blob检测
- 11. 在emgu cv中重塑
- 12. SVG:用孔填充图案
- 13. 用孔填充区域
- 14. 自适应孔填充
- 15. 使用Emgu的Background Subtaction cv
- 16. 使用Emgu CV运行相机CV
- 17. 与Emgu CV一起使用Kinect ColorImageFrame CV
- 18. 加载训练SVM - Emgu CV
- 19. Emgu CV未检测到CUDA
- 20. 如何使用emgu CV
- 21. 划分团块在Emgu CV
- 22. Haar Cascades Emgu CV C#error
- 23. 捕获RTSP与Emgu CV
- 24. Emgu Cv运动检测
- 25. Emgu CV微笑检测
- 26. EMGU CV SURF图像匹配
- 27. emgu CV C#捕获类
- 28. Emgu CV中的人像模式
- 29. Emgu CV 3.2.0中的计数器
- 30. Emgu CV - EmguCV中的图像框架(Skeletonization)
非常感谢克里斯!那就对了 !!! –