私は数週間、ウェブカメラの画像を取得して Windows フォームにレンダリングする作業を行ってきましたが、ずっと速度の問題に苦しんでいました。バックグラウンド プロセスを更新するには、少なくとも 10 Hz のフレーム レートが必要です。
私はpictureBoxの使用を開始しましたが、最終的な解決策は、フォーム内にXNAパネルを作成し、ここで見つけたスクリプトを使用してビットマップをTexture2Dに変換することにより、画像を背景スプライトとしてレンダリングすることです。
私が今遭遇し、解決できなかった問題は次のとおりです。以下のようにビットマップコンストラクターを呼び出してコードにビットマップをロードすると、すべてがスムーズに実行され、高い 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 で処理する前に Web カメラからのビットマップを単純に上書きすることです。
今の私の質問は、レンダリング速度の大きな違いを説明できるビットマップの構築方法に何か欠けているのでしょうか? Texture2D への変換はここで問題ですか? しかし、別の画像がその変換速度にどのように影響するかはわかりません。