Emgu CV 人脸识别:在多个文件上并行运行 DetectHaarCascade 问题
Posted
技术标签:
【中文标题】Emgu CV 人脸识别:在多个文件上并行运行 DetectHaarCascade 问题【英文标题】:Emgu CV Face Recognition: Running DetectHaarCascade on multiple files in parallel issues 【发布时间】:2012-03-22 13:22:09 【问题描述】:我正在尝试通过在多个文件上同时运行 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】:通过给每个线程一个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));
);
【讨论】:
以上是关于Emgu CV 人脸识别:在多个文件上并行运行 DetectHaarCascade 问题的主要内容,如果未能解决你的问题,请参考以下文章
C# - Emgu CV - 人脸识别代码在 EigenObjectRecognizer 处停止执行并无错误退出
C# - Emgu Cv - 人脸识别 - 将保存到 Access 数据库的人脸训练集作为二进制文件加载到 EigenObjectRecognizer 中以进行人脸识别