我有一个用 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个轮廓(没有一个被过滤掉)。
我想我对 python 行的作用有一些误解,当涉及到 0
中的 3
或 cnts_hs[0,i,3]
时,我仍然有这种误解。这就是为什么我在 .net 实现中将它们排除在外。
我想我应该提到我为 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
答案 0 :(得分:0)
经过更多的挖掘,我找到了解决方案:
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);
}
}