我的应用程序正在使用WPF Control显示来自网络摄像头的许多视频。
摘要代码位于
之下public void DisPlayVideoThreadProc()
{
while (isDisplayThreadRunning)
{
Global.mainWindow.Dispatcher.Invoke(new Action(delegate()
{
for (int i = 0; i < numOfCamera; i++)
{
BitmapSource img = bitmapQueue[i].Serve(); //Pop the frame from Queue
ControlDisplay[i].DrawImage(img); //Draw this frame on ControlDisplay[i]
}
}));
}
}
当相机数量很大(> 15相机)时遇到问题,那么UI线程对用户的交互来说非常慢。
我知道显示许多摄像机视频时UI线程很重要。但我不知道如何改进它。有人可以告诉我,如何解决这个问题。
非常感谢!
答案 0 :(得分:0)
不要在一次调用中绘制所有相机。这将阻止gui线程太长时间。你最好每次摄像头调用调用。或至少最多4批次。
您可以将Serve()
方法从调用中移出并将其存储在字典中并使用DispatcherTimer进行更新。
<强>伪:强>
// hold the camera images.
public class CameraImage
{
public bool Updated {get; set; }
public BitmapSource Image {get; set; }
}
// cache
private Dictionary<int, CameraImage> _cameraCache = new Dictionary<int, CameraImage>();
// thread method to get the images.
while (isDisplayThreadRunning)
{
for (int i = 0; i < numOfCamera; i++)
{
BitmapSource img = bitmapQueue[i].Serve(); //Pop the frame from Queue
lock(_cameraCache)
{
CameraImage currentCameraImage;
if(!_cameraCache.TryGetValue(i, out currentCameraImage))
{
_cameraCache.Add(i, currentCameraImage = new CameraImage());
}
currentCameraImage.Image = img;
currentCameraImage.Updated = true;
}
}
}
// index cycler
private int _index;
// display timer.
public void DispatcherTimeMethod()
{
lock(_cameraCache)
{
CameraImage currentCameraImage;
if(_cameraCache.TryGetValue(_index, out currentCameraImage))
if(currentCameraImage.Updated)
{
ControlDisplay[_index].DrawImage(currentCameraImage.Image);
currentCameraImage.Updated = false;
}
}
_index++;
if(_index >= MAXCAMERAS)
_index = 0;
}
如果相机(全部在一起)将生成太多图像,它将自动跳过图像。
答案 1 :(得分:0)
目前,您正在一个线程(UI线程)中更新所有相机。这使得UI线程始终冻结,即使您没有注意到它。
我建议使用Parallel.For来更新(多个)单独线程上的摄像头,然后使用UI调度程序更新UI上的图像。
这样的事情:
while ( isDisplayThreadRunning ) {
//start a new parallel for loop
Parallel.For( 0, numOfCamera, num => {
BitmapSource img = bitmapQueue[i].Serve(); //Pop the frame from Queue
//draw the new image on the UI thread
Global.mainWindow.Dispatcher.Invoke(
new Action( delegate
{
ControlDisplay[i].DrawImage( img ); //Draw this frame on ControlDisplay[i]
} ) );
} );
Thread.Sleep( 50 );//sleep if desired, lowers CPU usage by limiting the max framerate
}
}