我使用佳能EOS SDK并希望通过相机流实现实时绿屏。
我有一个简单的绿屏算法,带有像素操作优化。
public Bitmap greenScreen(Bitmap input, int tolerance)
{
FastPixel fpinput = new FastPixel(input);
fpinput.Lock();
Bitmap output = new Bitmap(input.Width, input.Height);
FastPixel fpoutput = new FastPixel(output);
fpoutput.Lock();
for (int y = 0; y < output.Height; y++)
{
for (int x = 0; x < output.Width; x++)
{
Color camColor = fpinput.GetPixel(x, y);
// Every component (red, green, and blue) can have a value from 0 to 255, so determine the extremes
byte max = Math.Max(Math.Max(camColor.R, camColor.G), camColor.B);
byte min = Math.Min(Math.Min(camColor.R, camColor.G), camColor.B);
bool replace =
camColor.G != min // green is not the smallest value
&& (camColor.G == max // green is the bsiggest value
|| max - camColor.G < 8) // or at least almost the biggest value
&& (max - min) > tolerance; // minimum difference between smallest/biggest value (avoid grays)
if (!replace)
fpoutput.SetPixel(x, y, camColor);
}
}
fpinput.Unlock(true);
fpoutput.Unlock(true);
return fpoutput.Bitmap;
}
对于800x600图片,我的i5需要大约300毫秒。当然,这对于流畅的直播来说还不够快。
我有哪些优化选项?有没有机会使用gpu功能?什么是机会?我不能将DirectShow与佳能相机一起使用(不存在驱动程序)
答案 0 :(得分:2)
<强> GetPixel/SetPixel
强>
不了解您的环境(我不使用C#编写代码),但这些功能在所有环境中都会痛苦地缓慢。通常有位图的替代品,如:
ScanLines[]()
LockBits/UnlockBits
图片获取
我再次不知道您正在使用的 SDK ,也不知道您需要的目标fps,但您的 SDK 流式传输可能很慢而且不仅仅是您的应用。 DirectShow 可为您提供30 fps
左右的较低分辨率。但是我注意到,对于更大的分辨率,它比 VFW 慢,但它可能与 USB 有关,而不是与流和驱动程序本身有关。由于你没有 DirectShow 驱动程序,你运气不好。如果您有 VFW 驱动程序,那么您可以使用它,但它通常只能提供15 fps
,但代码要简单得多,而且 CPU 要求不高。< / p>
顺便说一下,某些驱动程序可以设置 fps 进行流式传输(或时间间隔),因此请搜索 SDK 以获取此类功能或令牌,可能只是 fps 默认设置。
另外尝试使用不同的 USB (如果使用USB连接),某些USB可能已经被其他设备带走了带宽(理想情况下在整个根HUB上使用单个摄像头进行测试)。
要检测哪一个是问题,请计算 fps ,而不会传输或查看像素(只需重新调整所有与图像相关的代码并仅测量偶数事件)。如果收购速度很快,那么驱动程序不是问题。然后使用传输进行测量,如果速度过慢则代码也是一个问题。