Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 2525 → Rev 2526

/MKLiveView/v1.0/Source/WebCamWrapper/Camera/Camera.cs
0,0 → 1,1119
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using WebCamLib;
 
namespace Touchless.Vision.Camera
{
public enum CameraProperty : int
{
Pan_degrees = WebCamLib.CameraProperty.Pan_degrees,
Tilt_degrees = WebCamLib.CameraProperty.Tilt_degrees,
Roll_degrees = WebCamLib.CameraProperty.Roll_degrees,
Zoom_mm = WebCamLib.CameraProperty.Zoom_mm,
Exposure_lgSec = WebCamLib.CameraProperty.Exposure_lgSec,
Iris_10f = WebCamLib.CameraProperty.Iris_10f,
FocalLength_mm = WebCamLib.CameraProperty.FocalLength_mm,
Flash = WebCamLib.CameraProperty.Flash,
Brightness = WebCamLib.CameraProperty.Brightness,
Contrast = WebCamLib.CameraProperty.Brightness,
Hue = WebCamLib.CameraProperty.Contrast,
Saturation = WebCamLib.CameraProperty.Saturation,
Sharpness = WebCamLib.CameraProperty.Sharpness,
Gamma = WebCamLib.CameraProperty.Gamma,
ColorEnable = WebCamLib.CameraProperty.ColorEnable,
WhiteBalance = WebCamLib.CameraProperty.WhiteBalance,
BacklightCompensation = WebCamLib.CameraProperty.BacklightCompensation,
Gain = WebCamLib.CameraProperty.Gain,
}
 
public sealed class CameraPropertyValue : IComparable<CameraPropertyValue>, IEquatable<CameraPropertyValue>
{
public CameraPropertyValue( bool isPercentageValue, int value, bool isAuto )
{
IsPercentageValue = isPercentageValue;
Value = value;
IsAuto = isAuto;
}
 
public int Value
{
get;
set;
}
 
private bool isAuto;
 
public bool IsAuto
{
get
{
return isAuto;
}
 
set
{
isAuto = value;
}
}
 
public bool IsManual
{
get
{
return !IsAuto;
}
 
set
{
IsAuto = !value;
}
}
 
private bool isPercentageValue;
 
public bool IsActualValue
{
get
{
return !IsPercentageValue;
}
 
set
{
IsPercentageValue = !value;
}
}
 
public bool IsPercentageValue
{
get
{
return isPercentageValue;
}
 
set
{
isPercentageValue = value;
}
}
 
#region ICompare<CameraPropertyValue> Members
 
public int CompareTo( CameraPropertyValue other )
{
int result = 0;
 
if( IsActualValue && other.IsPercentageValue )
result = -1;
else if( IsPercentageValue && other.IsActualValue )
result = 1;
else
{
if( Value < other.Value )
result = -1;
else if( Value > other.Value )
result = 1;
else
{
if( IsAuto && other.IsManual )
result = -1;
else if( IsManual && other.IsAuto )
result = 1;
}
}
 
return result;
}
 
#endregion
 
#region IEquatable<CameraPropertyValue> Members
 
public bool Equals( CameraPropertyValue other )
{
return Object.ReferenceEquals( this, other ) || CompareTo( other ) == 0;
}
 
#endregion
 
public override bool Equals( Object obj )
{
bool result;
 
if( !( result = Object.ReferenceEquals( this, obj ) ) )
{
CameraPropertyValue other = obj as CameraPropertyValue;
 
if( result = other != null )
result = Equals( other );
}
 
return result;
}
}
 
public sealed class CameraPropertyRange : IComparable<CameraPropertyRange>, IEquatable<CameraPropertyRange>
{
public CameraPropertyRange( int minimum, int maximum, int step, int defaults, bool isAuto )
{
Minimum = minimum;
Maximum = maximum;
Step = step;
Defaults = defaults;
IsAuto = isAuto;
}
 
public int Minimum
{
get;
private set;
}
 
public int Maximum
{
get;
private set;
}
 
public int Range
{
get
{
return Maximum - Minimum;
}
}
 
public int DomainSize
{
get
{
return Range + 1;
}
}
 
public int Step
{
get;
private set;
}
 
public int Defaults
{
get;
private set;
}
 
public bool IsAuto
{
get;
private set;
}
 
public bool IsManual
{
get
{
return !IsAuto;
}
}
 
#region ICompare<CameraPropertyRange> Members
 
public int CompareTo( CameraPropertyRange other )
{
int result = 0;
 
if( Minimum < other.Minimum )
result = -1;
else if( Minimum > other.Minimum )
result = 1;
else
{
if( Maximum < other.Maximum )
result = -1;
else if( Maximum > other.Maximum )
result = 1;
else
{
if( Step < other.Step )
result = -1;
else if( Step > other.Step )
result = 1;
else
{
if( Defaults < other.Defaults )
result = -1;
else if( Defaults > other.Defaults )
result = 1;
else
{
if( IsAuto && other.IsManual )
result = -1;
else if( IsManual && other.IsAuto )
result = 1;
}
}
}
}
 
return result;
}
 
#endregion
 
#region IEquatable<CameraPropertyRange> Members
 
public bool Equals( CameraPropertyRange other )
{
return Object.ReferenceEquals( this, other ) || CompareTo( other ) == 0;
}
 
#endregion
 
public override bool Equals( Object obj )
{
bool result;
 
if( !( result = Object.ReferenceEquals( this, obj ) ) )
{
CameraPropertyRange other = obj as CameraPropertyRange;
 
if( result = other != null )
result = Equals( other );
}
 
return result;
}
}
 
public sealed class CameraPropertyCapabilities : IComparable<CameraPropertyCapabilities>, IEquatable<CameraPropertyCapabilities>
{
internal CameraPropertyCapabilities( Camera camera, WebCamLib.CameraPropertyCapabilities capabilities )
{
Camera = camera;
InternalCapabilities = capabilities;
}
 
public Camera Camera
{
get;
private set;
}
 
internal WebCamLib.CameraPropertyCapabilities InternalCapabilities
{
get;
private set;
}
 
public bool IsSupported
{
get
{
return InternalCapabilities.IsSupported;
}
}
 
public bool IsFullySupported
{
get
{
return InternalCapabilities.IsFullySupported;
}
}
 
public bool IsGetSupported
{
get
{
return InternalCapabilities.IsGetSupported;
}
}
 
public bool IsSetSupported
{
get
{
return InternalCapabilities.IsSetSupported;
}
}
 
public bool IsGetRangeSupported
{
get
{
return InternalCapabilities.IsGetRangeSupported;
}
}
 
#region IComparable<CameraPropertyCapabilities> Members
// sort order: IsGetSupported, IsSetSupported, IsGetRangeSupported; this exists and other doesn't first/less for all keys
public int CompareTo( CameraPropertyCapabilities other )
{
int result = 0;
 
if( IsGetSupported && !other.IsGetSupported )
result = -1;
else if( !IsGetSupported && other.IsGetSupported )
result = 1;
else
{
if( IsSetSupported && !other.IsSetSupported )
result = -1;
else if( !IsSetSupported && other.IsSetSupported )
result = 1;
else
{
if( IsGetRangeSupported && !other.IsGetRangeSupported )
result = -1;
else if( !IsGetRangeSupported && other.IsGetRangeSupported )
result = 1;
}
}
 
return result;
}
#endregion
 
#region IEquatable<CameraPropertyCapabilities>
public bool Equals( CameraPropertyCapabilities other )
{
return CompareTo( other ) == 0;
}
#endregion
 
public override bool Equals( object obj )
{
bool result;
 
CameraPropertyCapabilities capabilities = obj as CameraPropertyCapabilities;
 
if( result = capabilities != null )
result = Equals( capabilities );
 
return result;
}
}
 
public sealed class CaptureSize : IComparable<CaptureSize>, IEquatable<CaptureSize>
{
public CaptureSize( int width, int height, int colorDepth )
{
Width = width;
Height = height;
ColorDepth = colorDepth;
}
 
public int Width
{
get;
private set;
}
 
public int Height
{
get;
private set;
}
 
public int ColorDepth
{
get;
private set;
}
 
public override String ToString()
{
return String.Format( "{0} x {1} @ {2}", Width, Height, ColorDepth );
}
 
#region IComparable<CaptureSize> Members
 
public int CompareTo( CaptureSize other )
{
int result;
 
if( Width < other.Width )
result = -1;
else if( Width > other.Width )
result = 1;
else
{
if( Height < other.Height )
result = -1;
else if( Height > other.Height )
result = 1;
else
{
if( ColorDepth < other.ColorDepth )
result = -1;
else if( ColorDepth > other.ColorDepth )
result = 1;
else
result = 0;
}
}
 
return result;
}
 
#endregion
 
#region IEquatable<CaptureSize> Members
 
public bool Equals( CaptureSize other )
{
return Object.ReferenceEquals( this, other ) || CompareTo( other ) == 0;
}
 
#endregion
 
public override bool Equals( Object obj )
{
bool result;
 
if( !( result = Object.ReferenceEquals( this, obj ) ) )
{
CaptureSize other = obj as CaptureSize;
if( result = other != null )
result = Equals( other );
}
 
return result;
}
 
public override int GetHashCode()
{
int result = 0;
 
result ^= Width;
result ^= Height << 11;
result ^= ColorDepth << 23;
 
return result;
}
}
 
/// <summary>
/// Represents a camera in use by the Touchless system
/// </summary>
public class Camera : IDisposable
{
public const int IgnoredBitsPerPixel = -1;
 
private readonly Object CameraMethodsLock = new Object();
 
private readonly CameraMethods _cameraMethods;
private RotateFlipType _rotateFlip = RotateFlipType.RotateNoneFlipNone;
 
public Camera( CameraMethods cameraMethods, string name, int index )
{
_name = name;
_index = index;
 
lock( CameraMethodsLock )
{
_cameraMethods = cameraMethods;
_cameraMethods.OnImageCapture += CaptureCallbackProc;
}
}
 
public string Name
{
get
{
return _name;
}
}
 
/// <summary>
/// Defines the frames per second limit that is in place, -1 means no limit
/// </summary>
public int Fps
{
get
{
return _fpslimit;
}
set
{
_fpslimit = value;
_timeBetweenFrames = ( 1000.0 / _fpslimit );
}
}
 
/// <summary>
/// Determines the width of the image captured
/// </summary>
public int CaptureWidth
{
get
{
return _width;
}
set
{
_width = value;
}
}
 
/// <summary>
/// Defines the height of the image captured
/// </summary>
public int CaptureHeight
{
get
{
return _height;
}
set
{
_height = value;
}
}
 
/// <summary>
/// Defines the bits per pixel of image captured.
/// </summary>
public int CaptureBitsPerPixel
{
get
{
return _bpp;
}
 
set
{
_bpp = value;
}
}
 
public bool HasFrameLimit
{
get
{
return _fpslimit != -1;
}
}
 
public bool FlipHorizontal
{
get
{
return RotateFlip == RotateFlipType.RotateNoneFlipX || RotateFlip == RotateFlipType.Rotate180FlipNone;
}
 
set
{
if( value && FlipVertical )
{
RotateFlip = RotateFlipType.Rotate180FlipNone;
}
else if( value && !FlipVertical )
{
RotateFlip = RotateFlipType.RotateNoneFlipX;
}
else if( !value && FlipVertical )
{
RotateFlip = RotateFlipType.Rotate180FlipX;
}
else if( !value && !FlipVertical )
{
RotateFlip = RotateFlipType.RotateNoneFlipNone;
}
}
}
 
public bool FlipVertical
{
get
{
return RotateFlip == RotateFlipType.Rotate180FlipX || RotateFlip == RotateFlipType.Rotate180FlipNone;
}
 
set
{
if( value && FlipHorizontal )
{
RotateFlip = RotateFlipType.Rotate180FlipNone;
}
else if( value && !FlipHorizontal )
{
RotateFlip = RotateFlipType.Rotate180FlipX;
}
else if( !value && FlipHorizontal )
{
RotateFlip = RotateFlipType.RotateNoneFlipX;
}
else if( !value && !FlipHorizontal )
{
RotateFlip = RotateFlipType.RotateNoneFlipNone;
}
}
}
 
/// <summary>
/// Command for rotating and flipping incoming images
/// </summary>
public RotateFlipType RotateFlip
{
get
{
return _rotateFlip;
}
set
{
// Swap height/width when rotating by 90 or 270
if( ( int ) _rotateFlip % 2 != ( int ) value % 2 )
{
int temp = CaptureWidth;
CaptureWidth = CaptureHeight;
CaptureHeight = temp;
}
_rotateFlip = value;
}
}
 
#region IDisposable Members
 
/// <summary>
/// Cleanup function for the camera
/// </summary>
public void Dispose()
{
StopCapture();
}
 
#endregion
 
/// <summary>
/// Returns the last image acquired from the camera
/// </summary>
/// <returns>A bitmap of the last image acquired from the camera</returns>
public Bitmap GetCurrentImage()
{
Bitmap b = null;
lock( _bitmapLock )
{
if( _bitmap == null )
{
return null;
}
 
b = new Bitmap( _bitmap );
}
 
return b;
}
 
public void ShowPropertiesDialog()
{
lock( CameraMethodsLock )
{
_cameraMethods.DisplayCameraPropertiesDialog( _index );
}
}
 
public CameraInfo GetCameraInfo()
{
lock( CameraMethodsLock )
{
return _cameraMethods.GetCameraInfo( _index );
}
}
 
#region Camera Properties
public bool IsCameraPropertySupported( CameraProperty property )
{
bool result = false;
 
lock( CameraMethodsLock )
{
_cameraMethods.IsPropertySupported( ( WebCamLib.CameraProperty ) property, ref result );
}
 
return result;
}
 
public bool SetCameraProperty( CameraProperty property, CameraPropertyValue value )
{
bool result;
 
if( value.IsActualValue )
result = SetCameraProperty_value( property, value.Value, value.IsAuto );
else // if( value.IsPercentageValue )
result = SetCameraProperty_percentage( property, value.Value, value.IsAuto );
 
return result;
}
 
public bool SetCameraProperty( CameraProperty property, bool isActualValue, int value )
{
bool result = false;
 
if( isActualValue )
result = SetCameraProperty_value( property, value );
else // is percentage value
result = SetCameraProperty_percentage( property, value );
 
return result;
}
 
public bool SetCameraProperty( CameraProperty property, bool isActualValue, int value, bool auto )
{
bool result = false;
 
if( isActualValue )
result = SetCameraProperty_value( property, value, auto );
else // is percentage value
result = SetCameraProperty_percentage( property, value, auto );
 
return result;
}
 
public bool SetCameraProperty_value( CameraProperty property, bool auto )
{
return SetCameraProperty_value( property, 0, auto );
}
 
// Assume manual control
public bool SetCameraProperty_value( CameraProperty property, int value )
{
return SetCameraProperty_value( property, value, false );
}
 
public bool SetCameraProperty_value( CameraProperty property, int value, bool auto )
{
bool result = false;
 
lock( CameraMethodsLock )
{
_cameraMethods.SetProperty_value( ( WebCamLib.CameraProperty ) property, value, auto, ref result );
}
 
return result;
}
 
public bool SetCameraProperty_percentage( CameraProperty property, bool auto )
{
return SetCameraProperty_percentage( property, 0, auto );
}
 
// Assume manual control
public bool SetCameraProperty_percentage( CameraProperty property, int percentage )
{
return SetCameraProperty_percentage( property, percentage, false );
}
 
public bool SetCameraProperty_percentage( CameraProperty property, int percentage, bool auto )
{
bool result = false;
 
lock( CameraMethodsLock )
{
_cameraMethods.SetProperty_percentage( ( WebCamLib.CameraProperty ) property, percentage, auto, ref result );
}
 
return result;
}
 
public CameraPropertyValue GetCameraProperty( CameraProperty property, bool isActualValue )
{
CameraPropertyValue result;
 
if( isActualValue )
result = GetCameraProperty_value( property );
else // is percentage value
result = GetCameraProperty_percentage( property );
 
return result;
}
 
public CameraPropertyValue GetCameraProperty_value( CameraProperty property )
{
CameraPropertyValue result;
 
bool successful = false;
 
int value = -1;
bool isAuto = false;
 
lock( CameraMethodsLock )
{
_cameraMethods.GetProperty_value( ( WebCamLib.CameraProperty ) property, ref value, ref isAuto, ref successful );
}
 
if( successful )
result = new CameraPropertyValue( false, value, isAuto );
else
result = null;
 
return result;
}
 
public CameraPropertyValue GetCameraProperty_percentage( CameraProperty property )
{
CameraPropertyValue result;
 
bool successful = false;
 
int value = -1;
bool isAuto = false;
 
lock( CameraMethodsLock )
{
_cameraMethods.GetProperty_percentage( ( WebCamLib.CameraProperty ) property, ref value, ref isAuto, ref successful );
}
 
if( successful )
result = new CameraPropertyValue( true, value, isAuto );
else
result = null;
 
return result;
}
 
public CameraPropertyRange GetCameraPropertyRange( CameraProperty property )
{
CameraPropertyRange result;
 
bool successful = false;
 
int minimum, maximum, step, defaults;
bool isAuto;
 
minimum = maximum = step = defaults = -1;
isAuto = false;
 
lock( CameraMethodsLock )
{
_cameraMethods.GetPropertyRange( ( WebCamLib.CameraProperty ) property, ref minimum, ref maximum, ref step, ref defaults, ref isAuto, ref successful );
}
 
if( successful )
result = new CameraPropertyRange( minimum, maximum, step, defaults, isAuto );
else
result = null;
 
return result;
}
 
public bool CameraPropertyHasRange( CameraProperty property )
{
bool result = false;
 
_cameraMethods.PropertyHasRange( ( WebCamLib.CameraProperty ) property, ref result );
 
return result;
}
 
public bool ValidateCameraProperty( CameraProperty property, int value )
{
bool result = false;
 
_cameraMethods.ValidatePropertyValue( ( WebCamLib.CameraProperty ) property, value, ref result );
 
return result;
}
 
public IDictionary<CameraProperty, CameraPropertyCapabilities> CameraPropertyCapabilities
{
get
{
IDictionary<CameraProperty, CameraPropertyCapabilities> result = new Dictionary<CameraProperty, CameraPropertyCapabilities>( _cameraMethods.PropertyCapabilities.Count );
 
foreach( WebCamLib.CameraProperty property in _cameraMethods.PropertyCapabilities.Keys )
{
CameraProperty prop = ( CameraProperty ) property;
CameraPropertyCapabilities capabilities = new CameraPropertyCapabilities( this, _cameraMethods.PropertyCapabilities[ property ] );
 
result.Add( prop, capabilities );
}
 
return result;
}
}
#endregion
 
public IList<CaptureSize> CaptureSizes
{
get
{
IList<Tuple<int, int, int>> rawSizes = new List<Tuple<int, int, int>>();
 
lock( CameraMethodsLock )
{
_cameraMethods.GetCaptureSizes( _index, rawSizes );
}
 
IList<CaptureSize> result = new List<CaptureSize>( rawSizes.Count );
foreach( Tuple<int, int, int> size in rawSizes )
{
CaptureSize newSize = new CaptureSize( size.Item1, size.Item2, size.Item3 );
result.Add( newSize );
}
 
return result;
}
}
 
/// <summary>
/// Event fired when an image from the camera is captured
/// </summary>
public event EventHandler<CameraEventArgs> OnImageCaptured;
 
/// <summary>
/// Returns the camera name as the ToString implementation
/// </summary>
/// <returns>The name of the camera</returns>
public override string ToString()
{
return _name;
}
 
#region Internal Implementation
 
private readonly object _bitmapLock = new object();
private readonly int _index;
private readonly string _name;
private Bitmap _bitmap;
private DateTime _dtLastCap = DateTime.MinValue;
private int _fpslimit = -1;
private int _height = 240;
private double _timeBehind;
private double _timeBetweenFrames;
private int _width = 320;
private int _bpp = 24;
 
internal bool StartCapture()
{
bool result = false;
 
lock( CameraMethodsLock )
{
_cameraMethods.StartCamera( _index, ref _width, ref _height, ref _bpp, ref result );
_cameraMethods.OnImageCapture += CaptureCallbackProc;
}
 
return result;
}
 
internal void StopCapture()
{
lock( CameraMethodsLock )
{
_cameraMethods.StopCamera();
_cameraMethods.OnImageCapture -= CaptureCallbackProc;
}
}
 
/// <summary>
/// Here is where the images come in as they are collected, as fast as they can and on a background thread
/// </summary>
private void CaptureCallbackProc( int dataSize, byte[] data )
{
// Do the magic to create a bitmap
int stride = _width * 3;
GCHandle handle = GCHandle.Alloc( data, GCHandleType.Pinned );
var scan0 = handle.AddrOfPinnedObject();
scan0 += ( _height - 1 ) * stride;
var b = new Bitmap( _width, _height, -stride, PixelFormat.Format24bppRgb, scan0 );
b.RotateFlip( _rotateFlip );
// NOTE: It seems that bntr has made that resolution property work properly
var copyBitmap = ( Bitmap ) b.Clone();
// Copy the image using the Thumbnail function to also resize if needed
//var copyBitmap = (Bitmap)b.GetThumbnailImage(_width, _height, null, IntPtr.Zero);
 
// Now you can free the handle
handle.Free();
 
ImageCaptured( copyBitmap );
}
 
private void ImageCaptured( Bitmap bitmap )
{
DateTime dtCap = DateTime.Now;
 
// Always save the bitmap
lock( _bitmapLock )
{
_bitmap = bitmap;
}
 
// FPS affects the callbacks only
if( _fpslimit != -1 )
{
if( _dtLastCap != DateTime.MinValue )
{
double milliseconds = ( ( dtCap.Ticks - _dtLastCap.Ticks ) / TimeSpan.TicksPerMillisecond ) * 1.15;
if( milliseconds + _timeBehind >= _timeBetweenFrames )
{
_timeBehind = ( milliseconds - _timeBetweenFrames );
if( _timeBehind < 0.0 )
{
_timeBehind = 0.0;
}
}
else
{
_timeBehind = 0.0;
return; // ignore the frame
}
}
}
 
var handler = OnImageCaptured;
 
if ( handler != null )
{
var fps = ( int ) ( 1 / dtCap.Subtract( _dtLastCap ).TotalSeconds );
handler.Invoke( this, new CameraEventArgs( bitmap, fps ) );
}
 
_dtLastCap = dtCap;
}
 
#endregion
}
 
/// <summary>
/// Camera specific EventArgs that provides the Image being captured
/// </summary>
public class CameraEventArgs : EventArgs
{
/// <summary>
/// Current Camera Image
/// </summary>
public Bitmap Image
{
get
{
return _image;
}
}
 
public int CameraFps
{
get
{
return _cameraFps;
}
}
 
#region Internal Implementation
 
private readonly int _cameraFps;
private readonly Bitmap _image;
 
internal CameraEventArgs( Bitmap i, int fps )
{
_image = i;
_cameraFps = fps;
}
 
#endregion
}
}
/MKLiveView/v1.0/Source/WebCamWrapper/Camera/CameraFrameSource.cs
0,0 → 1,105
using System;
using System.ComponentModel.Composition;
using Touchless.Vision.Camera.Configuration;
using Touchless.Vision.Contracts;
 
