'emguCV - Quick calculation of area of the object with holes in binary image
In my application I online process images (1920x400) with frame rate up to 350 fps. From these images I calculate continuously the area of black object situated in the middle of the picture. The object has often few white holes.
Sample image 1:

Sample image 2:

For calculation of area I'm currently using the emguCV function CvInvoke.CountNonZero(Mat) on the thresholded (B/W) image. This solution runs pretty OK, but my problem are the holes, which could mispresent the results rapidly.
I tried to use morphological erosion in order to fill the holes
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));
}
but this operation deforms the object shape dramatically. I want to fill the holes, but keep the outer shape if poss unchanged.
I also tried to use my own method, which column by column searches first upper and lower black pixel and from the positions of these pixels calculate the area of the outer shape.
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;
}
This method returns very good results, but it is too time-demanding.
Don't you have any idea, how to improve my function in order to speed it up? Or don't you have any other idea, how could I reach the results?
Many thanks in advance :)
Solution 1:[1]
It all depends on what morphological operation you choose to perform.
I first binarized the images by selecting an optimal threshold.
Then I performed morphological open. Unlike stated by yvs, morphological close does not change the image at all. Since the holes to be filled are surrounded by black pixels morphological open solves the problem.
If however, the holes were surrounded by white pixels, morphological close would do the trick.
OUTPUT
Image 1:
Threshold:
Morphological Open:
Image 2:
Threshold:
Morphological Open:
As you can see, in both the cases the holes have been filled.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Jeru Luke |




