我开始使用EmguCV,但我偶然发现尝试从抓取器的位图转换为Texture2D的性能问题
这是我的代码
private void FrameGrabber()
{
NamePersons.Add("");
currentFrame = grabber.QueryFrame().Resize(320, 240, INTER.CV_INTER_CUBIC);
gray = currentFrame.Convert<Gray, Byte>();
MCvAvgComp[][] facesDetected = gray.DetectHaarCascade(face, 1.2, 10, HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, new Size(20, 20));
foreach (MCvAvgComp f in facesDetected[0])
{
t = t + 1;
result = currentFrame.Copy(f.rect).Convert<Gray, byte>().Resize(100, 100, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
currentFrame.Draw(f.rect, new Bgr(System.Drawing.Color.Red), 2);
if (trainingImages.ToArray().Length != 0)
{
MCvTermCriteria termCrit = new MCvTermCriteria(ContTrain, 0.001);
EigenObjectRecognizer recognizer = new EigenObjectRecognizer(trainingImages.ToArray(), labels.ToArray(), 2500, ref termCrit);
name = recognizer.Recognize(result);
currentFrame.Draw(name, ref font, new System.Drawing.Point(f.rect.X - 2, f.rect.Y - 2), new Bgr(System.Drawing.Color.LightGreen));
}
NamePersons[t - 1] = name;
NamePersons.Add("");
}
t = 0;
for (int nnn = 0; nnn < facesDetected[0].Length; nnn++)
names = names + NamePersons[nnn] + ", ";
names = "";
NamePersons.Clear();
Bitmap b = currentFrame.ToBitmap();
//slow
using (MemoryStream s = new MemoryStream())
{
b.Save(s, System.Drawing.Imaging.ImageFormat.Png);
s.Seek(0, SeekOrigin.Begin); //must do this, or error is thrown in next line
frame = Texture2D.FromStream(GraphicsDevice, s);
}
////second option but image is bluish and still slow
//GraphicsDevice.Textures[0] = null;
//if (frame == null || b.Width != frame.Width || b.Height != frame.Height)
// frame = new Texture2D(GraphicsDevice, b.Width, b.Height);
//BitmapData bData = b.LockBits(new System.Drawing.Rectangle(new System.Drawing.Point(), b.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
//int byteCount = bData.Stride * b.Height;
//byte[] bmpBytes = new byte[byteCount];
//Marshal.Copy(bData.Scan0, bmpBytes, 0, byteCount);
//b.UnlockBits(bData);
//frame.SetData(bmpBytes);
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
grabber = new Capture();
}
protected override void UnloadContent()
{
grabber.Dispose();
}
protected override void Update(GameTime gameTime)
{
FrameGrabber();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Microsoft.Xna.Framework.Color.LightGray);
spriteBatch.Begin();
if (frame !=null)
spriteBatch.Draw(frame, new Microsoft.Xna.Framework.Rectangle(0, 0, ScreenWidth, ScreenHeight), Microsoft.Xna.Framework.Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
我在网上搜索了文档,但没有运气。
答案 0 :(得分:0)
我解决了我的问题,创建了一个启动并行线程并处理来自网络摄像头的帧转换的类。 如果有人有兴趣,转换为纹理并处理面部识别我用过:
private Image<Gray, byte> gray = null;
private HaarCascade haarCascade = new HaarCascade("haarcascade_frontalface_default.xml");
private void QueryFrame()
{
while (is_running)
{
nextFrame = capture.QueryFrame().Flip(FLIP.HORIZONTAL);
if (nextFrame != null)
{
gray = nextFrame.Convert<Gray, Byte>();
MCvAvgComp[][] facesDetected = gray.DetectHaarCascade(haarCascade, 1.2, 10, HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, new System.Drawing.Size(20, 20));
foreach (MCvAvgComp face in facesDetected[0])
nextFrame.Draw(face.rect, new Bgr(System.Drawing.Color.Red), 2);
byte[] bgrData = nextFrame.Bytes;
for (int i = 0; i < colorData.Length; i++)
colorData[i] = new Color(bgrData[3 * i + 2], bgrData[3 * i + 1], bgrData[3 * i]);
}
}
}