1

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

私のひどい英語ですみません。

4

2 に答える 2

2

NULLレンダリングでグラフを作成します。また、directshowSDKのサンプルグラバーの例もご覧ください。グラフのフレームを取得する方法を示します。その後、フレームをopenCVに渡して処理することができます。

于 2012-04-05T16:40:01.777 に答える
1

基本的には、次のように接続します。

Source -> Sample Grabber -> Null renderer

graphEdit または GraphEdit+ をダウンロードすると、これらのフィルターを視覚的に表すことができます。例として、ローカル Web カメラからヌル レンダラーに接続されたサンプル グラバーへのグラフを作成しました。GraphEdit+ によって生成された C# コードは次のとおりです。

//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;
    }

}

}

サンプル フレームを実際にキャプチャする必要がありますが、上記の投稿で述べたように、MSDN の sampleGrabber SDK を調べて、その方法を見つけることができます。

于 2012-04-05T18:18:27.727 に答える