namespace Touchless.Vision.Camera
{
[Export(typeof(IFrameSource))]
public class CameraFrameSource : IFrameSource
{
public event Action<IFrameSource, Frame, double> NewFrame;
public bool IsCapturing { get; private set; }
 
private Camera _camera;
public Camera Camera
{
get { return _camera; }
 
internal set
{
if (_camera != value)
{
bool restart = IsCapturing;
if (IsCapturing)
{
StopFrameCapture();
}
 
_camera = value;
 
if (restart)
{
StartFrameCapture();
}
}
}
}
 
[ImportingConstructor]
public CameraFrameSource([Import(ExportInterfaceNames.DefaultCamera)] Camera camera)
{
if (camera == null) throw new ArgumentNullException("camera");
 
this.Camera = camera;
}
 
public bool StartFrameCapture()
{
bool result;
 
if (result = !IsCapturing && this.Camera != null)
{
this.Camera.OnImageCaptured += OnImageCaptured;
IsCapturing = result = this.Camera.StartCapture();
}
 
return result;
}
 
public void StopFrameCapture()
{
if (IsCapturing)
{
this.Camera.StopCapture();
this.Camera.OnImageCaptured -= OnImageCaptured;
this.IsCapturing = false;
}
}
 
private void OnImageCaptured(object sender, CameraEventArgs e)
{
var handler = this.NewFrame;
if (IsCapturing && handler != null)
{
var frame = new Frame(e.Image);
handler(this, frame, e.CameraFps);
}
}
 
public string Name
{
get { return "Touchless Camera Frame Source"; }
}
 
public string Description
{
get { return "Retrieves frames from Camera"; }
}
 
public bool HasConfiguration
{
get { return true; }
}
 
 
public System.Windows.UIElement ConfigurationElement
{
get
{
return new CameraFrameSourceConfigurationElement(this);
}
}
}
}
/MKLiveView/v1.0/Source/WebCamWrapper/Camera/CameraService.cs
0,0 → 1,81
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel.Composition;
 
