2012-04-05 22 views
1

StackOverflowで検索を使用しましたが、答えが見つかりませんでした。私はアプリケーションを開発してOpenCVを使用していますが、私は別のビデオ(主に* .avi)で作業する必要があるので、DirectShowを使うことにしました。私は単純なアプリケーションを作成することができましたが、ActiveWindowを作成せずに* .aviからフレームを取得する方法については何も説明できません。実際、DirectShowでビデオを読むだけで、OpenCVを使ってビデオを処理して表示します。 助けていただければ幸いです。前もって感謝します!DirectShowとopenCV。

私のひどい英語のためにすみません。

+0

可能な複製[再生せずにDirectShowから生のビデオフレームを取得できますか?](http://stackoverflow.com/questions/8924355/can-i-get-raw-video-frames-from-directshow-without-playback ) – karlphillip

+0

はい、このスレッドは見つかりませんでした、ありがとうございます! – Nikita

答えて

2

NULLレンダリングを使用してグラフを作成します。 DirectShow SDKのサンプルグラバーの例も見てください。グラフのフレームを取得する方法を示します。処理のためにフレームをopenCVに渡すことができます。

Source -> Sample Grabber -> Null renderer 

ダウンロードGraphEditのか、GraphEditの+を、あなたはこれらのフィルタを視覚的に表現することができます。

+0

ありがとう、私はサンプルグラバーの例を検討します。 "NULLレンダリングでグラフを作成する" - 私はそれをどうすればいいのか分かりません、どうか説明できますか? – Nikita

+0

通常、グラフをレンダリングするとき、単純なrenderfileコマンドを使って、普通は以下のグラフがあります:file reader-> decoder-> video render。あるいは、ヌルレンダラーを使用するためにグラフを手動で作成することもできます:reader-> decoder-> nullレンダリング。 nullレンダラーは、何も表示されないようにサンプルを黙って破棄します。アクティブなムービーウィンドウはありません。 – Saibal

+0

ありがとうございました!私はそれを持っていると思う=) – Nikita

1

は、基本的にはこのような何かを接続したいです。例として、ローカルのウェブカメラからnullレンダラーに接続されたサンプルグラバーにグラフを作成しました。あなたはまだ、実際にサンプルフレームをキャプチャする必要があるだろうが、とは、あなたがMSDNにsampleGrabber SDKに見ることができます上記の記事で言及された

//Don't forget to add reference to DirectShowLib in your project. 
using System; 
using System.Collections.Generic; 
using System.Runtime.InteropServices.ComTypes; 
using System.Runtime.InteropServices; 
using DirectShowLib; 

namespace graphcode 
{ 
class Program 
{ 
    static void checkHR(int hr, string msg) 
    { 
     if (hr < 0) 
     { 
      Console.WriteLine(msg); 
      DsError.ThrowExceptionForHR(hr); 
     } 
    } 

    static void BuildGraph(IGraphBuilder pGraph) 
    { 
     int hr = 0; 

     //graph builder 
     ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); 
     hr = pBuilder.SetFiltergraph(pGraph); 
     checkHR(hr, "Can't SetFiltergraph"); 

     Guid CLSID_SampleGrabber = new Guid("{C1F400A0-3F08-11D3-9F0B-006008039E37}"); //qedit.dll 
     Guid CLSID_NullRenderer = new Guid("{C1F400A4-3F08-11D3-9F0B-006008039E37}"); //qedit.dll 

     //add Integrated Camera 
     IBaseFilter pIntegratedCamera = CreateFilter(@"@device:pnp:\\?\usb#vid_04f2&pid_b221&mi_00#7&34997cec&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"); 
     hr = pGraph.AddFilter(pIntegratedCamera, "Integrated Camera"); 
     checkHR(hr, "Can't add Integrated Camera to graph"); 

