Jump to content

XNA Memória Esgotada


Cronicle8

Recommended Posts

Boa dia,

Estou a criar um jogo cujo objetivo é capturar imagens de uma webcam, depois aplicar uns filtros para detetar movimento, até agora consegui por a webcam a funcionar no programa, mas quando aplico os filtros dá-me um erro "Região de Bitmaps bloqueada", após conseguir resolver esse erro, deu-me outro de seguida "O formato de pixeis tem de ser igual no Overlay" ou algo assim parecido, mais uma vez consegui resolver o problema. Agora estou preso num outro erro "Memória Esgotada." System out of memory exception.

O erro aparece na seguinte linha:

image = eventArgs.Frame.Clone(Rec, PixelFormat.Format8bppIndexed);

Mas quando eu uso os breakpoints diz-me que o erro vem de :

for (int i = 0; i < imgData.Length; i++)
		    {
			    byteData[i] = (byteData[i] & 0x000000ff) << 16 | (byteData[i] & 0x0000FF00) | (byteData[i] & 0x00FF0000) >> 16 | (byteData[i] & 0xFF000000);
		    }

Em baixo apresento os dois métoos completos.

private void device_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
    {
	    image = eventArgs.Frame.Clone(Rec, PixelFormat.Format8bppIndexed);
	    MoveTowards moveTowardsFilter = new MoveTowards();
	    Difference differenceFilter = new Difference();
	    IFilter thresholdFilter = new Threshold(15);
	    if (backgroundFrame == null)
	    {
		    backgroundFrame = processingFilter1.Apply(image);
		    width = image.Width;
		    height = image.Height;
		    return;
	    }
	    processingFilter1.Add(new Difference(backgroundFrame));
	    processingFilter1.Add(new Threshold(15));
	    processingFilter1.Add(new Opening());
	    processingFilter1.Add(new Edges());
	    tmpImage = processingFilter1.Apply(image);
	    if (++counter == 2)
	    {
		    counter = 0;
		    moveTowardsFilter.OverlayImage = tmpImage;
		    moveTowardsFilter.ApplyInPlace(backgroundFrame);
	    }
	    differenceFilter.OverlayImage = backgroundFrame;
	    bitmapData = tmpImage.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
	    differenceFilter.ApplyInPlace(bitmapData);
	    thresholdFilter.Apply(bitmapData);
	    blobCounter.ProcessImage(bitmapData);
	    System.Drawing.Rectangle[] rects = blobCounter.GetObjectsRectangles();
	    Graphics g = Graphics.FromImage(image);
	    using (Pen pen = new Pen(System.Drawing.Color.Red, 1))
	    {
		    foreach (System.Drawing.Rectangle rc in rects)
		    {
			    g.DrawRectangle(pen, rc);
			    if ((rc.Width > 15) && (rc.Height > 15))
			    {
				    //Para os retângulos maiores
			    }
		    }
	    }
	    g.Dispose();
    }

private Texture2D GetTexture(GraphicsDevice dev, System.Drawing.Bitmap bmp)
    {
	    int[] imgData = new int[bmp.Width * bmp.Height];
	    Texture2D texture = new Texture2D(dev, bmp.Width, bmp.Height);
	    unsafe
	    {
		    // lock bitmap
		    System.Drawing.Imaging.BitmapData origdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
		    uint* byteData = (uint*)origdata.Scan0;
		    // Switch bgra -> rgba
		    for (int i = 0; i < imgData.Length; i++)
		    {
			    byteData[i] = (byteData[i] & 0x000000ff) << 16 | (byteData[i] & 0x0000FF00) | (byteData[i] & 0x00FF0000) >> 16 | (byteData[i] & 0xFF000000);
		    }
		    // copy data
		    System.Runtime.InteropServices.Marshal.Copy(origdata.Scan0, imgData, 0, bmp.Width * bmp.Height);
		    byteData = null;
		    // unlock bitmap
		    bmp.UnlockBits(origdata);
	    }
	    texture.SetData(imgData);
	    return texture;
    }
Link to comment
Share on other sites

já não pego no c# prai a .... que tempos

mas parece que o teu problema está aqui

image = eventArgs.Frame.Clone(Rec, PixelFormat.Format8bppIndexed);

em cada frame estás a criar uma cópia do frame mas (talvez, porque o C# funciona com garbage collection) deverás "libertar" isso

isto porque se em cada frame tem um memory leak deste tamanho a tua excepção não demora nada a aparecer

IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Para quem estiver curioso, já consegui resolver o problema, o problema estava nos PixelFormat, Aqui vai o código:

tmpImage = eventArgs.Frame.Clone(Rec, PixelFormat.Format24bppRgb);
	    Bitmap image = (Bitmap)tmpImage.Clone();
				    Threshold filter2 = new Threshold(200);
	    Invert invert = new Invert();
	    Bitmap grayImage = Grayscale.CommonAlgorithms.BT709.Apply(image);
	    invert.ApplyInPlace(grayImage);
	    filter2.ApplyInPlace(grayImage);
	    try
	    {
		    blobCounter.ProcessImage(grayImage);
	    }
	    catch
	    {
	    }
				    Graphics g = Graphics.FromImage(tmpImage);
	    blobCounter.MinHeight = 40;
	    blobCounter.MinWidth = 40;
	    blobCounter.ObjectsOrder = ObjectsOrder.Area;
	    System.Drawing.Rectangle[] rects = blobCounter.GetObjectsRectangles();
	    Pen pen = new Pen(System.Drawing.Color.Red, 1);
	    using (pen)
	    {
		    foreach (System.Drawing.Rectangle rc in rects)
		    {
			    g.DrawRectangle(pen, rects[0].X, rects[0].Y, rects[0].Width, rects[0].Height);
			    g.DrawRectangle(pen, rects[1].X, rects[1].Y, rects[1].Width, rects[1].Height);
		    }
	    }
	    g.Dispose();
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.