I'm currently using EmguCV to apply some filters to image, so i have 6 picture box, each picture box represent same image but with a filter. The problem is when pan and zoom sometimes i got AccessViolationException error.
/// <summary>
/// Start processing the image
/// </summary>
public void ProcessImage()
{
//Load the image from file and resize it for display
Image<Bgr, Byte> img =
new Image<Bgr, byte>(FilePath);
AddImageBox("Original", img.Bitmap);
//.Resize(400, 400, Emgu.CV.CvEnum.Inter.Linear, true);
HistogramPanel.ClearHistogram();
HistogramPanel.GenerateHistograms(img, 256);
HistogramPanel.Refresh();
ListViewItem item = lvData.Items.Add("FileName");
item.SubItems.Add(FileName);
item = lvData.Items.Add("Size");
item.SubItems.Add($"{img.Bitmap.Size.Width}, {img.Bitmap.Size.Height}");
//Convert the image to grayscale and filter out the noise
Image<Gray, Byte> imgGray = img.Convert<Gray, Byte>().PyrDown().PyrUp();
/*UMat uimage = new UMat();
CvInvoke.CvtColor(img, uimage, ColorConversion.Bgr2Gray);
//use image pyr to remove noise
UMat pyrDown = new UMat();
CvInvoke.PyrDown(uimage, pyrDown);
CvInvoke.PyrUp(pyrDown, uimage);*/
AddImageBox("Filtered", imgGray.Bitmap);
/*Image<Gray, Byte> imgGray =
new Image<Gray, byte>(uimage.Bitmap);*/
Image<Gray, Byte> imgCanny = imgGray.Canny(200, 100);
AddImageBox("Canny", imgCanny.Bitmap);
Image<Gray, float> imgSobel = imgGray.Sobel(1, 0, 5);
AddImageBox("Sobel", imgSobel.Bitmap);
Image<Gray, float> imgLaplace = imgGray.Laplace(3);
AddImageBox("Laplace", imgLaplace.Bitmap);
Image<Gray, float> imgSobelHeavy = imgGray.Sobel(0, 1, 3).Add(imgGray.Sobel(1, 0, 3)).AbsDiff(new Gray(0.0));
AddImageBox("Sobel Heavy", imgSobelHeavy.Bitmap);
IsLoaded = true;
}
Each picturebox is Sync with others, so if zoom or pan, others will sync to same position and zoom
ImageBox.ZoomChanged += (sender, args) => SyncImages();
ImageBox.Scroll += (sender, args) => SyncImages();
/// <summary>
/// Sync all images to be at same zoom and position
/// </summary>
public void SyncImages()
{
if (ReferenceEquals(ParentTab, null) || ParentTab.SuspendEvents) return;
ParentTab.SuspendEvents = true;
foreach (var ctrlImageBox in ParentTab.ImageBoxs)
{
if (ReferenceEquals(ctrlImageBox, this))
continue;
ctrlImageBox.ImageBox.Zoom = ImageBox.Zoom;
ctrlImageBox.ImageBox.AutoScrollPosition = new Point(Math.Abs(ImageBox.AutoScrollPosition.X), Math.Abs(ImageBox.AutoScrollPosition.Y));
}
Program.FrmMain.UpdateStatusBar();
ParentTab.SuspendEvents = false;
}
After some pan or zooms this error will show:
System.AccessViolationException occurred HResult=0x80004003 Message=Tentativa de ler ou escrever na memória protegida. Isto é normalmente uma indicação de que existe outra memória danificada. Source=System.Drawing StackTrace: at System.Drawing.SafeNativeMethods.Gdip.GdipDrawImageRectRect(HandleRef graphics, HandleRef image, Single dstx, Single dsty, Single dstwidth, Single dstheight, Single srcx, Single srcy, Single srcwidth, Single srcheight, Int32 srcunit, HandleRef imageAttributes, DrawImageAbort callback, HandleRef callbackdata) at System.Drawing.Graphics.DrawImage(Image image, RectangleF destRect, RectangleF srcRect, GraphicsUnit srcUnit) at Cyotek.Windows.Forms.ImageBox.DrawImage(Graphics g) at Cyotek.Windows.Forms.ImageBox.OnPaint(PaintEventArgs e) at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer) at System.Windows.Forms.Control.WmPaint(Message& m) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
I'm using AppDomain.CurrentDomain.UnhandledException to cath this
.NET Framework: 4.6.2 (With WinForms)
Problem: AccessViolationException
Picture box in use: Cyotek.Windows.Forms.ImageBox, also tried with Emgu.CV.UI.PanAndZoomPictureBox and i get the same error
Memory looks like corrupted or maybe GC?
I have experienced a similar issue only using VideoCapture twice on the same video file.
While I do not know the exact cause, this is a concurrency issue, using lock statements appropriately is typically the solution.
My belief is that both VideoCapture instances have some asynchronous code behind the scenes that is still running when the next VideoCapture instance attempts to access the same place in the video file's storage on the hard drive.
It is not a complete fix, but compiling the project for 64 bit will lessen the frequency of these issues. I am certain this is due to the code running more efficiently in 64 bit rather than some roundabout dll issue.
If i find a complete solution, I will be sure to let you know.
User contributions licensed under CC BY-SA 3.0