I have a circle detection written in python which I now need to convert into emgu cv to enable bundling into an Xamarin IOS App.
For that I save images of the detection process at various parts to compare it to the new .net implementation. While some parts are straight forward others seems to be more tricky. I am currently stuck on the hierarchy for detected shapes and already checked for examples as well as this answer which I then picked as a first solution.
This is the python line I try to convert:
# finding all contours in the image which are enclosed within other contours (child contours)
( cnts, cnts_hs ) = cv2.findContours(img.copy(), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
cnts = [cnt for i,cnt in enumerate(cnts) if cnts_hs[0,i,3] != -1]
Currently I tried it using the mentioned answer which results in the following implementation:
// finding all contours in the image which are enclosed within other contours (child contours)
// NOTE:
// 'hier' is of type 'Mat'
// 'cnts' 'cntsContourOut' are both of type 'VectorOfVectorOfPoint'
CvInvoke.FindContours(img.Clone(), cnts, hier, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple);
int count = cnts.Size;
for (int i = 0; i < count; i++)
{
using (VectorOfPoint cntr = cnts[i]) {
// check if the contour is enclosed in another contour
if (hier.GetDataPointer(i).ToInt32() != -1)
{
cntsContourOut.Push(cntr);
}
}
}
But the result is quite different... while the python lines results in 49 contours after filtering for a given sample-image the .net lines result in the original 91 contours (none is filtered out).
I guess I have some misunderstanding what the python line does, which I still have when it comes to the 0
or 3
in cnts_hs[0,i,3]
. That's why I just left them out in the .net implementation.
I guess I should have mentioned that I tried the following param variants for hier.GetDataPointer()
:
hier.GetDataPointer(0,i,3)
// result in an array size exceeded exception
hier.GetDataPointer(i,3) // or even 4 instead of 3
// result in the same 91 contours
After some more digging in I've found the solution:
var data = hier.GetData();
for (int i = 0; i < count; i++)
{
using (VectorOfPoint cntr = cnts[i]) {
var d = (int)data.GetValue(new int[3] { 0, i, 3 });
if(d != -1)
cntsContourOut.Push(cntr);
}
}