这是 OpenCvSharp 中的一个错误,我提交了一个包含在 NuGet 版本 2.4.10.20150604 中的修复程序。
OpenCvSharpExtern
OpenCvSharp 在内部使用的 C++ 包装器 dll 导出了两个互操作调用:calib3d_findCirclesGrid_InputArray
和calib3d_findCirclesGrid_vector
.
它们的签名仅在 C++ 类型cv::_OutputArray
和参数std::vector<cv::Point2f>
的使用上有所不同centers
,但在 C# extern 定义中,它们都定义为IntPtr
,使得这些方法在 C# 编译时可互换。
影响 git 版本(最新提交 e14c711958)具有FindCirclesGrid
映射到相同互操作调用的C# 重载calib3d_findCirclesGrid_InputArray
,因此重载 usingPoint2f[]
不起作用,因为 C++ 代码没有得到它期望的参数。
例如,此处使用校准图像的模拟作为输入图像:
// Fails with NuGet package OpenCvSharp-AnyCPU 2.4.10.20150320.
using (var imageStream = new MemoryStream())
{
using (var circleBoard = new System.Drawing.Bitmap(650, 850))
using (var g = System.Drawing.Graphics.FromImage(circleBoard))
{
g.Clear(System.Drawing.Color.White);
for (int y = 0; y <= 10; y += 1)
for (int x = 0; x <= 3; x += 1)
{
var dx = 10 + x * 150;
var dy = 10 + y * 75;
g.FillEllipse(System.Drawing.Brushes.Black, dx + ((y + 1) % 2) * 75, dy, 50, 50);
}
circleBoard.Save(imageStream, System.Drawing.Imaging.ImageFormat.Png);
}
Mat im = Cv2.ImDecode(imageStream.GetBuffer(), OpenCvSharp.LoadMode.GrayScale);
Size patternsize = new Size(4, 11);
var centers = new List<Point2f>();
if (Cv2.FindCirclesGrid(im, patternsize, OutputArray<Point2f>.Create(centers), FindCirclesGridFlag.AsymmetricGrid | FindCirclesGridFlag.Clustering))
{
// Ok, finds 44 circles
Console.WriteLine(centers.Count());
}
Point2f[] centers2 = null;
if (Cv2.FindCirclesGrid(im, patternsize, out centers2, FindCirclesGridFlag.AsymmetricGrid | FindCirclesGridFlag.Clustering))
{
// Crashes with AccessViolationException
Console.WriteLine(centers2.Count());
}
}