OpenCV 网络摄像头帧到 OpenGL 纹理

E. 威廉姆斯

我正在使用 C# 并使用OpenTK(OpenGL 包装器)和EmguCV(OpenCV 包装器)。

我想要做的很容易理解:抓取网络摄像头视频流并将其放在GLControl.

  1. 我有一个静态class调用Capturer,它有一个捕获帧并将其作为cv::Mat包装对象返回的方法

    internal static void Initialize()
    {
        cap = new VideoCapture(1);
        cap.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.Fps, 25);
        cap.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameWidth, 1920);
        cap.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameHeight, 1080);
    }
    
    internal static Mat GetCurrentFrame()
    {
        mat = cap.QueryFrame();
        if (!mat.IsEmpty)
        {
            return mat;
        }
        return null;
    }
    
  2. 现在在我的GLControl Load event我初始化捕获器和 OpenGL

        Capturer.Initialize();
    
        GL.ClearColor(Color.Blue);
        GL.Enable(EnableCap.Texture2D);
    
        GL.Viewport(-glControl1.Width, -glControl1.Height, glControl1.Width * 2, glControl1.Height * 2);
    
  3. 最后,在GLControl Paint event

        GL.Clear(ClearBufferMask.ColorBufferBit);
    
        GL.MatrixMode(MatrixMode.Projection);
        GL.LoadIdentity();
    
        Mat m = Capturer.GetCurrentFrame();
        if (m != null)
        {
            GL.GenTextures(1, out textureId);
            GL.BindTexture(TextureTarget.Texture2D, this.textureId);
    
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.Nearest);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
    
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (float)TextureWrapMode.Clamp);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (float)TextureWrapMode.Clamp);
    
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, 1920, 1080, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgr, PixelType.UnsignedByte, m.DataPointer);
        }
        m.Dispose();
    
        glControl1.SwapBuffers();
        glControl1.Invalidate();
    

这是显示一个完整的蓝屏。我认为错误在m.DataPointer.

(我曾尝试Bitmap使用该属性渲染帧m.Bitmap并且它可以工作,但性能非常糟糕。)

E. 威廉姆斯

绘制一个矩形GLControl来解决它:

            GL.Begin(PrimitiveType.Quads);
                GL.TexCoord2(0, 0); GL.Vertex2(0, 0);
                GL.TexCoord2(0, 1); GL.Vertex2(0, 1);
                GL.TexCoord2(1, 1); GL.Vertex2(1, 1);
                GL.TexCoord2(1, 0); GL.Vertex2(1, 0);
            GL.End();
            m.Dispose();

请务必在绘制框架后处理对象,以免内存不足。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章