I am making a program in windows.forms, that is controling TV, taking screenshots of the screen and measuring time for certain events to happen (menu load, video start...). I make each measurement several times in a loop before I move to the next loop. For that I am using Emgu.CV. The screenshots are stored as a Mat in my class Shot:
internal class Shot
{
public Mat image { get; }
public int time { get; }
public Shot(Bitmap image, Rectangle rect, int time)
{
Rectangle translatedRect = new Rectangle(rect.X, rect.Y, rect.Width - rect.X, rect.Height - rect.Y);
this.image = new Mat(image.ToImage<Bgr, byte>().Mat, translatedRect);
this.time = time;
}
private Shot(Mat image, int time)
{
this.image = image;
this.time = time;
}
public Shot Clone()
{
return new Shot(image.Clone(), time);
}
}
The rest of the Mats are only stored in the current loop as a needle.
Now the problem - every now and then (and I mean quite frequently) I am getting "System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'" once I try to access the data of a Mat. The most extreme occurencce of this was when it iccured in this way.
var currentBlackScreen = imageProcessor.GetPrintscreenMat(chosenScreen, zone);
.
//I make some measurements here using the needle
.
currentBlackScreen.Save("000needletaken1.png"); //I successfuly tried to save the needle
.
//I am not using the currentBlackScreen in any way in this part of the code
.
currentBlackScreen.Save("000needletaken2.png"); //I get the error here.
I use Save() because it is a good indicator, that the Mat is corrupted. This problem seems to have started after I started using Mat(Mat, Rectangle). Can anyone please help me?
Note that I am currently leaving all the work of disposing of the images and Mats to Garbage Collector - and it have worked ok so far. I even tried to not use the needle itself, but Clone() it every time I pass it into a function as the first thing I do.
Edit: I am using winforms only to create a user interface so that the user can set up details of how the program will behave. After that winforms is not used until the end of the measurement.
The problem can be solved by adding clone() to the result Mat
this.image = new Mat(image.ToImage<Bgr, byte>().Mat, translatedRect).clone();
as @Pete suggested.