[英]C# memory leak after inputing and rotating image Bitmap from USB camera
我啟動將圖像從USB攝像機下載到C#Windows應用程序的步驟:(使用Accord(即AForge)的VideoCaptureDevice)
// Automatically start inputing each frame from camera:
var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
// Select physical USB camera: http://accord-framework.net/docs/html/T_Accord_Video_DirectShow_VideoCaptureDevice.htm
videoSource = new VideoCaptureDevice( videoDevices[0].MonikerString, pixelFormat_for_ExhaustiveTemplateMatching);
// Select event handlers:
videoSource.NewFrame += new NewFrameEventHandler( EVENT_camera_frame ); //http://accord-framework.net/docs/html/T_Accord_Video_NewFrameEventArgs.htm
// Start slurpin up them camera frames:
videoSource.Start();
然后,我處理包含相機下一個圖像幀的每個事件:
private static void EVENT_camera_frame(object sender, NewFrameEventArgs camera_frame_event)
{
if( latest_frame_buffer_Bitmap != null )
{
latest_frame_buffer_Bitmap.Dispose();
}
// Allocate camera Bitmap buffer:
camera_buffer_Bitmap = new Bitmap(
// ..rotate and copy raw camera frame image bitmap from camera_frame_Bitmap to camera_buffer_Bitmap:
image_rotator_RotateBilinear.Apply( camera_frame_Bitmap )); /////////// 2ND BITMAP BUFFER /////////////
// Init a Bitmap for size of frame from camera and for conversion from camera native pixel format to comparison compatible format Format24bppRgb:
latest_frame_buffer_Bitmap = new Bitmap( camera_frame_Bitmap.Width,
camera_frame_Bitmap.Height,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
// From rotated, camera format image bitmap in camera_frame_Bitmap, convert to Format24bppRgb and copy to latest_frame_buffer_Bitmap:
using (Graphics gr = Graphics.FromImage( latest_frame_buffer_Bitmap))
{
gr.DrawImage( camera_buffer_Bitmap, new Rectangle(0, 0,
latest_frame_buffer_Bitmap.Width,
latest_frame_buffer_Bitmap.Height));
camera_buffer_Bitmap.Dispose();
// Draw crop rectangle in Live Camera View:
using( Graphics live_image_Graphics = Graphics.FromImage( latest_frame_buffer_Bitmap ) )
{
live_image_Graphics.DrawRectangle( crop_pen, crop_display_rectangle ); ///////////// DRAW CROPPING RECTANGLE /////////////
}
// Show crop rectangle in PictureBox of Live Camera View:
control_panel.show_camera_crosshairs();
}
camera_frame_Bitmap.Dispose(); // I just tried this, but didn't fix the leak.
}
然后,我執行.BeginInvoke以“計划” UI線程來更新PictureBox:
public void show_camera_crosshairs()
{
// Show crosshairs, if requested in camera view:
// Create pen.
Pen crosshairs_pen = new Pen(Color.White, 1 );
int width = Computer_Vision_API.latest_frame_buffer_Bitmap.Width;
int height = Computer_Vision_API.latest_frame_buffer_Bitmap.Height;
int top_y = height - 1;
int bottom_y = 0;
int left_x = 0;
int right_x = width - 1;
// Create points that define line.
Point crosshair_point_top = new Point( width / 2, top_y );
Point crosshair_point_bottom = new Point( width / 2, bottom_y );
Point crosshair_point_left = new Point( 0, height / 2 );
Point crosshair_point_right = new Point( width-1, height / 2 );
float[] dashValues = { 4, 2 };
crosshairs_pen.DashPattern = dashValues;
// Verticle crosshair:
Graphics live_image_Graphics = Graphics.FromImage( Computer_Vision_API.latest_frame_buffer_Bitmap );
live_image_Graphics.DrawLine( crosshairs_pen, crosshair_point_top, crosshair_point_bottom );
// Horizontal crosshair:
live_image_Graphics.DrawLine( crosshairs_pen, crosshair_point_left, crosshair_point_right );
live_image_Graphics.Dispose();
// Display latest frame from camera:
Common.dbg("","","BeginInvoke: update_PictureBox");
PictureBox_live_camera.BeginInvoke( new update_PictureBox_Delegate( update_PictureBox ));
}
最后,我有UI線程更新PictureBox ...
public delegate void update_PictureBox_Delegate( );
public void update_PictureBox()
{
Common.dbg("","","");
Computer_Vision_API.computer_vision_resource.WaitOne();
Common.dbg("","","computer_vision_resource");
PictureBox_live_camera.Image = Computer_Vision_API.latest_frame_buffer_Bitmap;
PictureBox_live_camera.BackgroundImage = Computer_Vision_API.latest_frame_buffer_Bitmap;
Computer_Vision_API.computer_vision_resource.ReleaseMutex(); // release use of computer vision Bitmap buffers, etc.
}
更新:我將內存泄漏的原因縮小到以下這一行:
image_rotator_RotateBilinear.Apply( camera_frame_Bitmap )); /////////// 2ND BITMAP BUFFER /////////////
問題不在代碼中。 這是我對Diag Tool(上面的圖)顯示的內存模式的誤解。 盡管在幾個事件回調中使用的內存有所增加,但是智能垃圾收集器不會自動處理每個回調。
感謝xxbbcc的啟發性評論。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.