我目前正在使用EmguCV对图像应用一些过滤器,所以我有6个图片框,每个图片框代表相同的图像,但带有过滤器。问题是当平移和缩放有时我得到AccessViolationException错误。
/// <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;
}
每个图片框都与其他图片同步,因此如果缩放或平移,其他图片框将同步到相同位置并缩放
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;
}
在进行一些平移或缩放后,此错误将显示:
发生了System.AccessViolationException 的HResult = 0x80004003 消息= Tentativa de ler ou escrevernamemóriaprotegida。 Istoénormalmenteumainindicaçãodeque existeoutramemoóriapanificada。 来源= System.Drawing中 堆栈跟踪: 在System.Drawing.SafeNativeMethods.Gdip.GdipDrawImageRectRect(HandleRef图形,HandleRef图像,单dstx,单dsty,单dstwidth,单dstheight,单srcx,单srcy,单srcwidth,单srcheight,Int32 srcunit,HandleRef imageAttributes,DrawImageAbort回调, HandleRef callbackdata) 在System.Drawing.Graphics.DrawImage(Image image,RectangleF destRect,RectangleF srcRect,GraphicsUnit srcUnit) 在Cyotek.Windows.Forms.ImageBox.DrawImage(Graphics g) 在Cyotek.Windows.Forms.ImageBox.OnPaint(PaintEventArgs e) 在System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e,Int16 layer) 在System.Windows.Forms.Control.WmPaint(消息&amp; m) 在System.Windows.Forms.Control.WndProc(消息&amp; m) 在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)
我正在使用AppDomain.CurrentDomain.UnhandledException来导致此
.NET Framework:4.6.2(使用WinForms)
问题:AccessViolationException
正在使用的图片框:Cyotek.Windows.Forms.ImageBox,也尝试使用Emgu.CV.UI.PanAndZoomPictureBox,我得到了同样的错误
内存看起来像是损坏了还是GC?
答案 0 :(得分:1)
我在同一个视频文件中只使用过两次VideoCapture,遇到了类似的问题。
虽然我不知道确切的原因,但这是一个并发问题,适当地使用lock statements通常是解决方案。
我认为,当下一个VideoCapture实例尝试访问硬盘驱动器上视频文件存储中的相同位置时,两个VideoCapture实例都会在幕后运行一些异步代码。
这不是一个完整的修复,但编译64位项目将减少这些问题的频率。我确信这是因为代码在64位而不是某些环形交叉dll问题上运行效率更高。
如果我找到完整的解决方案,我一定会通知您。