如何将轮廓层次结构从 python openCV 转换为 emgu cv 以查找封闭轮廓

How to convert contour hierarchy from python openCV to emgu cv to find enclosing contours

我有一个用 python 编写的圆圈检测,我现在需要将其转换为 emgu cv 以启用捆绑到 Xamarin IOS 应用程序中。

为此,我保存了检测过程各个部分的图像,以便将其与新的 .net 实现进行比较。虽然有些部分很简单,但其他部分似乎更棘手。我目前停留在检测到的形状的层次结构上,并且已经检查了示例以及 this answer 然后我选择了它作为第一个解决方案。

这是我尝试转换的 python 行:

# 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]

目前我使用上述答案进行了尝试,结果如下:

// 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);
        }
    }
}

但结果却大不相同...而 python 行在对给定样本图像进行过滤后产生 49 个轮廓,而 .net 行产生原始的 91 个轮廓(none被过滤掉)。 我想我对 python 行的作用有一些误解,当涉及到 cnts_hs[0,i,3] 中的 03 时我仍然有这种误解。这就是为什么我在 .net 实现中将它们排除在外的原因。

编辑 1:

我想我应该提到我为 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

经过进一步挖掘,我找到了解决方案:

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);
    }
}