基於開源的GOCW和Directshow.net,實現攝像頭預覽、采集、錄像等操作


本文基於開源的GOCW和Directshow.net ,實現圖像采集等操作。最為關鍵的部分在於可以實現攝像頭的控制,同時關於視頻采集進行了實現。
具體的內容請關注首發於51CTO的課程《基於Csharp+OpenCV圖像處理實戰》
首先拖控件,拉出窗體具體樣子。
二、引入Directshow.net,開啟攝像頭預覽

using DirectShowLib;
namespace WINFORM_DEMO
{
     public partial  class Form2  : Form
    {
         private Capture cam;
         public Form2()
        {
            InitializeComponent();
             //構造攝像頭數據
            foreach (DsDevice ds in DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice))
            {
                cbCam.Items.Add(ds.Name);
            }
             //初始化攝像頭
            InitVideoDevice();
        }
         ////helper////
         public  void InitVideoDevice()
        {
             try
            {
                 if (cam  != null)
                    cam.Dispose();
                 //讀取參數
                 int VIDEODEVICE  =  0// zero based index of video capture device to use
                 const  int VIDEOWIDTH  =  640; // 是用默認(最大)分辨率
                 const  int VIDEOHEIGHT  =  480// Depends on video device caps
                 const  int VIDEOBITSPERPIXEL  =  24// BitsPerPixel values determined by device
                cam  =  new Capture(VIDEODEVICE, VIDEOWIDTH, VIDEOHEIGHT, VIDEOBITSPERPIXEL, picPreview);
            }
             catch
            {
                MessageBox.Show( "攝像頭打開錯誤,請首先確保攝像頭連接並至少支持1024*768分辨率!");
            }
        }
    }
}

在這里,我們通過引入Capture.cs達到獲取所有攝像頭的目的,實現了攝像頭預覽。注意這的ViDEODEVICE是0,那么通過修改其就可以開啟其他攝像頭,需要注意的是首先要進行關閉。這里通過一個簡單的重構可以達到目的。

  ////helper////
         public  void InitVideoDevice( int VIDEODEVICE  =  0)
        {
             try
            {
                 if (cam  != null)
                    cam.Dispose();
                 //讀取參數
                 const  int VIDEOWIDTH  =  640; // 是用默認(最大)分辨率
                 const  int VIDEOHEIGHT  =  480// Depends on video device caps
                 const  int VIDEOBITSPERPIXEL  =  24// BitsPerPixel values determined by device
                cam  =  new Capture(VIDEODEVICE, VIDEOWIDTH, VIDEOHEIGHT, VIDEOBITSPERPIXEL, picPreview);
            }
             catch
            {
                MessageBox.Show( "攝像頭打開錯誤,請首先確保攝像頭連接並至少支持1024*768分辨率!");
            }
        }
         private  void button1_Click(object sender, EventArgs e)
        {
             //獲得選擇的攝像頭
             int iSelect  = cbCam.SelectedIndex;
             //開啟新攝像頭
            InitVideoDevice(iSelect);
        }

最后, 添加攝像頭屬性控制,這里使用的是Dshow的相關內容,所以比較晦澀。

   /// <summary>
         /// Displays a property page for a filter
         /// </summary>
         /// <param name="dev">The filter for which to display a property page</param>
         private  void DisplayPropertyPage(IBaseFilter dev)
        {
             //Get the ISpecifyPropertyPages for the filter
            ISpecifyPropertyPages pProp  = dev as ISpecifyPropertyPages;
             int hr  =  0;
             if (pProp  == null)
            {
                 //If the filter doesn't implement ISpecifyPropertyPages, try displaying IAMVfwCompressDialogs instead!
                IAMVfwCompressDialogs compressDialog  = dev as IAMVfwCompressDialogs;
                 if (compressDialog  != null)
                {
                    hr  = compressDialog.ShowDialog(VfwCompressDialogs.Config, IntPtr.Zero);
                    DsError.ThrowExceptionForHR(hr);
                }
                 else
                {
                    MessageBox.Show( "Item has no property page""No Property Page", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                 return;
            }
             //Get the name of the filter from the FilterInfo struct
            FilterInfo filterInfo;
            hr  = dev.QueryFilterInfo(out filterInfo);
            DsError.ThrowExceptionForHR(hr);
             // Get the propertypages from the property bag
            DsCAUUID caGUID;
            hr  = pProp.GetPages(out caGUID);
            DsError.ThrowExceptionForHR(hr);
             //Create and display the OlePropertyFrame
            object oDevice  = (object)dev;
            hr  = OleCreatePropertyFrame( this.Handle,  00, filterInfo.achName,  1, ref oDevice, caGUID.cElems, caGUID.pElems,  00, IntPtr.Zero);
            DsError.ThrowExceptionForHR(hr);
            Marshal.ReleaseComObject(oDevice);
             if (filterInfo.pGraph  != null)
            {
                Marshal.ReleaseComObject(filterInfo.pGraph);
            }
             // Release COM objects
            Marshal.FreeCoTaskMem(caGUID.pElems);
    }

為了正確使用,你還需要添加
         //A (modified) definition of OleCreatePropertyFrame found here: http://groups.google.no/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/db794e9779144a46/55dbed2bab4cd772?lnk=st&q=[DllImport(%22olepro32.dll%22)]&rnum=1&hl=no#55dbed2bab4cd772
        [DllImport( "oleaut32.dll", CharSet  = CharSet.Unicode, ExactSpelling  =  true)]
         public  static  extern  int OleCreatePropertyFrame(
            IntPtr hwndOwner,
             int x,
             int y,
            [MarshalAs(UnmanagedType.LPWStr)] string lpszCaption,
             int cObjects,
            [MarshalAs(UnmanagedType.Interface, ArraySubType  = UnmanagedType.IUnknown)]
            ref object ppUnk,
             int cPages,
            IntPtr lpPageClsID,
             int lcid,
             int dwReserved,
            IntPtr lpvReserved);
以及
using System.Runtime.InteropServices;
並且在攝像頭打開的時候添加相關變量定義。


         private  void button1_Click(object sender, EventArgs e)
        {
             //獲得選擇的攝像頭
             int iSelect  = cbCam.SelectedIndex;
             //開啟新攝像頭
            InitVideoDevice(iSelect);
             //生成配套的視頻控制界面
             if (theDevice  != null)
            {
                Marshal.ReleaseComObject(theDevice);
                theDevice  = null;
            }
             //Create the filter for the selected video input device
            string devicepath  = cbCam.SelectedItem.ToString();
            theDevice  = CreateFilter(FilterCategory.VideoInputDevice, devicepath);
        }

那么到這一步,基於開源的GOCW和Directshow.net,實現圖像采集等操作就已經完成。下一步就是應該 引入GOCW,實現實時圖像處理。




附件列表

     


    免責聲明!

    本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



     
    粵ICP備18138465號   © 2018-2025 CODEPRJ.COM