0

有很多关于这个的帖子,但我仍然无法弄清楚。我对此很陌生,所以请原谅。

我显示一个图像,然后抓取一个新图像,并尝试显示它。当显示新图像时,它具有旧图像的残余。我试过Picture1.Image= null无济于事。

托管内存有问题吗?我怀疑这与内存的管理方式有关,即代码以某种方式将新图像复制到旧图像上,从而留下前一个图像中的一些数据。

这是显示数据的代码scaled1(来自这个有用的早期帖子):

编辑: 添加的代码显示处理绘制的数组。如果使用该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();
4

1 回答 1

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数组,而是sumsinsumcos数组 - 你总是添加到那些,所以你会添加到已经存在的值,而不是再次从零开始. 因此,您需要首先将这些数组重置为零(这就是这样Array.Clear做的)。

于 2014-07-17T08:00:45.770 回答