This article is a review of the C#
Microsoft .NET samples that ship with the DUO SDK. This will be updated as new features are added or specifications updated to the DUO API. In the Developers/Samples
folder within the SDK download you can find the latest version of these samples with a Visual Studio project to compile.
Before reading this guide it is recommended to review our API and SDK Docs to get an understanding of the design, common practices and usage. With DUO devices you will always receive a pointer to DUOFrame which contains all relevant sensor data. The following examples showcase the usage of the DUOFrame structure while using different device functions. Also make sure you have the latest SDK download.
Here are some of the common methods used through-out the examples:
And variables/structures:
To access the DUOLib in C# we use provide a class to help facilitate interaction with the native DLL. Here is a quick overview of the class and the key methods exposed to C#.
using System; using System.Runtime.InteropServices; namespace DUODeviceLib { public delegate void DUOFrameCallback(ref DUOFrame pFrameData, IntPtr pUserData); public static class DUOLib { public static string GetLibVersion(); public static int EnumerateResolutions(DUOResolutionInfo[] resolutions, int resListSize, int width, int height , DUOBinning binning, float fps); public static extern bool OpenDUO(ref IntPtr duo); public static extern bool CloseDUO(IntPtr duo); public static extern bool StartDUO(IntPtr duo, DUOFrameCallback frameCallback, IntPtr pUserData, bool masterMode = true); public static extern bool StopDUO(IntPtr duo); public static bool GetDUODeviceName(IntPtr duo, ref string val); public static bool GetDUOFirmwareVersion(IntPtr duo, ref string val); public static bool GetDUOFirmwareBuild(IntPtr duo, ref string val); public static bool GetDUOResolutionInfo(IntPtr duo, ref DUOResolutionInfo val); public static bool GetDUOExposure(IntPtr duo, ref double val); public static bool GetDUOExposureMS(IntPtr duo, ref double val); public static bool GetDUOGain(IntPtr duo, ref double val); public static bool GetDUOHFlip(IntPtr duo, ref bool val); public static bool GetDUOVFlip(IntPtr duo, ref bool val); public static bool GetDUOCameraSwap(IntPtr duo, ref bool val); public static bool GetDUOLedPWM(IntPtr duo, ref double val); public static bool GetDUOFrameDimension(IntPtr duo, ref uint w, ref uint h); public static bool SetDUOResolutionInfo(IntPtr duo, DUOResolutionInfo val); public static bool SetDUOExposure(IntPtr duo, double val); public static bool SetDUOExposureMS(IntPtr duo, double val); public static bool SetDUOGain(IntPtr duo, double val); public static bool SetDUOHFlip(IntPtr duo, bool val); public static bool SetDUOVFlip(IntPtr duo, bool val); public static bool SetDUOCameraSwap(IntPtr duo, bool val); public static bool SetDUOLedPWM(IntPtr duo, double val); public static bool SetDUOLedPWMSeq(IntPtr duo, DUOLEDSeq[] seq, uint count); } }
Example using the DUOLib in C# via the DUODeviceLib bindings, in this sample we showcase setting up a device and outputting results to a standard console window. Accessing the DUOLib class directly compared to using the Device helper class as we showcase in the next sample.
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using DUODeviceLib; namespace DUOLibConsoleDemo { class Program { static IntPtr duo = IntPtr.Zero; static DUOFrameCallback frameCallback = new DUOFrameCallback(FrameCallback); static int frameCount = 0; static void FrameCallback(ref DUOFrame pFrameData, IntPtr pUserData) { frameCount++; Console.WriteLine("Frame ID: {0}, Timestamp: {1}", frameCount, pFrameData.timeStamp); if (pFrameData.IMUPresent) { for (int i = 0; i < pFrameData.IMUSamples; i++) { Console.WriteLine(" Sample #{0}", i+1); Console.WriteLine(" Timestamp: {0}", pFrameData.IMUData[i].timeStamp); Console.WriteLine(" Acceleration : ({0}:{1}:{2})", pFrameData.IMUData[i].accelData[0], pFrameData.IMUData[i].accelData[1], pFrameData.IMUData[i].accelData[2]); Console.WriteLine(" Gyro : ({0}:{1}:{2})", pFrameData.IMUData[i].gyroData[0], pFrameData.IMUData[i].gyroData[1], pFrameData.IMUData[i].gyroData[2]); Console.WriteLine(" Temperature : {0} C", pFrameData.IMUData[i].tempData); } } } static void Main(string[] args) { string libName = DUOLib.GetLibVersion(); Console.WriteLine("DUO Library Version: {0}", libName); bool isOpened = DUOLib.OpenDUO(ref duo); if (isOpened) { string infoString = ""; if (DUOLib.GetDUODeviceName(duo, ref infoString)) Console.WriteLine("Device Name: {0}", infoString); if (DUOLib.GetDUOSerialNumber(duo, ref infoString)) Console.WriteLine("Serial Number: {0}", infoString); if (DUOLib.GetDUOFirmwareVersion(duo, ref infoString)) Console.WriteLine("Firmware Version: {0}", infoString); if (DUOLib.GetDUOFirmwareBuild(duo, ref infoString)) Console.WriteLine("Firmware Build: {0}", infoString); DUOResolutionInfo[] resInfos = new DUOResolutionInfo[1]; int resolutionsCount = DUOLib.EnumerateResolutions(resInfos, 1, 320, 240, (DUOBinning)((int)DUOBinning.DUO_BIN_HORIZONTAL2 + DUOBinning.DUO_BIN_VERTICAL2), 60); if (resolutionsCount == 0x00) { DUOLib.CloseDUO(duo); return; } DUOLib.SetDUOResolutionInfo(duo, resInfos[0]); DUOResolutionInfo resInfo = new DUOResolutionInfo(); if(DUOLib.GetDUOResolutionInfo(duo, ref resInfo)) Console.WriteLine("DUO Resolution: {0}x{1}, {2}, {3}", resInfo.width, resInfo.height, resInfo.binning, resInfo.fps); uint w = 0, h = 0; if (DUOLib.GetDUOFrameDimension(duo, ref w, ref h)) Console.WriteLine("DUO Frame Dimension: {0}x{1}", w, h); DUOLib.SetDUOCameraSwap(duo, false); DUOLib.SetDUOHFlip(duo, false); DUOLib.SetDUOVFlip(duo, false); DUOLib.SetDUOExposure(duo, 10.0); DUOLib.SetDUOGain(duo, 10.0); DUOLib.SetDUOLedPWM(duo, 40.0); double paramValue = 0.0; if (DUOLib.GetDUOExposure(duo, ref paramValue)) Console.WriteLine("DUO Exposure: {0}", paramValue); if (DUOLib.GetDUOGain(duo, ref paramValue)) Console.WriteLine("DUO Gain: {0}", paramValue); if (DUOLib.GetDUOLedPWM(duo, ref paramValue)) Console.WriteLine("DUO PWM: {0}", paramValue); bool bValue = false; if (DUOLib.GetDUOCameraSwap(duo, ref bValue)) Console.WriteLine("DUO Camera Swap: {0}", bValue ? "YES" : "NO"); if (DUOLib.GetDUOVFlip(duo, ref bValue)) Console.WriteLine("DUO VFlip: {0}", bValue ? "YES" : "NO"); if (DUOLib.GetDUOHFlip(duo, ref bValue)) Console.WriteLine("DUO HFlip: {0}", bValue ? "YES" : "NO"); Console.WriteLine("Press Any Key to start frame grabbing"); Console.ReadKey(); if (DUOLib.StartDUO(duo, frameCallback, IntPtr.Zero)) { Console.WriteLine("Press Any Key to stop frame grabbing"); Console.ReadKey(); DUOLib.StopDUO(duo); } DUOLib.CloseDUO(duo); } Console.WriteLine("Press Any Key to exit application"); Console.ReadKey(); } } }
Example using the DUOLib in C# via the DUODeviceLib and DUODevice helper class. This class helps simplify using the DUO in your application by providing common features such as device creation as well as using traditional event system to update/notify upon parameter changes.
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using DUODeviceLib; namespace DUODeviceConsoleDemo { class Program { static void DUODeviceStatusChanged(DUODevice sender, bool isRunning) { if (isRunning) Console.WriteLine("[START DUO DEVICE]"); else Console.WriteLine("[STOP DUO DEVICE]"); } static int frameCount = 0; static void DUOFrameReceived(DUODevice sender, ref DUOFrame pFrameData) { frameCount++; Console.WriteLine("Frame ID: {0}, Timestamp: {1}", frameCount, pFrameData.timeStamp); if (pFrameData.IMUPresent) { for (int i = 0; i < pFrameData.IMUSamples; i++) { Console.WriteLine(" Sample #{0}", i + 1); Console.WriteLine(" Timestamp: {0}", pFrameData.IMUData[i].timeStamp); Console.WriteLine(" Acceleration : ({0}:{1}:{2})", pFrameData.IMUData[i].accelData[0], pFrameData.IMUData[i].accelData[1], pFrameData.IMUData[i].accelData[2]); Console.WriteLine(" Gyro : ({0}:{1}:{2})", pFrameData.IMUData[i].gyroData[0], pFrameData.IMUData[i].gyroData[1], pFrameData.IMUData[i].gyroData[2]); Console.WriteLine(" Temperature : {0} C", pFrameData.IMUData[i].tempData); } } } static void Main(string[] args) { Console.WriteLine("Press Any Key to Create DUODevice"); Console.ReadKey(); DUODevice device = new DUODevice(); Console.WriteLine(device); Console.WriteLine("\nPress Any Key to Start Capture"); Console.ReadKey(); device.DUODeviceStatusChanged += DUODeviceStatusChanged; device.DUOFrameReceived += DUOFrameReceived; device.Start(); Console.WriteLine("\nPress Any Key to Stop Capture"); Console.ReadKey(); device.Stop(); device.Dispose(); } } }
In this sample we showcase using the DUO within the WPF (Windows Presentation Foundation) application. We use the DUODeviceLib and DUOFrameViewer to display frames using standard XAML.
MainWindow.xaml.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.ComponentModel; using DUODeviceLib; namespace DUODeviceWPFDemo { ////// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { DUODevice duoDevice = null; public MainWindow() { InitializeComponent(); this.Loaded += new RoutedEventHandler(MainWindow_Loaded); this.Closing += new System.ComponentModel.CancelEventHandler(MainWindow_Closing); } void MainWindow_Closing(object sender, CancelEventArgs e) { duoDevice.Stop(); } void MainWindow_Loaded(object sender, RoutedEventArgs e) { duoDevice = new DUODevice(); frameViewer.Device = duoDevice; duoDevice.Resolution = new DUOResolutionInfo() { width = 320, height = 240, binning = DUOBinning.DUO_BIN_HORIZONTAL2 | DUOBinning.DUO_BIN_VERTICAL2, fps = 30 }; duoDevice.Start(); duoDevice.Exposure = 100; duoDevice.Gain = 10; } } }
MainWindow.xaml