【问题标题】:Why i get bad image result from my webcamera?为什么我的网络摄像头的图像结果不好?
【发布时间】:2013-12-25 22:40:24
【问题描述】:

我从 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 过滤器连接到前一个过滤器。图像准备好时调用回调函数。

不幸的是,图像输出错误,我不知道为什么。

回调还说 bufferlen 是 614 400 字节。奇怪,因为这意味着像素只有 16 位。 (640*480*2)。这是否意味着缓冲区具有不同的色彩空间?尤夫?大多数示例不关心色彩空间,并且工作正常。我还在 mediaType 中指定了 RGB24。

非常感谢你帮助我。

【问题讨论】:

    标签: c# webcam directshow video-capture directshow.net


    【解决方案1】:

    您应该在连接其输入之前设置您的 Sample Grabber。您将其设为 24 位 RGB 的请求迟了,并且您的实际连接和媒体类型不同。您仍然在回调中忽略了这一点,因此图片损坏了。

    【讨论】:

    • 你是对的。现在,我的问题解决了。非常感谢 Roman R。
    猜你喜欢
    • 2015-04-18
    • 1970-01-01
    • 2020-07-06
    • 1970-01-01
    • 2014-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    相关资源
    最近更新 更多