     //add SampleGrabber 
     IBaseFilter pSampleGrabber = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_SampleGrabber)); 
     hr = pGraph.AddFilter(pSampleGrabber, "SampleGrabber"); 
     checkHR(hr, "Can't add SampleGrabber to graph"); 

     //add Null Renderer 
     IBaseFilter pNullRenderer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_NullRenderer)); 
     hr = pGraph.AddFilter(pNullRenderer, "Null Renderer"); 
     checkHR(hr, "Can't add Null Renderer to graph"); 

     //connect Integrated Camera and SampleGrabber 
     hr = pGraph.ConnectDirect(GetPin(pIntegratedCamera, "Capture"), GetPin(pSampleGrabber, "Input"), null); 
     checkHR(hr, "Can't connect Integrated Camera and SampleGrabber"); 

     //connect SampleGrabber and Null Renderer 
     hr = pGraph.ConnectDirect(GetPin(pSampleGrabber, "Output"), GetPin(pNullRenderer, "In"), null); 
     checkHR(hr, "Can't connect SampleGrabber and Null Renderer"); 

    } 

    static void Main(string[] args) 
    { 
     try 
     { 
      IGraphBuilder graph = (IGraphBuilder)new FilterGraph(); 
      Console.WriteLine("Building graph..."); 
      BuildGraph(graph); 
      Console.WriteLine("Running..."); 
      IMediaControl mediaControl = (IMediaControl)graph; 
      IMediaEvent mediaEvent = (IMediaEvent)graph; 
      int hr = mediaControl.Run(); 
      checkHR(hr, "Can't run the graph"); 
      bool stop = false; 
      int n = 0; 
      while (!stop) 
      { 
       System.Threading.Thread.Sleep(500); 
       Console.Write("."); 
       EventCode ev; 
       IntPtr p1, p2; 
       if (mediaEvent.GetEvent(out ev, out p1, out p2, 0) == 0) 
       { 
        if (ev == EventCode.Complete || ev == EventCode.UserAbort) 
        { 
         Console.WriteLine("Done!"); 
         stop = true; 
        } 
        else 
        if (ev == EventCode.ErrorAbort) 
        { 
         Console.WriteLine("An error occured: HRESULT={0:X}", p1); 
         mediaControl.Stop(); 
         stop = true; 
        } 
        mediaEvent.FreeEventParams(ev, p1, p2); 
       } 
       // stop after 10 seconds 
       n++; 
       if (n > 20) 
       { 
        Console.WriteLine("stopping.."); 
        mediaControl.Stop(); 
        stop = true; 
       } 
      } 
     } 
     catch (COMException ex) 
     { 
      Console.WriteLine("COM error: " + ex.ToString()); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Error: " + ex.ToString()); 
     } 
    } 

    public static IBaseFilter CreateFilter(string displayName) 
    { 
     int hr = 0; 
     IBaseFilter filter = null; 
     IBindCtx bindCtx = null; 
     IMoniker moniker = null; 

     try 
     { 
      hr = CreateBindCtx(0, out bindCtx); 
      Marshal.ThrowExceptionForHR(hr); 

      int eaten; 
      hr = MkParseDisplayName(bindCtx, displayName, out eaten, out moniker); 
      Marshal.ThrowExceptionForHR(hr); 

      Guid guid = typeof(IBaseFilter).GUID; 
      object obj; 
      moniker.BindToObject(bindCtx, null, ref guid, out obj); 
      filter = (IBaseFilter)obj; 
     } 
     finally 
     { 
      if (bindCtx != null) Marshal.ReleaseComObject(bindCtx); 
      if (moniker != null) Marshal.ReleaseComObject(moniker); 
     } 

     return filter; 
    } 

    [DllImport("ole32.dll")] 
    public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc); 

    [DllImport("ole32.dll")] 
    public static extern int MkParseDisplayName(IBindCtx pcb, [MarshalAs(UnmanagedType.LPWStr)] string szUserName, out int pchEaten, out IMoniker ppmk); 

    static IPin GetPin(IBaseFilter filter, string pinname) 
    { 
     IEnumPins epins; 
     int hr = filter.EnumPins(out epins); 
     checkHR(hr, "Can't enumerate pins"); 
     IntPtr fetched = Marshal.AllocCoTaskMem(4); 
     IPin[] pins = new IPin[1]; 
     while (epins.Next(1, pins, fetched) == 0) 
     { 
      PinInfo pinfo; 
      pins[0].QueryPinInfo(out pinfo); 
      bool found = (pinfo.name == pinname); 
      DsUtils.FreePinInfo(pinfo); 
      if (found) 
       return pins[0]; 
     } 
     checkHR(-1, "Pin not found"); 
     return null; 
    } 

} 

}

:GraphEditの+によって生成されたC#コードはこれですそれを行う方法を見つけるために。

関連する問題