namespace Touchless.Vision.Camera
{
public static class CameraService
{
private static WebCamLib.CameraMethods _cameraMethods;
 
private static WebCamLib.CameraMethods CameraMethods
{
get
{
if (_cameraMethods == null)
{
try
{
_cameraMethods = new WebCamLib.CameraMethods();
 
}
catch (Exception)
{
}
 
}
 
return _cameraMethods;
}
}
 
[Export(ExportInterfaceNames.DefaultCamera)]
public static Camera DefaultCamera
{
get { return AvailableCameras.FirstOrDefault(); }
}
 
private static List<Camera> _availableCameras;
public static IList<Camera> AvailableCameras
{
get
{
try
{
if (_availableCameras == null && CameraMethods != null)
{
_availableCameras = BuildCameraList().ToList();
}
 
}
catch (Exception)
{
 
}
 
 
return _availableCameras;
}
}
public static void ClearCameraList()
{
_availableCameras = null;
_cameraMethods = null;
}
 
private static IEnumerable<Camera> BuildCameraList()
{
if (CameraMethods != null)
{
for (int i = 0; i < CameraMethods.Count; i++)
{
WebCamLib.CameraInfo cameraInfo = CameraMethods.GetCameraInfo(i);
yield return new Camera(CameraMethods, cameraInfo.Name, cameraInfo.Index);
}
}
}
}
}
/MKLiveView/v1.0/Source/WebCamWrapper/Camera/Configuration/CameraFrameSourceConfigurationElement.xaml
0,0 → 1,26
<UserControl x:Class="Touchless.Vision.Camera.Configuration.CameraFrameSourceConfigurationElement"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="550" Height="260">
<GroupBox Header="Camera Settings">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical" Width="200">
<ComboBox x:Name="comboBoxCameras" SelectionChanged="comboBoxCameras_SelectionChanged" />
<StackPanel x:Name="panelCameraInfo" Orientation="Vertical" MinWidth="180" DataContext="{Binding SelectedItem, ElementName=comboBoxCameras, Mode=Default}">
<Button Click="buttonCameraProperties_Click" x:Name="buttonCameraProperties" Content="Adjust Camera Properties" Margin="0,10,0,10" />
<CheckBox Content="Flip Image Horizontally" IsChecked="{Binding FlipHorizontal, Mode=TwoWay}" />
<CheckBox Content="Flip Image Vertically" IsChecked="{Binding FlipVertical, Mode=TwoWay}" />
<StackPanel Orientation="Horizontal" Margin="0,10,0,10">
<Label VerticalAlignment="Center" Margin="-1">Current Frames Per Second:</Label>
<Label x:Name="labelCameraFPSValue" Content="{Binding Fps, Mode=Default}" Margin="3,0,0,0" Width="40" HorizontalContentAlignment="Right"></Label>
</StackPanel>
<StackPanel Orientation="Horizontal">
<CheckBox x:Name="chkLimitFps" Content="Limit Frames Per Second:" VerticalAlignment="Center" Checked="chkLimitFps_Checked" Unchecked="chkLimitFps_Unchecked" />
<TextBox x:Name="txtLimitFps" Margin="10,0,0,0" Text="-1" Width="40" VerticalAlignment="Center" MaxLines="1" HorizontalContentAlignment="Right" IsEnabled="False" TextChanged="txtLimitFps_TextChanged" />
</StackPanel>
</StackPanel>
</StackPanel>
<Image x:Name="imgPreview" Width="320" Height="240" Margin="10,0,10,0" Stretch="Fill" VerticalAlignment="Top" />
</StackPanel>
</GroupBox>
</UserControl>
/MKLiveView/v1.0/Source/WebCamWrapper/Camera/Configuration/CameraFrameSourceConfigurationElement.xaml.cs
0,0 → 1,119
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using Touchless.Shared.Extensions;
 
