具體的內容請關注首發於51CTO的課程《基於Csharp+OpenCV圖像處理實戰》
首先拖控件,拉出窗體具體樣子。
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,
0,
0, filterInfo.achName,
1, ref oDevice, caGUID.cElems, caGUID.pElems,
0,
0, 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,實現實時圖像處理。
附件列表