【发布时间】:2018-10-20 00:58:19
【问题描述】:
我启动从 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.
}
U P D A T E : 我将内存泄漏的原因缩小到这一行:
image_rotator_RotateBilinear.Apply( camera_frame_Bitmap )); /////////// 2ND BITMAP BUFFER /////////////
【问题讨论】:
-
你在哪里清理你以前的位图?
Bitmap是一次性的,创建新的时候需要去掉之前的图片。 -
与 ... latest_frame_buffer_Bitmap.Dispose();和 camera_buffer_Bitmap.Dispose();
-
好吧,也许我错过了那些。为什么你把你的截图称为内存泄漏?似乎内存会上升一点,然后循环回收。它真的会随着时间的推移而不断增加吗? (很难从屏幕截图中分辨出峰值。)
-
xxbbcc:那么,那只是一种垃圾收集模式?
-
对不起,我直到现在才看到你的评论。是的,根据您的屏幕截图,这似乎是一种 GC 模式。如果峰值随着时间的推移越来越高,则表明存在内存泄漏。
标签: c# .net image image-processing bitmap