Emgu CV Распознавание лиц: запуск DetectHaarCascade для нескольких файлов в параллельных выпусках - PullRequest
1 голос
/ 05 марта 2012

Я пытаюсь улучшить скорость обнаружения лиц на изображениях, запустив обнаружение лиц DetectHaarCascade одновременно для нескольких файлов. Но я сталкиваюсь с AccessViolationException, интересно, есть ли у кого-нибудь примеры того, как параллельно выполнять распознавание лиц EMGU CV.

Вот простой тест, который я написал, где у меня есть 98 изображений для обнаружения:

    [TestMethod]
    public void TestDetectParallel()
    {
        var face = new HaarCascade("haarcascade_frontalface_default.xml");
        var images =
            Directory.EnumerateFiles(Environment.CurrentDirectory, "*.jpg").AsParallel().Select(
                file => new Image<Gray, byte>(file));
        Parallel.ForEach(
            images, 
            image =>
            {
                image.DetectHaarCascade(face, 1.2, 10, HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
                                        new Size(20, 20));
            });
    }

, поскольку я запускаю его параллельно, я столкнулся с проблемой многопоточности с трассировкой стека:

System.AccessViolationException was unhandled by user code
  Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
  Source=Emgu.CV
  StackTrace:
       at Emgu.CV.CvInvoke.cvHaarDetectObjects(IntPtr image, IntPtr cascade, IntPtr storage, Double scaleFactor, Int32 minNeighbors, HAAR_DETECTION_TYPE flags, Size minSize)
       at Emgu.CV.Image`2.<>c__DisplayClassa.<DetectHaarCascade>b__6(IImage img, Int32 channel) in C:\Emgu\emgucv-windows-x86 2.3.0.1416\Emgu.CV\Image.cs:line 888
       at Emgu.CV.Image`2.ForEachDuplicateChannel[TReturn](Func`3 conv) in C:\Emgu\emgucv-windows-x86 2.3.0.1416\Emgu.CV\Image.cs:line 1229
       at Emgu.CV.Image`2.DetectHaarCascade(HaarCascade haarObj, Double scaleFactor, Int32 minNeighbors, HAAR_DETECTION_TYPE flag, Size minSize) in C:\Emgu\emgucv-windows-x86 2.3.0.1416\Emgu.CV\Image.cs:line 904
       at PhotosortService.UnitTest.UnitTest1.<>c__DisplayClass3.<TestDetectParallel>b__1(Image`2 image) in C:\Users\bchiu\Desktop\PhotosortService\PhotosortService.UnitTest\UnitTest1.cs:line 35
       at System.Threading.Tasks.Parallel.<>c__DisplayClass32`2.<PartitionerForEachWorker>b__30()
       at System.Threading.Tasks.Task.InnerInvoke()
       at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
       at System.Threading.Tasks.Task.<>c__DisplayClass7.<ExecuteSelfReplicating>b__6(Object )
       at System.Threading.Tasks.Task.ExecuteSelfReplicating(Task root)
       at System.Threading.Tasks.Task.Execute()
       at System.Threading.Tasks.Task.ExecutionContextCallback(Object obj)
       at System.Threading.ExecutionContext.runTryCode(Object userData)
       at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
       at System.Threading.Tasks.Task.ExecuteEntry(Boolean bPreventDoubleExecution)
       at System.Threading.Tasks.ThreadPoolTaskScheduler.TryExecuteTaskInline(Task task, Boolean taskWasPreviouslyQueued)
       at System.Threading.Tasks.TaskScheduler.TryRunInline(Task task, Boolean taskWasPreviouslyQueued, Object threadStatics)
       at System.Threading.Tasks.Task.InternalRunSynchronously(TaskScheduler scheduler)
       at System.Threading.Tasks.Task.RunSynchronously(TaskScheduler scheduler)
       at System.Threading.Tasks.Parallel.PartitionerForEachWorker[TSource,TLocal](Partitioner`1 source, ParallelOptions parallelOptions, Action`1 simpleBody, Action`2 bodyWithState, Action`3 bodyWithStateAndIndex, Func`4 bodyWithStateAndLocal, Func`5 bodyWithEverything, Func`1 localInit, Action`1 localFinally)
       at System.Threading.Tasks.Parallel.ForEachWorker[TSource,TLocal](IEnumerable`1 source, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Action`3 bodyWithStateAndIndex, Func`4 bodyWithStateAndLocal, Func`5 bodyWithEverything, Func`1 localInit, Action`1 localFinally)
       at System.Threading.Tasks.Parallel.ForEach[TSource](IEnumerable`1 source, Action`1 body)
       at PhotosortService.UnitTest.UnitTest1.TestDetectParallel() in C:\Users\bchiu\Desktop\PhotosortService\PhotosortService.UnitTest\UnitTest1.cs:line 33
  InnerException: 

Большое спасибо!

1 Ответ

1 голос
/ 12 марта 2012

Решается путем предоставления var face = new HaarCascade("haarcascade_frontalface_default.xml"); объекта каждому потоку.

[TestMethod]
public void TestDetectParallel()
{        
    var images =
        Directory.EnumerateFiles(Environment.CurrentDirectory, "*.jpg").AsParallel().Select(
            file => new Image<Gray, byte>(file));
    Parallel.ForEach(
        images, 
        image =>
        {
            var face = new HaarCascade("haarcascade_frontalface_default.xml");
            image.DetectHaarCascade(face, 1.2, 10, HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
                                    new Size(20, 20));
        });
}
...