参与生活
本文关键字:生活 | 更新日期: 2023-09-27 18:14:14
我使用佳能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上大约需要300ms。当然,对于流畅的直播来说,这还不够快。
我有哪些优化选项?是否有机会使用gpu功能?什么是机会?我不能使用DirectShow佳能相机(没有驱动程序存在)
-
GetPixel/SetPixel
不知道你的环境(我不写c#代码),但这些函数在所有环境中都慢得令人痛苦。位图通常有如下替代方案:
-
ScanLines[]()
-
LockBits/UnlockBits
在c#中直接访问像素
-
-
图像采集
再次,我不知道SDK您正在使用的不是您需要的目标fps,但有可能您的SDK流很慢,而不仅仅是您的应用程序。DirectShow可以为您提供
30 fps
左右的较低分辨率。然而,我注意到,对于更大的分辨率,它比VFW慢,但它可能与USB有关,而不是流媒体和驱动程序本身。由于您没有DirectShow驱动程序,您就不走运了。如果你有VFW驱动程序,那么你可以使用它,但它通常只能给你15 fps
,但代码明显更简单,CPU要求更少。Btw一些驱动程序有能力设置fps流(或时间间隔),所以搜索你的SDK这样的功能或令牌也许你只是有低fps默认设置。
也尝试使用不同的USB(如果使用USB连接)一些USB可以有带宽已经被其他设备带走(理想情况下,在整个根HUB上使用单个相机进行测试)。
要检测哪一个是问题,计数fps,而没有像素被传输或查看(只是rem所有图像相关代码和测量只是偶数发生)。如果收购是快速的,那么驱动程序就不是问题。然后测量传输速度,如果传输速度太慢,代码也是一个问题。