2013-04-15 26 views
9

Ok, tôi đã cố gắng làm điều gì đó cụ thể với nguồn cấp dữ liệu video từ một webcam. Tôi có một kính hiển vi Lumenera Infinity 2 mà tôi đang cố kéo nguồn cấp dữ liệu và muốn có thể sửa đổi nguồn cấp dữ liệu khi nó xuất hiện. Vì tôi không thể tìm cách làm điều đó bằng Trình phát Video nguồn, tôi đã quyết định thay thế kéo từng khung hình (tối đa 15 khung hình/giây cho máy ảnh) dưới dạng bitmap để tôi có thể thực hiện các sửa đổi ở đó.Rò rỉ bộ nhớ trong mã webcam

Vấn đề là: Tôi bị rò rỉ bộ nhớ HUGE. Khi tôi chạy video chỉ bằng cách sử dụng videoSourcePlayer, nó di chuyển với khoảng 30 meg. Khi tôi chạy kéo khung như bitmap, nó sẽ phá vỡ 1 gig bộ nhớ chỉ trong vài giây.

Tôi đang thiếu gì ở đây? Tôi đã tìm thấy bộ sưu tập rác tự động sẽ lấy các khung cũ khi chúng không thể truy cập được. Tôi có nên thử bắt buộc thu gom rác trên bitmap không? Hay nó là cái gì khác hoàn toàn và tôi noobishly thiếu nó.

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; 
} 
+8

'Bitmap' là' IDisposable' – I4V

+0

Chỉ cần đoán nhanh: Có thể sự kiện Xử lý khung hình mới? nó nhân bản một khung hình, bao nhiêu lần và sự kiện này được gọi là bao nhiêu lần? – Max

+0

Tôi giả định ở mỗi khung hình, do đó, tối đa (dựa trên phần cứng) 15 lần mỗi giây. Tôi sẽ kiểm tra và đảm bảo rằng mặc dù –

Trả lời

2

Hãy thử điều này:

Nó giải quyết một số các lỗ hổng bộ nhớ tôi có kinh nghiệm với Aforge và PictureBoxes, nhưng VideoSourcePlayer là tốt hơn nhiều nơi tiêu thụ bộ nhớ là có liên quan.

+0

Tuyệt vời! Điều đó sẽ giúp một bó! Tôi đang chạy vào một vấn đề với nó, mặc dù- nhận được một lỗi thread chéo trên videoPictureBox1.Image.Dispose(). "Thao tác chéo không hợp lệ: Kiểm soát 'videoPictureBox1' được truy cập từ một chuỗi khác với chuỗi được tạo trên đó." –

+0

Bạn có gặp phải vấn đề đó khi bạn đang làm việc với điều này không? –

+0

ah đúng rồi, bạn cần sử dụng Gọi. Tôi đã chỉnh sửa câu trả lời của tôi, vì vậy nó sẽ sửa chữa các lỗi thread chéo. –

2

Tôi nghĩ rằng đây là một trong những khu vực đó có thể sử dụng cải thiện:

cam = new 
    VideoCaptureDevice(captureDevices[CameraSelectComboBox.SelectedIndex].MonikerString); 

cam.NewFrame -= Handle_New_Frame; // you're pointing to the new instance of VCD, so this will have no effect. 

cam.NewFrame += new AForge.Video.NewFrameEventHandler(Handle_New_Frame); 
videoSourcePlayer1.Visible = false; 
cam.Start(); 

Đó khối mã được chảy máu bộ nhớ mỗi khi bạn nhấn vào nút kết nối.

Bạn cần có tham chiếu đến VCD ở cấp chính. Vì vậy, định nghĩa một biến thành viên tại Form1 lớp trình độ:

private VideoCaptureDevice _cameraContext; 

Và trong xử lý sự kiện kết nối, làm việc này:

if (_camerContext != null) 
{ 
    _cameraContext.NewFrame -= Handle_New_Frame; 
} 
_cameraContext = new VideoCaptureDevice(blah blah blah); 
_cameraContext.NewFrame += Handle_New_Frame; 
videoSourcePlayer1.Visible = false; 
_cameraContext.Start(); 

BTW, tôi giả sử bạn đang NET 3.5 hoặc mới hơn, do đó cú pháp gán ủy nhiệm mới.

+0

Lưu ý: đây chỉ là _one_ khu vực mã mà tôi thấy một sự rò rỉ rõ ràng. Xem xét rằng rò rỉ bộ nhớ là đáng kể, bạn cũng nên xem cách bitmap đang được xử lý. – code4life

+0

Tuyệt vời! Cảm ơn một bó cho thông tin đó. Và vâng, giả định của bạn là đúng - Tôi đang sử dụng 4.5 –