9

わかりました、ウェブカメラからのビデオ フィードで特定のことをしようとしています。フィードを取り込もうとしている Lumenera Infinity 2 顕微鏡があり、入ってくるフィードを変更できるようにしたいと考えています。Video Source Player を使用してそれを行う方法が見つからなかったため、代わりに使用することにしました各フレーム (カメラの場合は最大 15 fps) をビットマップとしてプルして、そこで変更を行うことができます。

問題は次のとおりです。大量のメモリ リークがあります。videoSourcePlayer だけを使用してビデオを実行すると、約 30 メガを使用して停止します。フレームをビットマップとしてプルすると、数秒で 1 ギガのメモリが壊れます。

ここで何が欠けていますか?自動ガベージ コレクションは、アクセスできなくなった古いフレームをすくい上げると考えました。ビットマップでガベージ コレクションを強制する必要がありますか? それとも、それはまったく別のものであり、私はそれを見逃しています。

FilterInfoCollection captureDevices;
VideoCaptureDevice cam;
Bitmap bitmap;

public Form1()
{
  InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
  try
  {
    captureDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);

    if (captureDevices.Count == 0)
      throw new ApplicationException();

    CameraSelectComboBox.Items.Clear();

    foreach (FilterInfo device in captureDevices)
    {
      CameraSelectComboBox.Items.Add(device.Name);
    }

    CameraSelectComboBox.SelectedIndex = 0;
    CameraSelectComboBox.Enabled = true;
  }
  catch (ApplicationException)
  {
    CameraSelectComboBox.Enabled = false;
  }
}

private void connectButton_Click(object sender, EventArgs e)
{
  cam = new VideoCaptureDevice(captureDevices[CameraSelectComboBox.SelectedIndex].MonikerString);
  cam.NewFrame -= Handle_New_Frame; //Just to avoid the possibility of a second event handler being put on
  cam.NewFrame += new AForge.Video.NewFrameEventHandler(Handle_New_Frame);
  videoSourcePlayer1.Visible = false;
  cam.Start();

  //videoPictureBox1.Visible = false;
  //videoSourcePlayer1.VideoSource = new VideoCaptureDevice(captureDevices[CameraSelectComboBox.SelectedIndex].MonikerString);
  //videoSourcePlayer1.Start();
}

private void Handle_New_Frame(object sender, NewFrameEventArgs eventArgs)
{
  bitmap = (Bitmap)eventArgs.Frame.Clone();

  videoPictureBox1.Image = bitmap;
}
4

2 に答える 2

2

これを試して:

private void Handle_New_Frame(object sender, NewFrameEventArgs eventArgs)
{
    if(bitmap != null)
        bitmap.Dispose();
    bitmap = new Bitmap(eventArgs.Frame);

    if(videoPictureBox1.Image != null)
        this.Invoke(new MethodInvoker(delegate() {videoPictureBox1.Image.Dispose();}));
    videoPictureBox1.Image = bitmap;
}

Aforge と PictureBoxes で経験したメモリ リークの一部は解決されましたが、メモリ消費に関しては、VideoSourcePlayer の方がはるかに優れています。

于 2013-04-15T14:29:29.380 に答える