private static void ReadExposure(Device device, Dictionary <string, CameraProperty> properties) { CameraProperty p = ReadFloatProperty(device, "ExposureTime"); if (!p.Supported) { p = ReadFloatProperty(device, "ExposureTimeAbs"); } string autoIdentifier = "ExposureAuto"; p.AutomaticIdentifier = autoIdentifier; p.CanBeAutomatic = false; p.Automatic = false; bool autoReadable = BaumerHelper.NodeIsReadable(device, p.AutomaticIdentifier); if (autoReadable) { p.CanBeAutomatic = true; string autoValue = BaumerHelper.GetString(device, p.AutomaticIdentifier); p.Automatic = autoValue == GetAutoTrue(autoIdentifier); } properties.Add("exposure", p); }
private static void ReadGain(Device device, Dictionary <string, CameraProperty> properties) { CameraProperty p = ReadFloatProperty(device, "Gain"); if (!p.Supported) { p = ReadIntegerProperty(device, "GainRaw", null); } string autoIdentifier = "GainAuto"; p.AutomaticIdentifier = autoIdentifier; p.CanBeAutomatic = false; p.Automatic = false; bool autoReadable = BaumerHelper.NodeIsReadable(device, p.AutomaticIdentifier); if (autoReadable) { p.CanBeAutomatic = true; string autoValue = BaumerHelper.GetString(device, p.AutomaticIdentifier); p.Automatic = autoValue == GetAutoTrue(autoIdentifier); } properties.Add("gain", p); }
public void Cancel() { log.DebugFormat("Cancelling thumbnail for {0}.", Alias); if (!baumerProvider.IsOpen) { return; } lock (locker) { baumerProvider.BufferProduced -= BaumerProducer_BufferProduced; baumerProvider.Stop(); if (wasJpegEnabled) { BaumerHelper.SetJPEG(baumerProvider.Device, true); } Close(); cancelled = true; } waitHandle.Set(); }
public override string GetSummaryAsText(CameraSummary summary) { string result = ""; string alias = summary.Alias; SpecificInfo info = summary.Specific as SpecificInfo; result = string.Format("{0}", alias); try { if (info != null && info.StreamFormat != null && info.CameraProperties.ContainsKey("width") && info.CameraProperties.ContainsKey("height") && info.CameraProperties.ContainsKey("framerate")) { string format = info.StreamFormat; int width = int.Parse(info.CameraProperties["width"].CurrentValue, CultureInfo.InvariantCulture); int height = int.Parse(info.CameraProperties["height"].CurrentValue, CultureInfo.InvariantCulture); double framerate = BaumerHelper.GetResultingFramerate(info.Device); if (framerate == 0) { framerate = double.Parse(info.CameraProperties["framerate"].CurrentValue, CultureInfo.InvariantCulture); } result = string.Format("{0} - {1}×{2} @ {3:0.##} fps ({4}).", alias, width, height, framerate, format); } } catch { } return(result); }
//private void imageProvider_GrabbingStartedEvent() //{ // grabbing = true; // if (GrabbingStatusChanged != null) // GrabbingStatusChanged(this, EventArgs.Empty); //} private void BaumerProvider_BufferProduced(object sender, BufferEventArgs e) { BGAPI2.Buffer buffer = e.Buffer; if (buffer == null || buffer.IsIncomplete || buffer.MemPtr == IntPtr.Zero) { return; } int payloadLength = (int)buffer.SizeFilled; // Wrap the buffer in an image, convert if needed. BGAPI2.Image image = imgProcessor.CreateImage((uint)buffer.Width, (uint)buffer.Height, buffer.PixelFormat, buffer.MemPtr, buffer.MemSize); bool ready = imageFormat == ImageFormat.JPEG || (imageFormat == ImageFormat.Y800 && BaumerHelper.IsY800(image.PixelFormat)); if (!ready) { // Color conversion is required. BGAPI2.Image transformedImage = GetTransformedImage(image); image.Release(); image = transformedImage; int bpp = BaumerHelper.IsY800(image.PixelFormat) ? 1 : 3; payloadLength = (int)(image.Width * image.Height * bpp); } CopyFrame(image, payloadLength); image.Release(); if (imageFormat != ImageFormat.JPEG && finishline.Enabled) { bool flush = finishline.Consolidate(frameBuffer); if (flush) { ComputeDataRate(finishline.BufferOutput.Length); if (FrameProduced != null) { FrameProduced(this, new FrameProducedEventArgs(finishline.BufferOutput, finishline.BufferOutput.Length)); } } } else { ComputeDataRate(payloadLength); if (FrameProduced != null) { FrameProduced(this, new FrameProducedEventArgs(frameBuffer, payloadLength)); } } }
private void Open() { if (grabbing) { Stop(); } try { baumerProvider.Open(specific.SystemKey, specific.InterfaceKey, specific.DeviceKey); } catch (Exception e) { log.Error("Could not open Baumer device."); LogError(e, ""); return; } if (!baumerProvider.IsOpen) { return; } // Store the device into the specific info so that we can retrieve device informations from the configuration dialog. specific.Device = baumerProvider.Device; if (!string.IsNullOrEmpty(specific.StreamFormat)) { BaumerHelper.WriteEnum(specific.Device, "PixelFormat", specific.StreamFormat); } if (firstOpen) { // Restore camera parameters from the XML blurb. // Regular properties, including image size. // First we read the current properties from the API to get fully formed properties. // We merge the values saved in the XML into the properties. // (The restoration from the XML doesn't create fully formed properties, it just contains the values). // Then commit the properties to the camera. Dictionary <string, CameraProperty> cameraProperties = CameraPropertyManager.Read(specific.Device, summary.Identifier); CameraPropertyManager.MergeProperties(cameraProperties, specific.CameraProperties); specific.CameraProperties = cameraProperties; CameraPropertyManager.WriteCriticalProperties(specific.Device, specific.CameraProperties); } else { CameraPropertyManager.WriteCriticalProperties(specific.Device, specific.CameraProperties); } }
private void PopulateStreamFormat() { lblColorSpace.Text = CameraLang.FormConfiguration_Properties_StreamFormat; bool readable = BaumerHelper.NodeIsReadable(device, "PixelFormat"); if (!readable) { cmbFormat.Enabled = false; return; } List <string> streamFormats = new List <string>(); NodeMap mapFormats = device.RemoteNodeList["PixelFormat"].EnumNodeList; for (ulong i = 0; i < mapFormats.Count; i++) { var node = mapFormats[i]; if (node.IsReadable) { streamFormats.Add(node.Value); } } if (streamFormats.Count == 0) { cmbFormat.Enabled = false; return; } // Sort correctly so that for example "Mono8" appears before "Mono10". // The selection is based on the string itself, not its index in the list. streamFormats.Sort(new AlphanumComparator()); string currentValue = BaumerHelper.GetString(device, "PixelFormat"); cmbFormat.Items.Clear(); foreach (var streamFormat in streamFormats) { cmbFormat.Items.Add(streamFormat); if (currentValue == streamFormat) { selectedStreamFormat = streamFormat; cmbFormat.SelectedIndex = cmbFormat.Items.Count - 1; } } }
private static CameraProperty ReadIntegerProperty(Device device, string symbol, string symbolMax) { CameraProperty p = new CameraProperty(); p.Identifier = symbol; bool readable = BaumerHelper.NodeIsReadable(device, symbol); if (!readable) { log.WarnFormat("Could not read Baumer property {0}: the property is not supported.", symbol); return(p); } p.Supported = true; p.Type = CameraPropertyType.Integer; p.ReadOnly = false; Node node = device.RemoteNodeList[symbol]; int currentValue = (int)node.Value; int min = (int)node.Min; int max = (int)node.Max; int step = (int)node.Inc; // Get the real max from another property, the bare max depends on the current offset. if (!string.IsNullOrEmpty(symbolMax)) { bool maxReadable = BaumerHelper.NodeIsReadable(device, symbolMax); if (maxReadable) { max = (int)device.RemoteNodeList[symbolMax].Value; } } bool highRange = (Math.Log10(max) - Math.Log10(min)) > 4; p.Minimum = min.ToString(CultureInfo.InvariantCulture); p.Maximum = max.ToString(CultureInfo.InvariantCulture); p.Step = step.ToString(CultureInfo.InvariantCulture); p.Representation = highRange ? CameraPropertyRepresentation.LogarithmicSlider : CameraPropertyRepresentation.LinearSlider; p.CurrentValue = currentValue.ToString(CultureInfo.InvariantCulture); return(p); }
private static CameraProperty ReadFloatProperty(Device device, string symbol) { CameraProperty p = new CameraProperty(); p.Identifier = symbol; bool readable = BaumerHelper.NodeIsReadable(device, symbol); if (!readable) { log.WarnFormat("Could not read Baumer property {0}: the property is not supported.", symbol); return(p); } p.Supported = true; p.Type = CameraPropertyType.Float; p.ReadOnly = false; Node node = device.RemoteNodeList[symbol]; double min = node.Min; double max = node.Max; string repr = node.Representation; double currentValue = node.Value; // We don't support a dedicated control for "pure numbers" just use the regular slider. if (repr == "PureNumber") { repr = "Linear"; } // Fix values that should be log. if ((Math.Log10(max) - Math.Log10(min)) > 4.0) { repr = "Logarithmic"; } p.Minimum = min.ToString(CultureInfo.InvariantCulture); p.Maximum = max.ToString(CultureInfo.InvariantCulture); p.Representation = ConvertRepresentation(repr); p.CurrentValue = currentValue.ToString(CultureInfo.InvariantCulture); return(p); }
private void UpdateResultingFramerate() { float resultingFramerate = BaumerHelper.GetResultingFramerate(device); lblResultingFramerateValue.Text = string.Format("{0:0.##}", resultingFramerate); bool discrepancy = false; if (cameraProperties.ContainsKey("framerate") && cameraProperties["framerate"].Supported) { float framerate; bool parsed = float.TryParse(cameraProperties["framerate"].CurrentValue, NumberStyles.Any, CultureInfo.InvariantCulture, out framerate); if (parsed && Math.Abs(framerate - resultingFramerate) > 1) { discrepancy = true; } } lblResultingFramerateValue.ForeColor = discrepancy ? Color.Red : Color.Black; }
/// <summary> /// Write generic property with optional auto flag. /// </summary> private static void WriteProperty(Device device, CameraProperty property) { if (property.ReadOnly) { return; } NodeMap nodeMap = device.RemoteNodeList; // Switch OFF the auto flag if needed, to be able to write the main property. if (!string.IsNullOrEmpty(property.AutomaticIdentifier)) { Node nodeAuto = BaumerHelper.GetNode(nodeMap, property.AutomaticIdentifier); if (nodeAuto != null) { bool writeable = nodeAuto.IsWriteable; bool currentAuto = ReadAuto(nodeAuto, property.AutomaticIdentifier); if (writeable && property.CanBeAutomatic && currentAuto && !property.Automatic) { WriteAuto(nodeAuto, property.AutomaticIdentifier, false); } } } // At this point the auto flag is off. Write the main property. Node node = BaumerHelper.GetNode(nodeMap, property.Identifier); if (node == null) { return; } if (!node.IsReadable || !node.IsWriteable) { return; } try { switch (property.Type) { case CameraPropertyType.Integer: { long value = long.Parse(property.CurrentValue, CultureInfo.InvariantCulture); long min = node.Min; long max = node.Max; long step = node.Inc; value = FixValue(value, min, max, step); node.Value = value; break; } case CameraPropertyType.Float: { double value = double.Parse(property.CurrentValue, CultureInfo.InvariantCulture); double min = node.Min; double max = node.Max; value = FixValue(value, min, max); node.Value = value; break; } case CameraPropertyType.Boolean: { bool value = bool.Parse(property.CurrentValue); node.Value = value; break; } default: break; } } catch { log.ErrorFormat("Error while writing Baumer GenICam property {0}.", property.Identifier); } // Finally, switch ON the auto flag if needed. if (!string.IsNullOrEmpty(property.AutomaticIdentifier)) { Node nodeAuto = BaumerHelper.GetNode(nodeMap, property.AutomaticIdentifier); if (nodeAuto != null && nodeAuto.IsWriteable && property.CanBeAutomatic && property.Automatic) { WriteAuto(nodeAuto, property.AutomaticIdentifier, true); } } }
/// <summary> /// Write either width or height as a centered region of interest. /// </summary> private static void WriteSize(Device device, CameraProperty property, string identifierOffset) { if (property.ReadOnly) { return; } NodeMap nodemap = device.RemoteNodeList; Node node = BaumerHelper.GetNode(nodemap, property.Identifier); if (node == null || !node.IsReadable || !node.IsWriteable) { return; } long value = long.Parse(property.CurrentValue, CultureInfo.InvariantCulture); long min = node.Min; long step = node.Inc; // Do not clamp on max, the max is based on the offset instead of the true max. value = Math.Max(value, min); long remainder = (value - min) % step; if (remainder != 0) { value = value - remainder + step; } // Offset handling. // Some cameras have a CenterX/CenterY property. // When it is set, the offset is automatic and becomes read-only. // If the offset can be written we use the normal computation. Node nodeOffset = BaumerHelper.GetNode(nodemap, identifierOffset); bool setOffset = nodeOffset != null && node.IsReadable && node.IsWriteable; if (setOffset) { long currentValue = node.Value; long max = currentValue + nodeOffset.Max; long offset = (max - value) / 2; long minOffset = nodeOffset.Min; long stepOffset = nodeOffset.Inc; long remainderOffset = (offset - minOffset) % stepOffset; if (remainderOffset != 0) { offset = offset - remainderOffset + stepOffset; } // We need to be careful with the order and not write a value that doesn't fit due to the offset, or vice versa. if (value > currentValue) { nodeOffset.Value = offset; node.Value = value; } else { node.Value = value; nodeOffset.Value = offset; } } else { node.Value = value; } }
/// <summary> /// Configure device and report frame format that will be used during streaming. /// This method must return a proper ImageDescriptor so we can pre-allocate buffers. /// </summary> public ImageDescriptor Prepare() { Open(); if (!baumerProvider.IsOpen) { return(ImageDescriptor.Invalid); } firstOpen = false; Device device = baumerProvider.Device; // Get the configured framerate for recording support. resultingFramerate = BaumerHelper.GetResultingFramerate(device); bool hasWidth = BaumerHelper.NodeIsReadable(device, "Width"); bool hasHeight = BaumerHelper.NodeIsReadable(device, "Height"); bool hasPixelFormat = BaumerHelper.NodeIsReadable(device, "PixelFormat"); bool canComputeImageDescriptor = hasWidth && hasHeight && hasPixelFormat; if (!canComputeImageDescriptor) { return(ImageDescriptor.Invalid); } int width = BaumerHelper.GetInteger(device, "Width"); int height = BaumerHelper.GetInteger(device, "Height"); string pixelFormat = BaumerHelper.GetString(device, "PixelFormat"); // We output in three possible formats: Y800, RGB24 or JPEG. // The output format depends on the stream format and the options. // Mono or raw -> Y800, Otherwise -> RGB24. // Camera-side JPEG compression. compression = specific.Compression; if (BaumerHelper.SupportsJPEG(device)) { if (BaumerHelper.FormatCanCompress(device, pixelFormat)) { BaumerHelper.SetJPEG(device, compression); } else { BaumerHelper.SetJPEG(device, false); compression = false; } } else { compression = false; } // Debayering. demosaicing = specific.Demosaicing; if (demosaicing) { if (imgProcessor.NodeList.GetNodePresent("DemosaicingMethod")) { // Options: NearestNeighbor, Bilinear3x3, Baumer5x5 imgProcessor.NodeList["DemosaicingMethod"].Value = "NearestNeighbor"; } else { demosaicing = false; } } imageFormat = BaumerHelper.ConvertImageFormat(pixelFormat, compression, demosaicing); frameBufferSize = ImageFormatHelper.ComputeBufferSize(width, height, imageFormat); frameBuffer = new byte[frameBufferSize]; finishline.Prepare(width, height, imageFormat, resultingFramerate); if (finishline.Enabled) { height = finishline.Height; resultingFramerate = finishline.ResultingFramerate; } int outgoingBufferSize = ImageFormatHelper.ComputeBufferSize(width, height, imageFormat); bool topDown = true; return(new ImageDescriptor(imageFormat, width, height, topDown, outgoingBufferSize)); }
private void SetExtraOptionsVisibility() { cbDebayering.Enabled = BaumerHelper.IsBayer(selectedStreamFormat); cbCompression.Enabled = BaumerHelper.SupportsJPEG(device) && BaumerHelper.FormatCanCompress(device, selectedStreamFormat); }
/// <summary> /// Start the device for a frame grab, wait a bit and then return the result. /// This method MUST raise a CameraThumbnailProduced event, even in case of error. /// </summary> public void Run(object data) { log.DebugFormat("Starting {0} for thumbnail.", summary.Alias); SpecificInfo specific = summary.Specific as SpecificInfo; bool opened = baumerProvider.Open(specific.SystemKey, specific.InterfaceKey, specific.DeviceKey); if (!opened) { log.DebugFormat("Could not open {0} for thumbnail.", summary.Alias); if (CameraThumbnailProduced != null) { CameraThumbnailProduced(this, new CameraThumbnailProducedEventArgs(summary, null, ImageDescriptor.Invalid, true, false)); } return; } baumerProvider.BufferProduced += BaumerProducer_BufferProduced; // Do not use JPEG compression for the thumbnail. wasJpegEnabled = BaumerHelper.GetJPEG(baumerProvider.Device); if (wasJpegEnabled) { BaumerHelper.SetJPEG(baumerProvider.Device, false); } try { baumerProvider.AcquireOne(); } catch (Exception e) { hadError = true; LogError(e, null); } if (!hadError) { waitHandle.WaitOne(timeoutGrabbing, false); } lock (locker) { if (!cancelled) { baumerProvider.BufferProduced -= BaumerProducer_BufferProduced; baumerProvider.Stop(); if (wasJpegEnabled) { BaumerHelper.SetJPEG(baumerProvider.Device, true); } Close(); log.DebugFormat("{0} closed.", summary.Alias); } } if (CameraThumbnailProduced != null) { CameraThumbnailProduced(this, new CameraThumbnailProducedEventArgs(summary, image, imageDescriptor, hadError, cancelled)); } }