我从SampleGrabber过滤器得到错误的图像结果。而不是彩色图像,图像是灰度的,红色/绿色像素介于两者之间,图像重复两次。
我不得不忘记重要的事情。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DirectShowLib;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
public IGraphBuilder gb;
public ICaptureGraphBuilder2 cgb;
public IBaseFilter filter;
static SampleGrabberCallback cb;
VideoInfoHeader header;
static Form1 thisform;
public class SampleGrabberCallback : ISampleGrabberCB
{
int ISampleGrabberCB.SampleCB(Double SampleTime, IMediaSample sample)
{
return 0;
}
int ISampleGrabberCB.BufferCB(Double SampleTime, IntPtr dataPtr, Int32 BufferLen)
{
Bitmap bitmap = new Bitmap(640, 480, 640 * 3, PixelFormat.Format24bppRgb, dataPtr);
Graphics g = thisform.panel1.CreateGraphics();
g.DrawImageUnscaled(bitmap, 0, 0, 640, 480);
return 0;
}
}
public Form1()
{
InitializeComponent();
thisform = this;
DsDevice[] videoInputDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
object obj = null; Guid iid = typeof(IBaseFilter).GUID;
videoInputDevices[1].Mon.BindToObject(null, null, ref iid, out obj);
filter = (IBaseFilter)obj;
ISampleGrabber grabberFilter = (ISampleGrabber)new SampleGrabber();
IBaseFilter baseGrabber = (IBaseFilter)grabberFilter;
((IAMCameraControl)filter).Set(CameraControlProperty.Exposure, 0, CameraControlFlags.Auto);
gb = (IGraphBuilder)new FilterGraph();
cgb = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
cgb.SetFiltergraph(gb);
IEnumPins pins;
IPin[] inputPin = { null };
IPin[] outputPin = { null };
filter.EnumPins(out pins);
pins.Next(1, outputPin, IntPtr.Zero);
baseGrabber.EnumPins(out pins);
pins.Next(1, inputPin, IntPtr.Zero);
gb.AddFilter(filter, "First Filter");
gb.AddFilter(baseGrabber, "Grabber Filter");
gb.Connect(outputPin[0], inputPin[0]);
grabberFilter.SetBufferSamples(true);
AMMediaType media = new AMMediaType();
media.majorType = MediaType.Video;
media.subType = MediaSubType.RGB24;
media.formatPtr = IntPtr.Zero;
grabberFilter.SetMediaType(media);
grabberFilter.GetConnectedMediaType(media);
header = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader));
cb = new SampleGrabberCallback();
grabberFilter.SetCallback(cb, 1);
cgb.RenderStream(PinCategory.Preview, MediaType.Video, filter, null, null);
((IMediaControl)gb).Run();
}
}
}
这是我的代码。我列举了所有视频设备。我的设备有ID 1.我创建了过滤器,其中传递了网络摄像头数据,然后我将samplegrabber过滤器连接到前一个过滤器。图像准备就绪时调用回调函数。
不幸的是,图像输出错误,我不明白为什么。
同样回调说缓冲区是614 400字节。奇怪,因为它意味着像素只有16位。 (640 * 480 * 2)。这是不是意味着,缓冲区有不同的色彩空间? YUV?大多数例子都不关心色彩空间,它的工作正常。我还在mediaType中指定了RGB24。
非常感谢你帮助我。
答案 0 :(得分:3)
您应该在连接输入之前设置Sample Grabber。您使其成为24位RGB的请求很晚,您的实际连接和媒体类型也不同。你仍然在你的回调中忽略了这一点,因此破碎的画面。