static Func <IManagedImage, IplImage> GetConverter(PixelFormatEnums pixelFormat, ColorProcessingAlgorithm colorProcessing) { int outputChannels; IplDepth outputDepth; if (pixelFormat < PixelFormatEnums.BayerGR8 || pixelFormat == PixelFormatEnums.BGR8 || pixelFormat <= PixelFormatEnums.BayerBG16 && colorProcessing == ColorProcessingAlgorithm.NoColorProcessing) { if (pixelFormat == PixelFormatEnums.BGR8) { outputChannels = 3; outputDepth = IplDepth.U8; } else { outputChannels = 1; var depthFactor = (int)pixelFormat; if (pixelFormat > PixelFormatEnums.Mono16) { depthFactor = (depthFactor - 3) / 4; } outputDepth = (IplDepth)(8 * (depthFactor + 1)); } return(image => { var width = (int)image.Width; var height = (int)image.Height; using (var bitmapHeader = new IplImage(new Size(width, height), outputDepth, outputChannels, image.DataPtr)) { var output = new IplImage(bitmapHeader.Size, outputDepth, outputChannels); CV.Copy(bitmapHeader, output); return output; } }); } PixelFormatEnums outputFormat; if (pixelFormat == PixelFormatEnums.Mono12p || pixelFormat == PixelFormatEnums.Mono12Packed) { outputFormat = PixelFormatEnums.Mono16; outputDepth = IplDepth.U16; outputChannels = 1; } else if (pixelFormat >= PixelFormatEnums.BayerGR8 && pixelFormat <= PixelFormatEnums.BayerBG16) { outputFormat = PixelFormatEnums.BGR8; outputDepth = IplDepth.U8; outputChannels = 3; } else { throw new InvalidOperationException(string.Format("Unable to convert pixel format {0}.", pixelFormat)); } return(image => { var width = (int)image.Width; var height = (int)image.Height; var output = new IplImage(new Size(width, height), outputDepth, outputChannels); unsafe { using (var destination = new ManagedImage((uint)width, (uint)height, 0, 0, outputFormat, output.ImageData.ToPointer())) { image.Convert(destination, outputFormat, (SpinnakerNET.ColorProcessingAlgorithm)colorProcessing); return output; } } }); }
public FlyCapture() { ColorProcessing = ColorProcessingAlgorithm.Default; source = Observable.Create <FlyCaptureDataFrame>((observer, cancellationToken) => { return(Task.Factory.StartNew(() => { lock (captureLock) { ManagedCamera camera; using (var manager = new ManagedBusManager()) { var guid = manager.GetCameraFromIndex((uint)Index); camera = new ManagedCamera(); camera.Connect(guid); // Power on the camera const uint CameraPower = 0x610; const uint CameraPowerValue = 0x80000000; camera.WriteRegister(CameraPower, CameraPowerValue); // Wait for camera to complete power-up const Int32 MillisecondsToSleep = 100; uint cameraPowerValueRead = 0; do { Thread.Sleep(MillisecondsToSleep); cameraPowerValueRead = camera.ReadRegister(CameraPower); }while ((cameraPowerValueRead & CameraPowerValue) == 0); } var capture = 0; try { // Set frame rate var prop = new CameraProperty(PropertyType.FrameRate); prop.absControl = true; prop.absValue = FramesPerSecond; prop.autoManualMode = false; prop.onOff = true; camera.SetProperty(prop); // Enable/disable blackfly pull up const uint pullUp = 0x19D0; if (EnableBlackflyOutputVoltage) { camera.WriteRegister(pullUp, 0x10000001); } else { camera.WriteRegister(pullUp, 0x10000000); } // Acquisition parameters var colorProcessing = ColorProcessing; var autoExposure = !AutoExposure; // Horrible hack to trigger update inititally var shutter = Shutter; var gain = Gain; // Configure embedded info const uint embeddedInfo = 0x12F8; uint embeddedInfoState = camera.ReadRegister(embeddedInfo); if (EnableEmbeddedFrameCounter) { embeddedInfoState |= (uint)1 << 6; } else { embeddedInfoState &= ~((uint)1 << 6); } if (EnableEmbeddedFrameTimeStamp) { embeddedInfoState |= (uint)1 << 0; } else { embeddedInfoState &= ~((uint)1 << 0); } camera.WriteRegister(embeddedInfo, embeddedInfoState); using (var image = new ManagedImage()) using (var notification = cancellationToken.Register(() => { Interlocked.Exchange(ref capture, 0); camera.StopCapture(); })) { camera.StartCapture(); Interlocked.Exchange(ref capture, 1); while (!cancellationToken.IsCancellationRequested) { IplImage output; BayerTileFormat bayerTileFormat; if (autoExposure != AutoExposure && AutoExposure) { prop = new CameraProperty(PropertyType.AutoExposure); prop.autoManualMode = true; prop.onOff = true; camera.SetProperty(prop); autoExposure = AutoExposure; // Shutter prop = new CameraProperty(PropertyType.Shutter); prop.absControl = true; prop.autoManualMode = true; prop.onOff = true; camera.SetProperty(prop); // Shutter prop = new CameraProperty(PropertyType.Gain); prop.absControl = true; prop.autoManualMode = true; prop.onOff = true; camera.SetProperty(prop); autoExposure = AutoExposure; } else if (autoExposure != AutoExposure && !AutoExposure) { shutter = -0.1f; // Hack gain = -0.1f; autoExposure = AutoExposure; } if (shutter != Shutter && !AutoExposure) { // Figure out max shutter time given current frame rate var info = camera.GetPropertyInfo(PropertyType.Shutter); var delta = info.absMax - info.absMin; prop = new CameraProperty(PropertyType.Shutter); prop.absControl = true; prop.absValue = Shutter * delta + info.absMin; prop.autoManualMode = false; prop.onOff = true; camera.SetProperty(prop); shutter = Shutter; } if (gain != Gain && !AutoExposure) { // Figure out max shutter time given current frame rate var info = camera.GetPropertyInfo(PropertyType.Shutter); var delta = info.absMax - info.absMin; prop = new CameraProperty(PropertyType.Gain); prop.absControl = true; prop.absValue = Gain * delta + info.absMin;; prop.autoManualMode = false; prop.onOff = true; camera.SetProperty(prop); gain = Gain; } try { camera.RetrieveBuffer(image); } catch (FC2Exception ex) { if (capture == 0) { break; } else if (IgnoreImageConsistencyError && ex.CauseType == ErrorType.ImageConsistencyError) { continue; } else { throw; } } if (image.pixelFormat == PixelFormat.PixelFormatMono8 || image.pixelFormat == PixelFormat.PixelFormatMono16 || (image.pixelFormat == PixelFormat.PixelFormatRaw8 && (image.bayerTileFormat == BayerTileFormat.None || colorProcessing == ColorProcessingAlgorithm.NoColorProcessing))) { unsafe { bayerTileFormat = image.bayerTileFormat; var depth = image.pixelFormat == PixelFormat.PixelFormatMono16 ? IplDepth.U16 : IplDepth.U8; var bitmapHeader = new IplImage(new Size((int)image.cols, (int)image.rows), depth, 1, new IntPtr(image.data)); output = new IplImage(bitmapHeader.Size, bitmapHeader.Depth, bitmapHeader.Channels); CV.Copy(bitmapHeader, output); } } else { unsafe { bayerTileFormat = BayerTileFormat.None; output = new IplImage(new Size((int)image.cols, (int)image.rows), IplDepth.U8, 3); using (var convertedImage = new ManagedImage( (uint)output.Height, (uint)output.Width, (uint)output.WidthStep, (byte *)output.ImageData.ToPointer(), (uint)(output.WidthStep * output.Height), PixelFormat.PixelFormatBgr)) { convertedImage.colorProcessingAlgorithm = colorProcessing; image.Convert(PixelFormat.PixelFormatBgr, convertedImage); } } } observer.OnNext(new FlyCaptureDataFrame(output, image.imageMetadata, bayerTileFormat)); } } } finally { // Power off the camera const uint CameraPower = 0x610; const uint CameraPowerValue = 0x00000000; camera.WriteRegister(CameraPower, CameraPowerValue); if (capture != 0) { camera.StopCapture(); } camera.Disconnect(); camera.Dispose(); } } }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Default)); }) .PublishReconnectable() .RefCount(); }