2016-08-09 4 views
1

Ich mache einige Tests mit AForge-Bibliothek. Ich versuche, Daten von meiner USB-Kamera (Frames) zu lesen. Es funktioniert sehr gut, aber das einzige Problem ist der RAM. Es leckt. Es scheint, dass ein Frame ~ 30 KB benötigt, aber der verwendete Speicher nimmt weiter zu.RAM-Auslastung steigt beim Lesen von Frames von der Kamera

Hier ist mein Code:

Imports AForge 
Imports AForge.Controls 
Imports AForge.Video 
Imports AForge.Video.DirectShow 
Imports System.Threading 
Imports System.IO 
Imports System.Collections.Concurrent 
Imports System.ComponentModel 

Public Class Form1 
    Dim sources As New FilterInfoCollection(FilterCategory.VideoInputDevice) 
    Dim WithEvents device As VideoCaptureDevice 
    Dim count As Long, bit As Bitmap 
    Dim read As New Thread(AddressOf read_que) 
    Dim pic_que As New ConcurrentQueue(Of Bitmap) 


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
     For Each cam As FilterInfo In sources 
      ComboBox1.Items.Add(cam.Name) 
     Next 
    End Sub 

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     device = New VideoCaptureDevice(sources(ComboBox1.SelectedIndex).MonikerString) 
     AddHandler device.NewFrame, new Video.NewFrameEventHandler(AddressOf frame) 

     device.WaitForStop() 
     device.Start() 
    End Sub 

    Sub frame(obj As Object, args As NewFrameEventArgs) 
     If bit IsNot Nothing Then 
      bit.Dispose() 
      bit = Nothing 
     End If 
     bit = New Bitmap(args.Frame) 

     If PictureBox1.Image IsNot Nothing Then 
      PictureBox1.Invoke(New MethodInvoker(Sub() PictureBox1.Image.Dispose())) 
     End If 

     PictureBox1.Image =bit ' or ... = Imaging.Image.Clone(args.Frame) 

    End Sub 
End Class 

Ich habe sogar versucht, alle Frames in einer gleichzeitigen Warteschlange zu setzen und dann in einem separaten Thread, es zu lesen (ich das vereinfachte Version geschrieben, die am wenigsten RAM-Speicher zu nehmen scheint). Aber es gibt ein anderes Problem (das ist nicht so wichtig): wenn ich die App starte, ist die Bildbox leer und der verwendete RAM ist 16 MB (konstant - also funktioniert es nicht).

Nur wenn ich den Task-Manager betrete und auf End Process drücke (ohne es zu schließen), werden die Frames angezeigt. Ich denke, es ist GUI-bezogen (wenn ich den End-Prozess drücke, löst es vielleicht ein Ereignis aus, das die Frame-Leseklasse startet?). enter image description here

nur zu zufälligen Zeiten scheint es, von der ersten Zeit zu arbeiten (es ist wahr, dass es vielleicht die Kamera Problem sein, weil es alt und nur auf XP so hatte ich funktioniert .NET Framework 4 verwenden).

Wo ist das Problem (die Priorität ist die Ramme Leckage)?

+0

Ist das Gerät jenes 'NewFrameEvents' auf einem anderen Thread erhöhen? Sieht so aus, als würdest du den auswählen, also tun sie das alle? Wenn Sie uns aufrufen, ein altes Bild zu löschen, warum legen Sie das neue Bild direkt fest? Es sieht nicht aus wie Option Strict verwendet wird. – Plutonix

+1

Coud das Problem damit nicht verursacht wird durch den Aufruf device.WaitForStop() verursacht. – FloatingKiwi

+0

@Plutonix hat recht, wenn mit dem Threading etwas nicht stimmt. Entsorgen Sie die Bitmap nur im ui-Thread, damit Sie sicher sein können, dass sie in diesem Moment nicht von der Bildbox gerendert wird. Sie können auch überprüfen, ob args.Frame entsorgt werden muss. – FloatingKiwi

Antwort

0

es gelöst. Danke für all deine Hilfe, aber ich wusste, dass mein Code funktionierte (ich benutzte vor einem Delegierten, um auf Bildbox zu zeichnen, so dass es threadsicher war - der Code, den ich zur Verfügung stellte, war "schnell und schmutzig"). Das Problem war ... die VM. Ich habe den Code auf einer VM getestet. Es funktioniert auf einem normalen PC.

Der Code sieht nun wie folgt aus:

Imports AForge 
Imports AForge.Controls 
Imports AForge.Video 
Imports AForge.Video.DirectShow 
Imports System.Threading 
Imports System.IO 
Imports System.Collections.Concurrent 
Imports System.ComponentModel 

Public Class Form1 
    Dim sources As New FilterInfoCollection(FilterCategory.VideoInputDevice) 
    Dim device As VideoCaptureDevice 
    Delegate Sub lp(ByRef pic As Bitmap) 
    Delegate Sub lpp(nr As Integer, nr2 As Integer) 
    Delegate Sub slp() 
    Dim count As Long, bit As Bitmap 
    Dim read As New Thread(AddressOf read_que) 
    Dim pic_que As New ConcurrentQueue(Of Bitmap) 


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
     For Each cam As FilterInfo In sources 
      ComboBox1.Items.Add(cam.Name) 
     Next 
    End Sub 

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     device = New VideoCaptureDevice(sources(ComboBox1.SelectedIndex).MonikerString) 
     AddHandler device.NewFrame, new Video.NewFrameEventHandler(AddressOf frame) 

     'device.WaitForStop() 
     device.Start() 

     'read.IsBackground = True 
     'read.Start() 
    End Sub 

    Sub frame(obj As Object, args As NewFrameEventArgs) 
     'If bit IsNot Nothing Then 
     ' bit.Dispose() 
     ' bit = Nothing 
     'End If 
     'bit = New Bitmap(args.Frame) 

     If PictureBox1.Image IsNot Nothing Then 
      PictureBox1.Invoke(New MethodInvoker(Sub() PictureBox1.Image.Dispose())) 
     End If 

     PictureBox1.Invoke(New MethodInvoker(Sub() PictureBox1.Image = Imaging.Image.Clone(args.Frame))) 'Imaging.Image.Clone(args.Frame) ' or ...=bit 
    End Sub 
End Class 
1

Versuchen Sie dies mit:

Sub frame(obj As Object, args As NewFrameEventArgs) 
    If Me.InvokeRequired Then 
     Me.BeginInvoke(Sub() frame(obj, args)) 
    Else 
     Dim oldImage = PictureBox1.Image 

     Dim bitmap = New Bitmap(args.Frame) 
     args.Frame.Dispose() 'Not sure if it has a Dispose 
     PictureBox1.Image = bitmap 

     If oldImage IsNot Nothing Then oldImage.Dispose() 

    End If 
End Sub 
+1

Wenn 'args.Frame' verwendet werden kann, um ein neues Bild zu erstellen, müsste es sicher entsorgt werden. Das OP hat anscheinend die Bedeutung von UpVotes ("nützlich, hilfreich") vergessen, obwohl sie 2 von Ihnen angebotene Schlüsselelemente verwenden, also +1, da sie nicht belästigt werden können – Plutonix

Verwandte Themen