Jump to content

Recommended Posts

Posted

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;
    }
Posted

As excepções do tipo System out of memory exception não são disparadas em nenhuma linha específica, são disparadas quando o pc fica sem recursos de memória.

Tenta rever o código para ver se podes ir libertando recursos à medida que não são precisos...

Posted

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
Posted

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();

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.