2017-07-24 229 views
0

我正在C#和使用OpenTK(OpenGL包裝)和EmguCV(OpenCV包裝)。OpenCV攝像頭幀OpenGL紋理

我想要做的事很容易理解:抓住網絡攝像機的視頻流,並把它放在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. 現在在我的GLControlLoad event我初始化capturer和OpenGL

    Capturer.Initialize(); 
    
        GL.ClearColor(Color.Blue); 
        GL.Enable(EnableCap.Texture2D); 
    
        GL.Viewport(-glControl1.Width, -glControl1.Height, glControl1.Width * 2, glControl1.Height * 2); 
    
  3. 最後,在GLControlPaint 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

(我曾嘗試使用屬性m.BitmapBitmap渲染的幀和它的作品,但表現實在是太糟糕)

+0

你沒有畫任何東西,那麼你爲什麼期望會出現什麼? – derhass

+0

你的意思是我需要繪製一個矩形或者'GLControl'的邊界嗎? –

+0

是的。只要將數據複製到texuttre就不會畫任何東西。您需要繪製紋理四邊形,或者您可以將紋理覆蓋到幀緩衝區。 – derhass

回答

1

繪製一個矩形邊界的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(); 

確保在繪製框架後處理對象,以免內存不足。