c# emgu/opencv 使用抛出异常 - 试图读取或写入受保护的内存
Posted
技术标签:
【中文标题】c# emgu/opencv 使用抛出异常 - 试图读取或写入受保护的内存【英文标题】:c# emgu/opencv usage throwing exception - Attempted to read or write protected memory 【发布时间】:2021-09-03 14:11:47 【问题描述】:我已经在这里访问了很多关于 System.AccessViolationException: 'Attempted to read or write protected memory.
错误的答案,它们似乎都是关于与图片无关的其他事情。
我正在学习图像处理,但我仍然在学习软件调试。我正在尝试使用基于 BRISK 的基于特征的图像检测和蛮力方法在另一个图像中搜索图像。但是由于某种原因,每次我运行并单击 button2 时都会出现上述错误,我不知道如何调试它。 matcher.KnnMatch(sceneDescriptor, matches, k);
行抛出异常,当我将鼠标悬停在它上面时,matches 的值为 null。
我在 Visual Studio 2019 中使用 NuGet 安装 Emgu.CV vs 4.5.1、Emgu.cv.bitmap、emgu.cv.runtime.windows 4.5.1。我什至尝试将我的编译模式从 x86 更改为 x64。我不知道我做错了什么。
文件 - myImgprocessing.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Emgu;
using Emgu.CV;
using Emgu.CV.Structure;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;
using Emgu.CV.Util;
using Emgu.CV.Features2D; // for brisk/ feature detectors
namespace mine
class MyImageProcessing
// store in memory any images we want to use
Dictionary<string, Image<Bgr, byte>> imgDict; // imgDict.Add("shark",img);
public Bitmap findImgFB(Image<Bgr, byte> sourceImg, Image<Bgr, byte> targetImg)
if ((sourceImg != null) && (targetImg != null))
var localImgSourceC = sourceImg.Clone();
var localImgSource = localImgSourceC.ToBitmap().ToImage<Gray, byte>();
var localImgTargetC = targetImg.Clone();
var localImgTarget = localImgTargetC.ToBitmap().ToImage<Gray, byte>();
//return localImgTarget.AsBitmap();
var myfoundPoints = processFBBrutforce(localImgTarget, localImgSource);
if(myfoundPoints != null)
// draw it now
CvInvoke.Polylines(sourceImg, myfoundPoints, true, new MCvScalar(0,0,255),5);
else
MessageBox.Show("cant find points to draw");
return sourceImg.AsBitmap(); // efficient way to convert gray image byte to grayscale
return new Bitmap(5, 5);
private static VectorOfPoint processFBBrutforce(Image<Gray, byte> target, Image<Gray, byte> sceneimg)
try
//
// initialization start
VectorOfPoint pointsToReturn = null;
Mat homography = null;
VectorOfKeyPoint targetKeyPoints = new VectorOfKeyPoint(); // key points stored here
VectorOfKeyPoint sceneKeyPoints = new VectorOfKeyPoint();
VectorOfVectorOfDMatch matches = null; // storing matches
Mat sceneDescriptor = new Mat();
Mat targetDescriptor = new Mat();
int k = 2; // NUMBER OF NEAREST MATCHES TO RETURN for uniquenes
Double uniqueThreshold = 0.80; // this is for finding neighbour matches so that it does not find duplicates and only uniques, tweak this number for results
Mat mask;
//descriptor and feature detection to use, tweak this for different results
Brisk featureDetector = new Brisk();
featureDetector.DetectAndCompute(target, null, targetKeyPoints, targetDescriptor,false); // give it img, place to store key points/descriptor, and false cus we need it to get key points
featureDetector.DetectAndCompute(sceneimg, null, sceneKeyPoints, sceneDescriptor, false);
// initialization end
//
// matching part - this is a brute-force matcher
BFMatcher matcher = new BFMatcher(DistanceType.Hamming);// we have to use 'hamming' distance calculator method because we are using BRISK feature detector above, can tweak respectively
matcher.Add(targetDescriptor);// give it model
matcher.KnnMatch(sceneDescriptor, matches, k);// match it with model and store in matches variable
// create a mask and set those values to 255
mask = new Mat(matches.Size,1,Emgu.CV.CvEnum.DepthType.Cv8U, 1);// 1 column, 8bit unsigned depth type, 1 channel image
mask.SetTo(new MCvScalar(255));
// goes through the masks and looks for match and sets to 255 or 0 for no match
Features2DToolbox.VoteForUniqueness(matches, uniqueThreshold, mask);
// give only the allowed scaled and rotated matches so it doesnt go past a certain point, this rejects any matches without the below requirements
int count = Features2DToolbox.VoteForSizeAndOrientation(targetKeyPoints, sceneKeyPoints, matches, mask, 1.5, 20); // scale = 1.5 , bins/rotation cap = 20
//
// now we can finally get the homography for the object
//
// if we dont have 4 matches, we cant build homography match
if(count >= 4)
homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(targetKeyPoints, sceneKeyPoints, matches, mask,
5); // adding mask will help to bring the best and unique matches - tweak the last peramiter
if (homography != null)
Rectangle rect = new Rectangle(Point.Empty, target.Size); // draw rectangle same size as the target image
// use homography to tell it where to draw it as it uses relationship between image and keypoints
// make array of the points as that what the transform method takes
PointF[] pts = new PointF[]
new PointF(rect.Left, rect.Bottom),
new PointF(rect.Right, rect.Bottom),
new PointF(rect.Right, rect.Top),
new PointF(rect.Left, rect.Top)
;
pts = CvInvoke.PerspectiveTransform(pts, homography); // put it into the pts
Point[] points = Array.ConvertAll<PointF, Point>(pts, Point.Round); // transform into vectorofpoints array to return
pointsToReturn = new VectorOfPoint(points);
return pointsToReturn;
catch (Exception e)
throw new Exception(e.Message);
然后在我的主窗口窗体中,我将目标和场景图像传递给它,并调用该方法以返回要显示的位图。但它每次都会在该特定行上出错:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Diagnostics;
using Emgu.CV;
using Emgu.CV.Structure;
namespace mine
public partial class mainform: Form
private Bitmap currentPassedImgBmp;
private void button2_Click_1(object sender, EventArgs e)
MyImageProcessing newImgProc = new MyImageProcessing();
Image<Bgr, byte> testTargetImg = new Image<Bgr, byte>(@"C:\items\target.png");
Image<Bgr, byte> sourceImgFromBMP = new Image<Bgr, byte>(@"C:\items\searchref.png");
// Image<Bgr, byte> sourceImgFromBMP = currentPassedImgBmp.ToImage<Bgr, byte>();
var mybitmap = newImgProc.findImgFB(sourceImgFromBMP, testTargetImg);
任何指导或指出正确的方向都会有所帮助,我花了将近一整天的时间浏览不同的答案和教程,这些答案和教程要么已经过时,要么指的是改变了上下文的视频。强>
【问题讨论】:
你说每次我尝试编译我都会收到上述错误 - 但听起来你在时看到了问题运行你的程序,因为你看到一个异常被抛出?编译时和运行时错误需要不同的处理。 抱歉,现在编辑我的答案 【参考方案1】:我没有测试我提出的解决方案,但我确信您需要在将匹配项传递给 KnnMatch 方法之前对其进行初始化:
VectorOfVectorOfDMatch matches = new VectorOfVectorOfDMatch();
我还要指出,您需要注意正确处理持有非托管资源的对象(例如 EmguCV 的 Mat 对象),否则一旦超出实验步骤,您将很快遇到内存问题。
【讨论】:
太棒了!只需更改 VectorOfVectorOfDMatch 匹配 = null;到您显示的代码已使其工作。以上是关于c# emgu/opencv 使用抛出异常 - 试图读取或写入受保护的内存的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 twain/emgu/open cv 获得良好的清晰度?