有很多关于此的帖子,但我仍然无法弄明白。我对此很新,所以请原谅。
我显示图像,然后抓取一个新图像,并尝试显示它。显示新图像时,它具有旧图像的残余。我试过Picture1.Image= null
无济于事。
托管内存是一个问题吗?我怀疑它与如何管理内存有关,不知何故,代码以一种从前一图像中留下一些数据的方式复制新图像和旧图像。
以下是在scaled1
中显示数据的代码(来自this之前的帖子):
修改
添加的代码显示了绘制的数组的处理。如果使用Array.Clear
方法清除数组,则覆盖行为将停止。也许当这个问题得到解决时,我可以发布一个证明该问题的规范片段。
这会将问题重置为:为什么在重写数组的每个值时都需要清除数组?数组如何保留先前值的信息?
ushort[] frame = null;
byte[] scaled1 = null;
double[][] frameringSin;
double[][] frameringCos;
double[] sumsin;
double[] sumcos;
frame = new ushort[mImageWidth * mImageHeight];
scaled1 = new byte[mImageWidth * mImageHeight];
frameringSin = new double[RingSize][];
frameringCos = new double[RingSize][];
ringsin = new double[RingSize];
ringcos = new double[RingSize];
//Fill array with images
for(int ring=0; ring <nN; ++ring)
{
mCamera.GrabFrameReduced(framering[ring], reduced, out preset);
}
//Process images
for (int i = 0; i < nN; ++i)
{
Array.Clear(frameringSin[i], 0, frameringSin.Length);
Array.Clear(frameringCos[i], 0, frameringSin.Length);
}
Array.Clear(sumsin, 0, sumsin.Length);
Array.Clear(sumcos, 0, sumcos.Length);
for(int r=0;r<nN; ++r)
{
for (int i = 0; i < frame.Length; ++i)//upto 12 ms
{
frameringSin[r][i] = framering[r][i]* ringsin[r] / nN;
frameringCos[r][i] = framering[r][i] *ringcos[r] / nN;
}
}
for (int i = 0; i < sumsin.Length; ++i)//up to 25ms
{
for (int r = 0; r < nN; ++r)
{
sumsin[i] += frameringSin[r][i];
sumcos[i] += frameringCos[r][i];
}
}
for(int r=0 ; r<nN ;++r)
{
for (int i = 0; i < sumsin.Length; ++i)
{
A[i] = Math.Sqrt(sumsin[i] * sumsin[i] + sumcos[i] * sumcos[i]);
}
//extract scaling parameters
...
//Scale Image
for (i1 = 0; i1 < frame.Length; ++i1)
scaled1[i1] = (byte)((Math.Min(Math.Max(min1, frameA[i1]), max1) - min1) * scale1);
bmp1 = new Bitmap(mImageWidth,mImageHeight,System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
var bdata1 = bmp1.LockBits(new Rectangle(new Point(0, 0), bmp1.Size), ImageLockMode.WriteOnly, bmp1.PixelFormat);
try
{
Marshal.Copy(scaled1, 0, bdata1.Scan0, scaled1.Length);
}
finally
{
bmp1.UnlockBits(bdata1);
}
Picture1.Image = bmp1;
Picture1.Refresh();
答案 0 :(得分:0)
实际上,您并没有替换数组中的所有值 - 您的 for
周期是错误的。你希望它们看起来像这样:
for (i1 = 0; i1 < frame.Length; i1++)
scaled1[i1] = (byte)((Math.Min(Math.Max(min1, frameA[i1]), max1) - min1)
* scale1);
区别( i++
vs ++i
)是您的方式,您正在跳过第一个和最后一个索引。 C#数组从0
开始,而你从1
开始(在第一次运行主体之前增加循环变量)。
此外,请注意,出于性能原因,如果您像这样通过数组,它会非常方便:
for (var i = 0; i < array.Length; i++)
/* do work with array[i] */
JIT编译器识别这一点并避免边界检查,因为它知道永远不会有溢出。当您使用数组进行大量工作时,这可以为您提供巨大的性能提升,即使您通过相同的索引访问多个阵列(其中一个不会有检查,其他人将 - 仍然保存很多工作)。
默认的JIT对此并不是很聪明(它必须非常快),所以其他任何东西都会重新引入边界检查。如果性能是您的关注点,那么您当然希望对代码进行概要分析。
编辑:啊,我的坏。无论如何,我认为您的问题不是必须清除frameringXXX
数组,而是sumsin
和sumcos
数组 - 您总是会添加到这些数组,所以你要添加已经存在的值,而不是再从零开始。所以你需要先将这些数组重置为零(这是Array.Clear
所做的)。