如何正确使用'using'命令?
How to use the 'using' command properly?
我刚刚创建了这个帐户,如果我忘记了一些重要信息,请原谅我。
我有以下代码,但我怀疑存在内存泄漏。代码的目标是从(模拟)相机的图像中获取字节,并使用这些字节生成 EmguCV 图像。问题是生成的数组的长度永远不会保持不变。当我生成 300x300 图像时,我希望该数组包含 90000 个条目。但这种情况很少见。数字不断变化。
我尝试按照一些教程学习如何正确使用 'using' 命令来处理变量,但到目前为止我都失败了。据我所知,我正在使用的字节列表似乎没有 IDisposable 函数。所以这可能是我失败的原因:/
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);
}
});
}
}
}
任何有关如何解决此问题的帮助将不胜感激!
你的问题是你正在使用并行循环将值添加到 "values" 列表,你正在多个线程中同时访问同一个列表,这不安全并且会损坏数据。改成常规循环应该就没问题了
您正在丢失字节,因为 Parallel.For
中的多线程代码不同步。下面是修复它的尝试。
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;
}
我刚刚创建了这个帐户,如果我忘记了一些重要信息,请原谅我。
我有以下代码,但我怀疑存在内存泄漏。代码的目标是从(模拟)相机的图像中获取字节,并使用这些字节生成 EmguCV 图像。问题是生成的数组的长度永远不会保持不变。当我生成 300x300 图像时,我希望该数组包含 90000 个条目。但这种情况很少见。数字不断变化。
我尝试按照一些教程学习如何正确使用 'using' 命令来处理变量,但到目前为止我都失败了。据我所知,我正在使用的字节列表似乎没有 IDisposable 函数。所以这可能是我失败的原因:/
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);
}
});
}
}
}
任何有关如何解决此问题的帮助将不胜感激!
你的问题是你正在使用并行循环将值添加到 "values" 列表,你正在多个线程中同时访问同一个列表,这不安全并且会损坏数据。改成常规循环应该就没问题了
您正在丢失字节,因为 Parallel.For
中的多线程代码不同步。下面是修复它的尝试。
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;
}