在我的应用程序中,我以最高350 fps的帧速率在线处理图像(1920x400)。从这些图像中,我连续计算出位于图片中间的黑色物体的面积。该物体通常没有几个白洞。
Example for you to get an idea of images
Example for you to get an idea of images
为了计算面积,我目前在阈值(B / W)图像上使用emguCV函数CvInvoke.CountNonZero(Mat)。这个解决方案运行得还不错,但是我的问题是漏洞,这些漏洞可能会很快误解结果。
我试图用形态侵 eclipse 来填补空缺
if (erodeEnable)
{
Mat kernel = new Mat(5, 5, DepthType.Cv8U, 1);
kernel.SetTo(new MCvScalar(1));
CvInvoke.Erode(postProcessTempMat, postProcessTempMat, new Mat(5, 5, DepthType.Cv8U, 1), new System.Drawing.Point(0,0), erodeIterations, BorderType.Default, new MCvScalar(0, 0, 0));
}
但是此操作会使对象的形状急剧变形。我想填充孔,但如果位置不变,请保持外形。
我还尝试使用自己的方法,该方法逐列搜索第一个上黑色像素和下黑色像素,并从这些像素的位置计算出外部形状的面积。
public int getBlackArea(Mat matImage)
{
Image<Gray, Byte> tempImg = matImage.ToImage<Gray, Byte>();
int result = 0;
int coll = 0;
int upperBorder, lowerBorder;
const int avFactor = 3;
result = 0;
for (coll = 0; coll < tempImg.Width; coll=coll+avFactor)
{
lowerBorder = 0;
while ((tempImg.Data[lowerBorder,coll, 0] > 0) && (lowerBorder < tempImg.Height))
{
lowerBorder++;
}
upperBorder = iMAGEhEIGHT - 1;
while ((tempImg.Data[upperBorder,coll, 0] > 0) && (upperBorder > 0))
{
upperBorder--;
}
result += ((upperBorder - lowerBorder) * avFactor);
//tempImg.Data[(upperBorder-5), coll, 0] = 120; // draw the outline for check of function
//tempImg.Data[(lowerBorder+5), coll, 0] = 120; // draw the outline for check of function
}
//tempImg.Save(@"C:\\pics\INFOoutlined.jpg");
return result;
}
此方法返回很好的结果,但是太费时了。
您没有任何想法,如何改善我的功能以加快速度?还是您没有其他想法,我怎么能得出结果?
提前谢谢了 :)
最佳答案
这完全取决于您选择执行哪种形态学操作。
首先,通过选择最佳阈值对图像进行二值化。
然后我执行了打开形态。与yvs所说的不同,形态 close 根本不改变图像。由于要填充的孔被黑色像素包围,因此开放可以解决该问题。
但是,如果孔被白色像素包围,则可以通过形态 close 来解决问题。
输出
图片1:
阈:
形态开放:
图片2:
阈:
形态开放:
如您所见,在两种情况下,孔均已填充。
关于c# - emguCV-快速计算二进制图像中带孔的对象的面积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42727644/