0

我有一个程序,它当前显示 USB 网络摄像头的预览,然后在按下按钮时在图片框中显示一个框架。这是通过使用 directshow DxSnap 示例完成的,因此使用 ISampleGrabberCB 接口。

是否可以在不使用按钮的情况下自动扫描每一帧?

我尝试使用计时器来执行此操作,但是结果以预览和捕获的图像的图像质量不佳而告终。

这可以通过使用 IsampleGrabberCB.BufferCB 函数来实现吗?

我目前使用的获取框架的方式是一个按钮,包括:

int ISampleGrabberCB.BufferCB(double sampleTime, IntPtr buffer, int bufferLength)
    {
        Debug.Assert(bufferLength == Math.Abs(pitch) * videoHeight, "Wrong Buffer Length");

        if (gotFrame)
        {
            gotFrame = false;
            Debug.Assert(imageBuffer != IntPtr.Zero, "Remove Buffer");

            CopyMemory(imageBuffer, buffer, bufferLength);

            pictureReady.Set();
        }
        return 0;
    }
public void getFrameFromWebcam()
{
   if (iPtr != IntPtr.Zero)
   {
       Marshal.FreeCoTaskMem(iPtr);
       iPtr = IntPtr.Zero;
   }

        //Get Image
        iPtr = sampleGrabberCallBack.getFrame();
        Bitmap bitmapOfFrame = new Bitmap(sampleGrabberCallBack.width, sampleGrabberCallBack.height, sampleGrabberCallBack.capturePitch, PixelFormat.Format32bppRgb, iPtr);
        bitmapOfFrame.RotateFlip(RotateFlipType.RotateNoneFlipY);
        pictureBox3.Image = bitmapOfFrame;
        barcodeReader(bitmapOfFrame);
}

public IntPtr getFrame()
    {
        int hr;
        pictureReady.Reset();
        imageBuffer = Marshal.AllocCoTaskMem(Math.Abs(pitch) * videoHeight);

        try
        {
            gotFrame = true;

            if (videoControl != null)
            {
                hr = videoControl.SetMode(stillPin, VideoControlFlags.Trigger);
                DsError.ThrowExceptionForHR(hr);
            }

            if (!pictureReady.WaitOne(9000, false))
            {
                throw new Exception("Timeout waiting to get picture");
            }

        }
        catch
        {
            Marshal.FreeCoTaskMem(imageBuffer);
            imageBuffer = IntPtr.Zero;
        }

        return imageBuffer;

    }
4

1 回答 1

2

DirectShow 为您设置视频流,因此您有一个帧流,而不是单个图像,例如在按下按钮时获得的(事实上,对按钮的响应对于 DirectShow 来说是不典型的,并且可能需要一些特定于相机的集成)。ISampleGrabberCB::SampleCB因此,您可以按顺序获取每个捕获的视频帧。您不使用计时器轮询它,而是为每一帧调用一个回调。

因为听起来你没有得到这个,我想你错过了两件事之一,或者两者兼而有之:

  1. 您可以/需要设置您感兴趣的捕获分辨率和像素格式 - 对于图像处理,您可能更喜欢未压缩的视频格式而不是压缩的
  2. 回调调用被阻塞,帧处理越慢,有效帧速率越低,因为您正在使用视频处理时间延迟视频流。

另请注意,某些消费级相机的快照分辨率更高,视频流分辨率更低,因此在视频处理方面,您无法达到相机规格中声明的最高分辨率。

于 2013-10-25T06:28:26.843 回答