Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# FindCirclesGrid中的OpenCVSharp AccessViolationException_C#_Opencv_Access Violation_Opencvsharp - Fatal编程技术网

C# FindCirclesGrid中的OpenCVSharp AccessViolationException

C# FindCirclesGrid中的OpenCVSharp AccessViolationException,c#,opencv,access-violation,opencvsharp,C#,Opencv,Access Violation,Opencvsharp,我正在使用OpenCVSharp运行一些校准测试,但我似乎无法让FindCirclesGrid正常工作,调用FindCirclesGrid时,我遇到了一个非常意外的AccessViolationException异常 我不确定我可能做错了什么,因为前两行与示例中的几乎一样,centers没有初始化,因为它是一个输出参数,传递给OpenCV的所有内容似乎都在OpenCVSharp的包装函数中初始化 void test() { Mat im = Cv2.ImRead(@"path_to_my

我正在使用OpenCVSharp运行一些校准测试,但我似乎无法让FindCirclesGrid正常工作,调用FindCirclesGrid时,我遇到了一个非常意外的AccessViolationException异常

我不确定我可能做错了什么,因为前两行与示例中的几乎一样,centers没有初始化,因为它是一个输出参数,传递给OpenCV的所有内容似乎都在OpenCVSharp的包装函数中初始化

void test()
{
    Mat im = Cv2.ImRead(@"path_to_my_file.jpg");
    Size patternsize = new Size(11, 4);
    Point2f[] centers;
    var f = Cv2.FindCirclesGrid(im, patternsize, out centers, FindCirclesGridFlag.AsymmetricGrid);
}
我使用的是nuget最新的OpenCVSharp

Edit1:我忘了在问题中提到这一点,但我已经尝试在FindCirclesGrid之后添加foillowing,以确保对象在应该收集之前没有被错误地收集,这并没有改变什么。同样,在调试和发布中也会发生同样的错误

 Console.Writeline(im.ToString());
 Console.Writeline(patternsize.ToString());
 Console.Writeline(centers.ToString());
 Console.Writeline(f.ToString());

垃圾收集可能在找到圆网格时执行。如果您在发布模式下运行应用程序而不进行调试,那么JIT编译器将执行优化,并且在完成对非托管资源的操作之前,对象可能会接受垃圾收集。很可能会导致应用程序崩溃

这个问题很容易解决:只需参考当前图像、图案大小等,直到该方法完成其工作,或者尝试使用以下方法:


而不是写这行

var f = Cv2.FindCirclesGrid(im, patternsize, out centers, FindCirclesGridFlag.AsymmetricGrid);
试试这个:

var f=Cv2.FindCirclesGrid(im、patternsize、out-Center、CALIB\u CB\u不对称网格)

如前所述,FindCirclesGrid()函数将第四个参数作为常数,具体取决于您的圆模式

它可以是以下内容之一:

CALIB\u CB\u对称网格使用对称圆图案。 CALIB\u CB\u不对称网格使用不对称的圆图案。 CALIB_CB_聚类使用一种特殊的算法进行网格检测。它对透视失真更为鲁棒,但对背景杂波更为敏感

您可以使用Ptr(FeatureDetector)类型的第五个参数来查找亮背景上类似黑圈的斑点

或者您可以尝试转换 “FindCirclesGridFlag.AsymmetricGrid”为整数。 e、 g.
(int)FindCirclesGridFlag.AsymmetricGrid
希望我已经理解了您的问题。

为此,我提交了一个包含在NuGet版本2.4.10.20150604中的修复程序

有两个互操作调用,由C++包装器DLL>代码> OpenCVAsPrPutsXNU/CON> > OpenCVHARP内部使用:<代码> CALB3DFIN CURLSCESGRIDIOL输入数组< /COD>和

他们的签名仅通过使用C++类型<代码> CV::OutOutoStuts和 STD::vector < /COD> > <代码>中心>代码>参数,但是在C→EXTENN定义中,这些都被定义为ItpTr>/Cuth>,使得方法在编译时可以在C</p>中互换。 <> > Git版本(最近提交E14C711958),C++代码重载的代码< > FindCirclesGrid <代码>映射到同一个互操作调用<代码> Calb3DyFieldCulsGrIDIIORIDUnit ,因此使用<代码> PoTr2F[]/Cuffe的过载不起作用,因为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());
    }
}
//NuGet软件包OpenCVAnyCPU 2.4.10.20150320失败。
使用(var imageStream=newmemoryStream())
{
使用(var circleBoard=新系统.绘图.位图(650850))
使用(var g=系统.绘图.图形.来自图像(圆圈板))
{
g、 清晰(系统、图纸、颜色、白色);

对于(int y=0;y我在github报告了一个bug。它现在似乎已经修复了,但我无法测试它


由于调用NativeMethods.calib3d_findCirclesGrid_InputArray(…)可能是具有非托管代码属性的东西?我应该将此添加到我的问题中,但在测试中,我已经通过在控制台中抛出而丢弃了它。为每个定义的对象(im patternsize和Center)创建Writeline(obj.ToString)确保没有GC问题。所以这不可能是问题。同样,在debug和Release中也会发生同样的问题。你是对的,这听起来像一个bug,而另一个重载不会抛出(它不起作用,对我来说返回false,但是,如果你有机会,你可以压缩你的示例项目,包括png文件,以便我可以比较并找到我的问题所在?我复制/粘贴了你的代码,并将pdf转换为jpeg,findcircles返回false)感谢更新的示例,我现在就可以复制它了。如果你可以做github bug,那将非常好,因为我对git&co一无所知,我甚至没有在那里的帐户。该bug已经关闭,它是我修复的bug的副本(请参阅我答案中的链接)。
// 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());
    }
}