1

ISampleGrabberCB::SampleCBこんにちは、 を使用して、フォーム内に表示される直前にライブ プレビューから画像を取得しようとしています。

すべての新しいフレームをビットマップに変換して処理できるようにしたいと考えています (たとえば、スキャン + 透かしタイプの画像を追加します)。

現在、私は次の方法でそれをやろうとしています:

int ISampleGrabberCB.SampleCB(double SampleTime, IMediaSample sample)
    {
        int hr;
        IntPtr buffer;
        AMMediaType mediaType;
        VideoInfoHeader videoInfo;
        int frameWidth;
        int frameHeight;
        int stride;
        int bufferLength;


        hr = sample.GetPointer(out buffer);
        DsError.ThrowExceptionForHR(hr);

        hr = sample.GetMediaType(out mediaType);
        DsError.ThrowExceptionForHR(hr);

        bufferLength = sample.GetSize();

        try
        {
            videoInfo = new VideoInfoHeader();
            Marshal.PtrToStructure(mediaType.formatPtr, videoInfo);

            frameWidth = videoInfo.BmiHeader.Width;
            frameHeight = videoInfo.BmiHeader.Height;
            stride = frameWidth * (videoInfo.BmiHeader.BitCount / 8);

            CopyMemory(imageBuffer, buffer, bufferLength);                

            Bitmap bitmapOfFrame = new Bitmap(frameWidth, frameHeight, stride, PixelFormat.Format24bppRgb, buffer);
            bitmapOfFrame.Save("C:\\Users\\...\\...\\...\\....jpg");


        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

        return 0;
    }

これは理論的には、ビットマップの作成に使用される画像の幅、高さ、ストライドを取得するために使用されるメディアタイプを取得する必要があります。次に、バッファーは IMediaSample のポインターから取得されます。

ただし、これは機能していないようです (ビットマップが保存されないため、これを推測しています)。では、すべての新しいフレームをビットマップに変換するにはどうすればよいでしょうか?

ピンが設定される追加機能:

public void setupGraphForSampleGrabber(DsDevice webcamDevice, Control displayBox)
    {
        int hr;
        ISampleGrabber sampleGrabber = null;
        IPin capturePin = null;
        IPin samplePin = null;
        IPin renderPin = null;
        IBaseFilter captureFilter;
        filtergraph = new FilterGraph() as IFilterGraph2;

        try
        {


            //Add the webcam
            hr = filtergraph.AddSourceFilterForMoniker(webcamDevice.Mon, null, webcamDevice.Name, out captureFilter);
            DsError.ThrowExceptionForHR(hr);

            //Get the still pin
            stillPin = DsFindPin.ByCategory(captureFilter, PinCategory.Still, 0);

            if (stillPin == null)
            {
                stillPin = DsFindPin.ByCategory(captureFilter, PinCategory.Preview, 0);
            }

            if (stillPin == null)
            {
                IPin outputPin = null;
                IPin inputPin = null;

                //As there is still no still pin set this to null
                videoControl = null;

                // Add a splitter
                IBaseFilter smartTee = (IBaseFilter)new SmartTee();

                try
                {
                    hr = filtergraph.AddFilter(smartTee, "SmartTee");
                    DsError.ThrowExceptionForHR(hr);

                    //Obtain the capture pin from the webcam and the input pin from the spliter and assign them to the outputPin and inputPin respectivly
                    outputPin = DsFindPin.ByCategory(captureFilter, PinCategory.Capture, 0);
                    inputPin = DsFindPin.ByDirection(smartTee, PinDirection.Input, 0);

                    //Then connect both of them to the graph
                    hr = filtergraph.Connect(outputPin, inputPin);
                    DsError.ThrowExceptionForHR(hr);

                    //Set the capture and still pins so we can use them with the rest of the program
                    stillPin = DsFindPin.ByName(smartTee, "Preview");
                    capturePin = DsFindPin.ByName(smartTee, "Capture");

                    setParameters(outputPin);

                }
                    //Release all the com objects to avoid problems as the program is to be used for extended periods

                finally
                {
                    if (outputPin != null)
                    {
                        Marshal.ReleaseComObject(outputPin);
                    }
                    if (outputPin != inputPin)
                    {
                        Marshal.ReleaseComObject(inputPin);
                    }
                    if (outputPin != smartTee)
                    {
                        Marshal.ReleaseComObject(smartTee);
                    }
                }
            }
            else
            {
                videoControl = captureFilter as IAMVideoControl;
                capturePin = DsFindPin.ByCategory(captureFilter, PinCategory.Capture, 0);
                setParameters(stillPin);
            }

            //Get interface
            sampleGrabber = new SampleGrabber() as ISampleGrabber;

            //Configure the samplegrabber
            IBaseFilter baseFilter = sampleGrabber as IBaseFilter;
            configureSampleGrabber(sampleGrabber);
            samplePin = DsFindPin.ByDirection(baseFilter, PinDirection.Input, 0);

            //Video Renderer
            IBaseFilter render = new VideoRendererDefault() as IBaseFilter;
            hr = filtergraph.AddFilter(render, "Renderer");
            DsError.ThrowExceptionForHR(hr);

            renderPin = DsFindPin.ByDirection(render, PinDirection.Input, 0);

            //Add samplegrabber to graph
            hr = filtergraph.AddFilter(baseFilter, "SampleGrabber");
            DsError.ThrowExceptionForHR(hr);

            if (videoControl == null)
            {
                //Connect still pin to samplegrabber
                hr = filtergraph.Connect(stillPin, samplePin);
                DsError.ThrowExceptionForHR(hr);

                //Connect capture pin to render
                hr = filtergraph.Connect(capturePin, renderPin);
                DsError.ThrowExceptionForHR(hr);
            }
            else
            {
                //Connect capture pin to render
                hr = filtergraph.Connect(capturePin, renderPin);
                DsError.ThrowExceptionForHR(hr);

                //Connect still pin to samplegrabber
                hr = filtergraph.Connect(stillPin, samplePin);
                DsError.ThrowExceptionForHR(hr);
            }

            //Get video properties
            saveVideoInfo(sampleGrabber);
            ConfigureVideoLocation(displayBox);

            //Run Graph
            IMediaControl mediaControl = filtergraph as IMediaControl;
            hr = mediaControl.Run();
            DsError.ThrowExceptionForHR(hr);


        }
        finally
        {
            if (sampleGrabber != null)
            {
                Marshal.ReleaseComObject(sampleGrabber);
                sampleGrabber = null;
            }
            if (capturePin != null)
            {
                Marshal.ReleaseComObject(capturePin);
                capturePin = null;
            }
            if (renderPin != null)
            {
                Marshal.ReleaseComObject(renderPin);
                renderPin = null;
            }
            if (samplePin != null)
            {
                Marshal.ReleaseComObject(samplePin);
                samplePin = null;
            }
        }
    }

さらに、サンプルグラバーを次のように構成します。

    public void configureSampleGrabber(ISampleGrabber sampleGrabber)
    {
        int hr;
        AMMediaType mediaType = new AMMediaType();

        //Set the values for media type and format
        mediaType.majorType = MediaType.Video;
        mediaType.subType = MediaSubType.RGB24;
        mediaType.formatType = FormatType.VideoInfo;
        hr = sampleGrabber.SetMediaType(mediaType);
        DsError.ThrowExceptionForHR(hr);

        DsUtils.FreeAMMediaType(mediaType);
        mediaType = null;

        //Configure
        hr = sampleGrabber.SetCallback(this, 0);
        DsError.ThrowExceptionForHR(hr);

    }
4

2 に答える 2

1

グラフが正しく設定されておらず、サンプルがサンプル グラバーを通過していないと思います。一見すると、サンプル グラバーはレンダリングされていないと思います。サンプル グラバー出力ピンをヌル レンダラーに接続すると、動作するはずです。

于 2013-11-01T18:57:48.533 に答える