namespace Touchless.Vision.Camera.Configuration
{
/// <summary>
/// Interaction logic for CameraFrameSourceConfigurationElement.xaml
/// </summary>
public partial class CameraFrameSourceConfigurationElement : UserControl
{
private readonly CameraFrameSource _cameraFrameSource;
 
public CameraFrameSourceConfigurationElement()
: this(null)
{
 
}
 
public CameraFrameSourceConfigurationElement(CameraFrameSource cameraFrameSource)
{
_cameraFrameSource = cameraFrameSource;
InitializeComponent();
 
if (!DesignerProperties.GetIsInDesignMode(this) && _cameraFrameSource != null)
{
_cameraFrameSource.NewFrame += NewFrame;
 
var cameras = CameraService.AvailableCameras.ToList();
comboBoxCameras.ItemsSource = cameras;
comboBoxCameras.SelectedItem = _cameraFrameSource.Camera;
}
}
 
private readonly object _frameSync = new object();
private bool _frameWaiting = false;
private void NewFrame(Touchless.Vision.Contracts.IFrameSource frameSource, Touchless.Vision.Contracts.Frame frame, double fps)
{
//We want to ignore frames we can't render fast enough
lock (_frameSync)
{
if (!_frameWaiting)
{
_frameWaiting = true;
Action workAction = delegate
{
this.labelCameraFPSValue.Content = fps.ToString();
this.imgPreview.Source = frame.OriginalImage.ToBitmapSource();
 
lock (_frameSync)
{
_frameWaiting = false;
}
};
Dispatcher.BeginInvoke(workAction);
}
}
}
 
private void comboBoxCameras_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
_cameraFrameSource.Camera = comboBoxCameras.SelectedItem as Camera;
panelCameraInfo.Visibility = comboBoxCameras.SelectedItem != null
? Visibility.Visible
: Visibility.Collapsed;
}
 
private void buttonCameraProperties_Click(object sender, RoutedEventArgs e)
{
_cameraFrameSource.Camera.ShowPropertiesDialog();
}
 
private void chkLimitFps_Checked(object sender, RoutedEventArgs e)
{
this.txtLimitFps.IsEnabled = true;
updateFPS();
}
 
private void chkLimitFps_Unchecked(object sender, RoutedEventArgs e)
{
//this.txtLimitFps.Text = "-1";
this.txtLimitFps.Background = Brushes.White;
_cameraFrameSource.Camera.Fps = -1;
this.txtLimitFps.IsEnabled = false;
}
 
private void txtLimitFps_TextChanged(object sender, TextChangedEventArgs e)
{
updateFPS();
}
 
private void updateFPS()
{
int fps;
if (int.TryParse(this.txtLimitFps.Text, out fps))
{
_cameraFrameSource.Camera.Fps = fps;
this.txtLimitFps.Background = Brushes.LightGreen;
}
else
{
this.txtLimitFps.Background = Brushes.Red;
}
}
}
}
/MKLiveView/v1.0/Source/WebCamWrapper/Camera/WebCamLibInterop.cs
0,0 → 1,45
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
 
