Reputation: 53
I just created this account so please forgive me if I forgot some crucial information.
I have the following code but I suspect that there is a memory leak. The goal of the code is to get the bytes from an image from a (simulated) camera und generate an EmguCV image with these. The problem is that the lenght of the generated array never stays the same. When I generate a 300x300 image, I would expect the array to contain 90000 entrys. But that is very rarely the case. The number is constantly changing.
I have tried to follow some tutorials on how to properly use the 'using' command to dispose of the variable but I have failed so far. As far as I can tell there seems to be no IDisposable function for the byte list I am using. So that might be a reason for my failure :/
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Emgu.CV;
using Emgu.CV.Structure;
namespace opencv_test
{
class Program
{
static void Main(string[] args)
{
Stemmer.Cvb.Image image = new Stemmer.Cvb.Image(300, 300);
image.Initialize(125);
List<byte> values = new List<byte>();
CopyPixelWithValue(image, values);
byte[] myArray = values.ToArray();
Emgu.CV.Image<Gray, Byte> test = new Image<Gray, Byte>(300, 300);
test.Bytes = myArray;
test.Save("D:/abc.jpg");
}
static unsafe void CopyPixelWithValue(Stemmer.Cvb.Image toGetValuesFrom, List<byte> values)
{
int width = toGetValuesFrom.Width;
int height = toGetValuesFrom.Height;
var toCopyData = toGetValuesFrom.Planes[0].GetLinearAccess();
byte* toCopyBase = (byte*)toCopyData.BasePtr;
long toCopyYInc = toCopyData.YInc.ToInt64();
long toCopyXInc = toCopyData.XInc.ToInt64();
Parallel.For(0, height, y =>
{
var pSrcLine = toCopyBase + y * toCopyYInc;
for (int x = 0; x < width; x++)
{
var srcVal = *(pSrcLine + x * toCopyXInc);
values.Add(srcVal);
}
});
}
}
}
Any help on how to fix this issue would be reatly appreciated!!
Upvotes: 3
Views: 263
Reputation: 43400
You are losing bytes because of unsynchronized multithreaded code inside Parallel.For
. Below is an attempt of fixing it.
static void Main(string[] args)
{
Stemmer.Cvb.Image image = new Stemmer.Cvb.Image(300, 300);
image.Initialize(125);
byte[] myArray = GetStemmerImageBytes(image);
Emgu.CV.Image<Gray, Byte> test = new Image<Gray, Byte>(300, 300);
test.Bytes = myArray;
test.Save("D:/abc.jpg");
}
static unsafe byte[] GetStemmerImageBytes(Stemmer.Cvb.Image image)
{
int width = image.Width;
int height = image.Height;
var linearAccess = image.Planes[0].GetLinearAccess();
byte* sourceBase = (byte*)linearAccess.BasePtr;
long sourceYInc = linearAccess.YInc.ToInt64();
long sourceXInc = linearAccess.XInc.ToInt64();
var result = new byte[width * height];
Parallel.For(0, height, y =>
{
var sourceLine = sourceBase + y * sourceYInc;
for (int x = 0; x < width; x++)
{
var srcVal = *(sourceLine + x * sourceXInc);
result[y * width + x] = srcVal;
}
});
return result;
}
Upvotes: 0
Reputation: 4542
You problem is that you are using a parallel loop to add values to "values" list, you are accessing the same list in multiple threads simultaneously, this is not safe and corrupts the data. Change it to a regular loop and you probably will have no problem.
Upvotes: 3