C# 如何使用directshow.net扫描ISampleGrabber中的每一帧
我有一个程序,当前显示一个usb网络摄像头的预览,然后在按下一个按钮时在一个图片盒中显示一个框架。这是通过使用directshow DxSnap样本完成的,因此使用ISampleGrabberCB接口 是否可以在不使用按钮的情况下自动扫描每一帧 我试着用定时器来做这件事,但是结果是预览和拍摄的图像质量都很差 这是否可以通过使用IsampleGrabberCB.BufferCB函数来实现 我目前使用的获取帧的方式是一个按钮,包括:C# 如何使用directshow.net扫描ISampleGrabber中的每一帧,c#,winforms,image-processing,directshow,directshow.net,C#,Winforms,Image Processing,Directshow,Directshow.net,我有一个程序,当前显示一个usb网络摄像头的预览,然后在按下一个按钮时在一个图片盒中显示一个框架。这是通过使用directshow DxSnap样本完成的,因此使用ISampleGrabberCB接口 是否可以在不使用按钮的情况下自动扫描每一帧 我试着用定时器来做这件事,但是结果是预览和拍摄的图像质量都很差 这是否可以通过使用IsampleGrabberCB.BufferCB函数来实现 我目前使用的获取帧的方式是一个按钮,包括: int ISampleGrabberCB.BufferCB(dou
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;
}
DirectShow为您设置视频流,因此您有一个帧流,而不是单独的图像,例如按下按钮时获得的图像(事实上,对按钮的响应对于DirectShow是不典型的,并且可能需要一些特定于相机的集成)<因此,code>ISampleGrabberCB::SampleCB将按顺序获取每个捕获的视频帧。您不使用计时器轮询它,而是为每一帧调用一个回调 因为听起来你没有明白这一点,我想你错过了两件事中的一件,或者两件都错过了:
还要注意的是,一些消费级相机的快照分辨率较高,而视频流分辨率较低,因此在视频处理方面,您无法达到相机规格中规定的最高分辨率。因此,我会使用给定的IMediaSample并将其转换为位图吗(因为外部库需要位图)?是的,这实际上很简单。常规流媒体并不完全使用位图,因此您必须从流媒体格式的视频帧中获取位图。我认为会是这种情况,我目前使用的是
ISampleGrabberCB::BufferCB
,因此当按下按钮时,当前帧将以较小的格式显示er框和条形码然后扫描给我一个数字字符串,所以基本上我试图自动实现这一点。是否有转换IMediaSample(我假设是当前帧)的一般过程进入位图?您的问题放错了。您已经自动获取了帧,因此不需要使用按钮,只需将回调调用连接到按钮处理程序所做的任何操作。不存在有关IMediaSample
的一般过程。但是,如果媒体样本是24/32位RGB,您可以使用此接口方法通过指针访问BufferCB中的数据。所以基本上我相信我的BufferCB会不断保存帧,然后当我单击我的按钮执行getFrameFromWebcam()函数时,它会调用getFrame()函数,然后获取当前保存的图像,然后函数的其余部分转换为位图,并将数字显示为字符串。是否理想地将所有这些内容移动到BufferCB中,并且仍然有效?