Я работаю в течение нескольких недель, захватывая изображение веб-камеры и визуализируя его на форме окна, но все время боролся с проблемами скорости. Мне нужно, по крайней мере, частоту кадров 10 Гц, чтобы обновлять фоновый процесс.Рендеринг растрового изображения с XNA медленно при захвате изображения с веб-камеры, почему?
Я начал использовать pictureBox, но решение, с которым я столкнулся, заключается в создании XNA-панели внутри моей Формы, а затем рендеринг изображения в качестве фонового-спрайта путем преобразования растрового изображения в Texture2D с использованием сценария Я нашел здесь.
Проблема, с которой я столкнулся сейчас, и не смог ее решить; когда я загружаю Bitmap в код, вызывая конструктор растрового изображения, как показано ниже, все выполняется гладко, и я могу получить высокий fps. Это то, что я делал во время тестирования, и был очень доволен результатами.
Bitmap image = new Bitmap(320, 240);
Но как только я посылаю точечный рисунок, который я захватить с веб-камеры она занимает гораздо больше времени, чтобы сделать по каким-то причинам я не могу понять. Насколько мне известно, растровые изображения имеют одинаковый формат, это только цвет пикселей, которые отличаются друг от друга. То, что я проверил для формата, - это размер (320 * 240), разрешение (96) и формат пикселей (Format32bppArgb). Я что-то пропустил?
Это, как я захватить изображение с веб-камеры:
VideoCaptureDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
FinalVideoSource = new VideoCaptureDevice(VideoCaptureDevices[0].MonikerString);
FinalVideoSource.DesiredFrameSize = new Size(320, 240);
FinalVideoSource.DesiredFrameRate = fps;
FinalVideoSource.NewFrame += new NewFrameEventHandler(FinalVideoSource_NewFrame);
void FinalVideoSource_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
// create bitmap from frame
image = eventArgs.Frame.Clone(new Rectangle(0, 0, 320, 240), PixelFormat.Format32bppArgb);
...
Это моя функция втягивания XNA:
protected override void Draw()
{
backTexture = GetTexture(GraphicsDevice, image);
GraphicsDevice.Clear(Microsoft.Xna.Framework.Color.CornflowerBlue);
// TODO: Add your drawing code here
sprites.Begin();
Vector2 pos = new Vector2(0, 0);
sprites.Draw(backTexture, pos, Microsoft.Xna.Framework.Color.White);
sprites.End();
}
private Texture2D GetTexture(GraphicsDevice dev, System.Drawing.Bitmap bmp)
{
int[] imgData = new int[bmp.Width * bmp.Height];
Texture2D texture = new Texture2D(dev, bmp.Width, bmp.Height);
unsafe
{
// lock bitmap
System.Drawing.Imaging.BitmapData origdata =
bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
uint* byteData = (uint*)origdata.Scan0;
// Switch bgra -> rgba
for (int i = 0; i < imgData.Length; i++)
{
byteData[i] = (byteData[i] & 0x000000ff) << 16 | (byteData[i] & 0x0000FF00) | (byteData[i] & 0x00FF0000) >> 16 | (byteData[i] & 0xFF000000);
}
// copy data
System.Runtime.InteropServices.Marshal.Copy(origdata.Scan0, imgData, 0, bmp.Width * bmp.Height);
byteData = null;
// unlock bitmap
bmp.UnlockBits(origdata);
}
texture.SetData(imgData);
return texture;
}
Я был бы очень признателен, если кто-то может мне помочь с этим, так как Я застрял сейчас. Сообщество здесь было замечательно, и мне удалось получить это далеко, не спрашивая раньше, что удивительно, поскольку у меня нет опыта в C# или XNA. Имея это в виду, я понимаю, что я могу пропустить что-то простое или просто подойти к этому неправильно.
Я сузил его до загрузки растрового изображения. Единственное, что я могу изменить при использовании недавно построенного растрового изображения, - это просто перезаписать его с веб-камеры перед его обработкой в XNA.
Мой вопрос прямо сейчас, я пропустил что-то с тем, как построены растровые изображения, которые могут объяснить большую разницу в скорости рендеринга? Является ли преобразование в Texture2D проблемой здесь? Но я не вижу, как другое изображение может повлиять на скорость этого преобразования.
LOL, я просто заметил, что этот вопрос задавали в марте. – EdgarT