namespace Touchless.Vision.Camera
{
internal static class WebCamLibInterop
{
 
//[DllImport("WebCamLib.dll", EntryPoint = "Initialize")]
//public static extern int WebCamInitialize();
 
//[DllImport("WebCamLib.dll", EntryPoint = "Cleanup")]
//public static extern int WebCamCleanup();
 
//[DllImport("WebCamLib.dll", EntryPoint = "RefreshCameraList")]
//public static extern int WebCamRefreshCameraList(ref int count);
 
//[DllImport("WebCamLib.dll", EntryPoint = "GetCameraDetails")]
//public static extern int WebCamGetCameraDetails(int index,
// [Out, MarshalAs(UnmanagedType.Interface)] out object nativeInterface,
// out IntPtr name);
 
public delegate void CaptureCallbackProc(
UInt32 dwSize,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeParamIndex = 0)] byte[] abData);
 
//[DllImport("WebCamLib.dll", EntryPoint = "StartCamera")]
//public static extern int WebCamStartCamera(
// [In, MarshalAs(UnmanagedType.Interface)] object nativeInterface,
// CaptureCallbackProc lpCaptureFunc,
// ref int width,
// ref int height
// );
 
//[DllImport("WebCamLib.dll", EntryPoint = "StopCamera")]
//public static extern int WebCamStopCamera();
 
//[DllImport("WebCamLib.dll", EntryPoint = "DisplayCameraPropertiesDialog")]
//public static extern int WebCamDisplayCameraPropertiesDialog(
// [In, MarshalAs(UnmanagedType.Interface)] object nativeInterface);
}
}