Open CJHCapture opened 5 years ago
Anyone have any comments or suggestions please?
@CJHCapture It looks like the image data is being loaded to memory, so eventually you run out of RAM and stuff starts getting loaded into protected areas, throwing this error.
Reading the code, it seems that processFrame
of HaarObjectDetector has an option to run the calculations in parallel, enabled by the detector.UseParallelProcessing = True
in your code. I'm halfway certain that this would spawn a thread for each new image, which isn't guaranteed to run until completion before enough threads spawn to completely overfill your memory.
Maybe you can try setting detector.UseParallelProcessing = False
and seeing what happens.
What would you like to submit? (put an 'x' inside the bracket that applies)
Issue description
I am using the ProcessFrame method for facial detection in VB.NET. I am collecting 4k images (about 7mb each) from two different cameras with a new image from each camera every 5 seconds. If I slow the image collections, say an image from each camera every 10 seconds, it takes longer to get the error, but the inverse is also true. If I speed up image collection, say to every 2 seconds, I get the error even faster.
The images are collected via the OpenCVSharp VideoCapture and I am adding an "image_processing" job to a BlockingCollection to process the images one at a time.
I am getting a System.AccessViolationException with the following Stack Trace:
System.AccessViolationException HResult=0x80004003 Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt. Source=Accord.Vision StackTrace: at Accord.Vision.Detection.HaarClassifier.Compute(IntegralImage2 image, Rectangle rectangle) at Accord.Vision.Detection.HaarObjectDetector.<>c__DisplayClass56_2.<ProcessFrame>b__0(Int32 j, ParallelLoopState options) at System.Threading.Tasks.Parallel.<>c__DisplayClass17_01.<ForWorker>b__1() at System.Threading.Tasks.Task.InnerInvoke() at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask) at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(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.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 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) at System.Threading.Tasks.Task.InternalRunSynchronously(TaskScheduler scheduler, Boolean waitForCompletion) at System.Threading.Tasks.Task.RunSynchronously(TaskScheduler scheduler) at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action1 body, Action2 bodyWithState, Func4 bodyWithLocal, Func1 localInit, Action1 localFinally) at System.Threading.Tasks.Parallel.For(Int32 fromInclusive, Int32 toExclusive, Action2 body) at Accord.Vision.Detection.HaarObjectDetector.ProcessFrame(UnmanagedImage image)
Sometimes it happens shortly after starting the process and sometimes it takes a few minutes, but the error always shows up.
The "image_processing" function has a public HaarObjectDetector object which is initialized when the class is created:
detector = New HaarObjectDetector(New FaceHaarCascade(), 40, ObjectDetectorSearchMode.Average, 1.5F, ObjectDetectorScalingMode.GreaterToSmaller)
detector.MaxSize = New Drawing.Size(500, 500)
detector.Suppression = 1
detector.UseParallelProcessing = True
Then, inside the "image_processing" method:
Dim vImage As Accord.Imaging.UnmanagedImage = Accord.Imaging.UnmanagedImage.FromManagedImage(Visualization.MatToBitMap(frame.Image.Clone))
I have tried many different options with the line above, sending it just a bitmap, converting to unmanaged, etc. but nothing seems to helprects = detector.ProcessFrame(vImage)
vImage.Dispose()
The "Visualization.MatToBitMap" function is as such and returns a bitmap:
Public Shared Function MatToBitMap(mat As OpenCvSharp.Mat) As Bitmap
Using ms As MemoryStream = mat.ToMemoryStream
mat.Dispose()
mat = Nothing
Return CType(Image.FromStream(ms), Bitmap)
End Using
End Function