0

我开始使用 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);
    }

我在网上搜索文档,但没有运气。

4

1 回答 1

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]);
            }
        }
    }
于 2012-09-29T06:52:26.297 回答