accord-net / framework

Machine learning, computer vision, statistics and general scientific computing for .NET
http://accord-framework.net
GNU Lesser General Public License v2.1
4.49k stars 1.99k forks source link

System.AccessViolationException in Accord.Vision.dll #1869

Open CJHCapture opened 5 years ago

CJHCapture commented 5 years ago

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 help rects = 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

CJHCapture commented 5 years ago

Anyone have any comments or suggestions please?

UnicodingUnicorn commented 5 years ago

@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.