2015-05-02 2 views
3

Я использую OpenCVSharp для запуска некоторых калибровочных тестов, но я не могу заставить FindCirclesGrid работать, я получаю неожиданное исключение AccessViolationException при вызове FindCirclesGrid.OpenCVSharp AccessViolationException в FindCirclesGrid

Я не уверен, что я мог ошибаться, поскольку первые две строки в точности такие же, как в образцах, центры не инициализируются, поскольку это выходной параметр, и все, что передается в 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); 
} 

Я использую последнюю OpenCVSharp прямо из NuGet

Edit1: я забыл упомянуть об этом в вопросе, но я уже попытался добавить foillowing после FindCirclesGrid, чтобы обеспечить объекты не были неправильно собраны до они должны, это ничего не изменило. Также ошибка происходит точно так же в отладке и выпуске.

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

С NativeMethods.calib3d_findCirclesGrid_InputArray (...) называется, может быть что-то с неуправляемым кодом атрибута? –

ответ

0

Сбор мусора может быть выполнен, пока найдена сетка круга. Если вы запустите приложение в режиме освобождения без отладки, то компилятор JIT выполнит оптимизацию, и объект может быть подвергнут сборке мусора до завершения операции над неуправляемым ресурсом. Скорее всего, это приведет к сбою приложения.

Проблема может быть легко исправлена: это просто необходимо сохранить ссылку на текущее изображение, размер рисунка и т.д., пока метод завершает свою работу, или попытаться использовать GC.KeepAlive метод:

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); 
    GC.KeepAlive(this); 
} 
+0

Я должен был добавить это к моему вопросу, но я уже отбросил это в своих тестах, бросив в console.Writeline (obj.ToString) для каждого объекта, определенного (im patternize и center), чтобы убедиться, что не было проблемы с GC , Так что это не может быть проблемой. Также проблема все-таки возникает при отладке и выпуске –

0

Вместо писать эту строку

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

Попробуйте:

var f = Cv2.FindCirclesGrid(im, patternsize, out centers, CALIB_CB_ASYMMETRIC_GRID);

As, функция FindCirclesGrid() принимает четвертый аргумент как константу в зависимости от вашего шаблона кругов.

Это может быть одно из следующих действий:

CALIB_CB_SYMMETRIC_GRID использует симметричный рисунок кругов. CALIB_CB_ASYMMETRIC_GRID использует асимметричный рисунок кругов. CALIB_CB_CLUSTERING использует специальный алгоритм обнаружения сетки. Он более устойчив к перспективным искажениям, но гораздо более чувствителен к фоновой помехе.

Вы можете использовать пятый аргумент типа Ptr (FeatureDetector) для поиска капли, например, темных кругов на светлом фоне.

Или ELSE вы можете попробовать преобразовать "FindCirclesGridFlag.AsymmetricGrid" в целое. , например. (int)FindCirclesGridFlag.AsymmetricGrid Надеюсь, что я понял ваш вопрос.

1

Этот was a bug in OpenCvSharp, я представил исправление, которое было включено в выпуск NuGet 2.4.10.20150604.

Существует два вызова interop, экспортированных с помощью dll, которые OpenCvSharp использует внутри: calib3d_findCirclesGrid_InputArray и calib3d_findCirclesGrid_vector.

Их подписи отличаются только использованием типов C++ и cv::_OutputArraystd::vector<cv::Point2f> для параметра centers, но в определениях EXTERN C# они оба определены как IntPtr, что делают методы Сменные во время компиляции в C#.

Аффект GIT версию (последний коммит e14c711958) имеет как C# перегруженные FindCirclesGrid сопоставляется с тем же-взаимодействия вызова calib3d_findCirclesGrid_InputArray, следовательно, перегрузка с помощью Point2f[] не работает, как код C++ не получает параметр он ожидает.

E.g. используя имитацию калибровки изображения here в качестве входного изображения:

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

Вы правы, это звучит как ошибка, а другая перегрузка не бросается (она не работает и возвращает false для меня, однако, если вы сохранили ее, zip ваш образец проекта, включая файл png, чтобы я мог сравнивать и находить, где моя проблема? Я копирую/вставляю код и преобразовываю PDF в jpeg и findcircles возвращает false) –

+0

Спасибо за обновленный образец, я могу воспроизвести это как рабочий Теперь. Если вы можете сделать ошибку github, которая была бы замечательной, поскольку я не знаю, что делать с git & co, у меня даже нет учетной записи. –

Смежные вопросы