예제 #1
0
        private void Open()
        {
            if (grabbing)
            {
                Stop();
            }

            try
            {
                deviceHandle = Pylon.CreateDeviceByIndex(deviceIndex);
                imageProvider.Open(deviceHandle);
            }
            catch (Exception e)
            {
                log.Error("Could not open Basler device.");
                LogError(e, imageProvider.GetLastErrorMessage());
                return;
            }

            if (!deviceHandle.IsValid)
            {
                return;
            }

            SpecificInfo specific = summary.Specific as SpecificInfo;

            if (specific == null)
            {
                return;
            }

            // Store the handle into the specific info so that we can retrieve device informations from the configuration dialog.
            specific.Handle = deviceHandle;
            GenApiEnum currentStreamFormat = PylonHelper.ReadEnumCurrentValue(deviceHandle, "PixelFormat");

            if (!string.IsNullOrEmpty(specific.StreamFormat) && specific.StreamFormat != currentStreamFormat.Symbol)
            {
                PylonHelper.WriteEnum(deviceHandle, "PixelFormat", specific.StreamFormat);
            }

            // The bayer conversion mode will be set during Prepare().

            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(deviceHandle, summary.Identifier);
                CameraPropertyManager.MergeProperties(cameraProperties, specific.CameraProperties);
                specific.CameraProperties = cameraProperties;
                CameraPropertyManager.WriteCriticalProperties(deviceHandle, specific.CameraProperties);
            }
            else
            {
                CameraPropertyManager.WriteCriticalProperties(deviceHandle, specific.CameraProperties);
            }
        }
예제 #2
0
        private void PopulateStreamFormat()
        {
            lblColorSpace.Text = CameraLang.FormConfiguration_Properties_StreamFormat;

            bool readable = Pylon.DeviceFeatureIsReadable(deviceHandle, "PixelFormat");

            if (!readable)
            {
                cmbFormat.Enabled = false;
                return;
            }

            string currentValue = Pylon.DeviceFeatureToString(deviceHandle, "PixelFormat");

            List <GenApiEnum> streamFormats = PylonHelper.ReadEnum(deviceHandle, "PixelFormat");

            if (streamFormats == null)
            {
                cmbFormat.Enabled = false;
                return;
            }

            foreach (GenApiEnum streamFormat in streamFormats)
            {
                cmbFormat.Items.Add(streamFormat);
                if (currentValue == streamFormat.Symbol)
                {
                    selectedStreamFormat    = streamFormat;
                    cmbFormat.SelectedIndex = cmbFormat.Items.Count - 1;
                }
            }
        }
예제 #3
0
        private void PopulateStreamFormat()
        {
            bool readable = Pylon.DeviceFeatureIsReadable(deviceHandle, "PixelFormat");

            if (!readable)
            {
                cmbFormat.Enabled = false;
                return;
            }

            string currentValue = Pylon.DeviceFeatureToString(deviceHandle, "PixelFormat");

            List <StreamFormat> streamFormats = PylonHelper.GetSupportedStreamFormats(deviceHandle);

            if (streamFormats == null)
            {
                cmbFormat.Enabled = false;
                return;
            }

            foreach (StreamFormat streamFormat in streamFormats)
            {
                cmbFormat.Items.Add(streamFormat);
                if (currentValue == streamFormat.Symbol)
                {
                    selectedStreamFormat    = streamFormat;
                    cmbFormat.SelectedIndex = cmbFormat.Items.Count - 1;
                }
            }
        }
예제 #4
0
        private void SetBayerComboVisibility()
        {
            EPylonPixelType pixelType = Pylon.PixelTypeFromString(selectedStreamFormat.Symbol);
            bool            isBayer8  = PylonHelper.IsBayer8(pixelType);

            cmbBayer8Conversion.Enabled = isBayer8;
            lblBayerConversion.Enabled  = isBayer8;
        }
예제 #5
0
 private void Populate()
 {
     try
     {
         PopulateStreamFormat();
         PopulateCameraControls();
     }
     catch
     {
         log.ErrorFormat(PylonHelper.GetLastError());
     }
 }
예제 #6
0
 private void Populate(SpecificInfo specific)
 {
     try
     {
         PopulateStreamFormat();
         PopulateBayerConversion();
         PopulateCameraControls();
     }
     catch
     {
         log.ErrorFormat(PylonHelper.GetLastError());
     }
 }
예제 #7
0
        private void cmbBayerConversion_SelectedIndexChanged(object sender, EventArgs e)
        {
            EPylonPixelType pixelType = Pylon.PixelTypeFromString(selectedStreamFormat.Symbol);
            bool            isBayer8  = PylonHelper.IsBayer8(pixelType);

            Bayer8Conversion selected = (Bayer8Conversion)cmbBayer8Conversion.SelectedIndex;

            if (selected == bayer8Conversion)
            {
                return;
            }

            bayer8Conversion = (Bayer8Conversion)cmbBayer8Conversion.SelectedIndex;
            specificChanged  = true;
        }
예제 #8
0
        private static void ReadGain(PYLON_DEVICE_HANDLE deviceHandle, Dictionary <string, CameraProperty> properties)
        {
            CameraProperty prop = ReadFloatProperty(deviceHandle, "Gain");

            if (!prop.Supported)
            {
                prop = ReadIntegerProperty(deviceHandle, "GainRaw");
            }

            prop.CanBeAutomatic      = true;
            prop.AutomaticIdentifier = "GainAuto";
            GenApiEnum auto = PylonHelper.ReadEnumCurrentValue(deviceHandle, prop.AutomaticIdentifier);

            prop.Automatic = auto != null && auto.Symbol == "Continuous";
            properties.Add("gain", prop);
        }
예제 #9
0
        public override string GetSummaryAsText(CameraSummary summary)
        {
            string result = "";
            string alias  = summary.Alias;

            SpecificInfo info = summary.Specific as SpecificInfo;

            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 = 0;

                    // The configured framerate is always between 0 and 100 000, but the actual resulting framerate can be obtained.
                    if (info.Handle != null && info.Handle.IsValid)
                    {
                        framerate = PylonHelper.GetResultingFramerate(info.Handle);
                    }
                    else
                    {
                        framerate = double.Parse(info.CameraProperties["framerate"].CurrentValue, CultureInfo.InvariantCulture);
                    }

                    result = string.Format("{0} - {1}×{2} @ {3:0.##} fps ({4}).", alias, width, height, framerate, format);
                }
                else
                {
                    result = string.Format("{0}", alias);
                }
            }
            catch
            {
                result = string.Format("{0}", alias);
            }

            return(result);
        }
예제 #10
0
        private void Populate()
        {
            try
            {
                PopulateStreamFormat();
                PopulateBayerConversion();
                PopulateCameraControls();
            }
            catch
            {
                string error = PylonHelper.GetLastError();
                if (string.IsNullOrEmpty(error))
                {
                    error = "Unknown";
                }

                log.ErrorFormat("Error while populating configuration options. Pylon error: {0}", error);
            }
        }
예제 #11
0
        private void UpdateResultingFramerate()
        {
            float resultingFramerate = PylonHelper.GetResultingFramerate(deviceHandle);

            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;
        }
예제 #12
0
        private static void ReadExposure(PYLON_DEVICE_HANDLE deviceHandle, string deviceClass, Dictionary <string, CameraProperty> properties)
        {
            CameraProperty prop = null;

            if (deviceClass == "BaslerUsb")
            {
                prop = ReadFloatProperty(deviceHandle, "ExposureTime");
            }
            else
            {
                prop = ReadFloatProperty(deviceHandle, "ExposureTimeAbs");
            }

            prop.CanBeAutomatic      = true;
            prop.AutomaticIdentifier = "ExposureAuto";
            GenApiEnum auto = PylonHelper.ReadEnumCurrentValue(deviceHandle, prop.AutomaticIdentifier);

            prop.Automatic = auto.Symbol == "Continuous";
            properties.Add("exposure", prop);
        }
예제 #13
0
        /// <summary>
        /// Takes a boolean of whether auto is ON or OFF, convert it to the correct representation and write it in the auto property.
        /// </summary>
        private static void WriteAuto(NODE_HANDLE nodeHandle, string identifier, bool isAuto)
        {
            string newValue = isAuto ? GetAutoTrue(identifier) : GetAutoFalse(identifier);

            switch (identifier)
            {
            case "AcquisitionFrameRateEnable":
            {
                bool newValueBool = bool.Parse(newValue);
                GenApi.BooleanSetValue(nodeHandle, newValueBool);
                break;
            }

            case "GainAuto":
            case "ExposureAuto":
            default:
            {
                PylonHelper.WriteEnum(nodeHandle, identifier, newValue);
                break;
            }
            }
        }
예제 #14
0
        private static void ReadGain(PYLON_DEVICE_HANDLE deviceHandle, Dictionary <string, CameraProperty> properties)
        {
            CameraProperty p = ReadFloatProperty(deviceHandle, "Gain");

            if (!p.Supported)
            {
                p = ReadIntegerProperty(deviceHandle, "GainRaw", null);
            }

            string autoIdentifier = "GainAuto";

            p.AutomaticIdentifier = autoIdentifier;
            GenApiEnum auto = PylonHelper.ReadEnumCurrentValue(deviceHandle, p.AutomaticIdentifier);

            p.CanBeAutomatic = auto != null;
            p.Automatic      = false;
            if (p.CanBeAutomatic && !string.IsNullOrEmpty(auto.Symbol))
            {
                p.Automatic = auto.Symbol == GetAutoTrue(autoIdentifier);
            }

            properties.Add("gain", p);
        }
예제 #15
0
        public static void Write(PYLON_DEVICE_HANDLE deviceHandle, CameraProperty property)
        {
            if (!property.Supported || string.IsNullOrEmpty(property.Identifier) || !deviceHandle.IsValid)
            {
                return;
            }

            // If "auto" flag is OFF we should write it first. On some cameras the value is not writable until the corresponding auto flag is off.
            // If it's ON (continuous), it doesn't matter as our value will be overwritten soon anyway.
            if (!string.IsNullOrEmpty(property.AutomaticIdentifier))
            {
                string enumValue = property.Automatic ? "Continuous" : "Off";
                PylonHelper.WriteEnum(deviceHandle, property.AutomaticIdentifier, enumValue);
            }

            NODEMAP_HANDLE nodeMapHandle = Pylon.DeviceGetNodeMap(deviceHandle);
            NODE_HANDLE    nodeHandle    = GenApi.NodeMapGetNode(nodeMapHandle, property.Identifier);

            if (!nodeHandle.IsValid)
            {
                return;
            }

            EGenApiAccessMode accessMode = GenApi.NodeGetAccessMode(nodeHandle);

            if (accessMode != EGenApiAccessMode.RW)
            {
                if (!string.IsNullOrEmpty(property.AutomaticIdentifier) && !property.Automatic)
                {
                    log.ErrorFormat("Error while writing Basler Pylon GenICam property {0}.", property.Identifier);
                    log.ErrorFormat("The property is not writable.");
                }

                return;
            }

            try
            {
                switch (property.Type)
                {
                case CameraPropertyType.Integer:
                {
                    long value     = long.Parse(property.CurrentValue, CultureInfo.InvariantCulture);
                    long step      = long.Parse(property.Step, CultureInfo.InvariantCulture);
                    long remainder = value % step;
                    if (remainder > 0)
                    {
                        value = value - remainder;
                    }

                    GenApi.IntegerSetValue(nodeHandle, value);
                    break;
                }

                case CameraPropertyType.Float:
                {
                    double max   = GenApi.FloatGetMax(nodeHandle);
                    double min   = GenApi.FloatGetMin(nodeHandle);
                    double value = double.Parse(property.CurrentValue, CultureInfo.InvariantCulture);
                    value = Math.Min(Math.Max(value, min), max);

                    GenApi.FloatSetValue(nodeHandle, value);
                    break;
                }

                case CameraPropertyType.Boolean:
                {
                    bool value = bool.Parse(property.CurrentValue);
                    GenApi.BooleanSetValue(nodeHandle, value);
                    break;
                }

                default:
                    break;
                }
            }
            catch
            {
                log.ErrorFormat("Error while writing Basler Pylon GenICam property {0}.", property.Identifier);
            }
        }
예제 #16
0
        /// <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 (deviceHandle == null || !deviceHandle.IsValid)
            {
                return(ImageDescriptor.Invalid);
            }

            firstOpen = false;

            // Get the configured framerate for recording support.
            resultingFramerate = PylonHelper.GetResultingFramerate(deviceHandle);

            SpecificInfo specific           = summary.Specific as SpecificInfo;
            string       streamFormatSymbol = specific.StreamFormat;

            bool hasWidth                  = Pylon.DeviceFeatureIsReadable(deviceHandle, "Width");
            bool hasHeight                 = Pylon.DeviceFeatureIsReadable(deviceHandle, "Height");
            bool hasPixelFormat            = Pylon.DeviceFeatureIsReadable(deviceHandle, "PixelFormat");
            bool canComputeImageDescriptor = hasWidth && hasHeight && hasPixelFormat;

            if (!canComputeImageDescriptor)
            {
                return(ImageDescriptor.Invalid);
            }

            int    width       = (int)Pylon.DeviceGetIntegerFeature(deviceHandle, "Width");
            int    height      = (int)Pylon.DeviceGetIntegerFeature(deviceHandle, "Height");
            string pixelFormat = Pylon.DeviceFeatureToString(deviceHandle, "PixelFormat");

            EPylonPixelType pixelType = Pylon.PixelTypeFromString(pixelFormat);

            if (pixelType == EPylonPixelType.PixelType_Undefined)
            {
                return(ImageDescriptor.Invalid);
            }

            // Note: the image provider will perform the Bayer conversion itself and only output two formats.
            // - Y800 for anything monochrome.
            // - RGB32 for anything color.
            imageProvider.SetDebayering(specific.Bayer8Conversion);

            bool        isBayer    = Pylon.IsBayer(pixelType);
            bool        isBayer8   = PylonHelper.IsBayer8(pixelType);
            bool        bayerColor = (isBayer && !isBayer8) || (isBayer8 && specific.Bayer8Conversion == Bayer8Conversion.Color);
            bool        color      = !Pylon.IsMono(pixelType) || bayerColor;
            ImageFormat format     = color ? ImageFormat.RGB32 : ImageFormat.Y800;

            finishline.Prepare(width, height, format, resultingFramerate);
            if (finishline.Enabled)
            {
                height             = finishline.Height;
                resultingFramerate = finishline.ResultingFramerate;
            }

            int  bufferSize = ImageFormatHelper.ComputeBufferSize(width, height, format);
            bool topDown    = true;

            return(new ImageDescriptor(format, width, height, topDown, bufferSize));
        }
예제 #17
0
        private void Open()
        {
            // Unlike in the DirectShow module, we do not backup and restore camera configuration.
            // If the user configured the camera outside of Kinovea we respect the new settings.
            // Two reasons:
            // 1. In DirectShow we must do the backup/restore to work around drivers that inadvertently reset the camera properties.
            // 2. Industrial cameras have many properties that won't be configurable in Kinovea
            // so the user is more likely to configure the camera from the outside.

            if (grabbing)
            {
                Stop();
            }

            try
            {
                deviceHandle = Pylon.CreateDeviceByIndex(deviceIndex);
                imageProvider.Open(deviceHandle);
            }
            catch (Exception e)
            {
                log.Error("Could not open Basler device.");
                LogError(e, imageProvider.GetLastErrorMessage());
                return;
            }

            if (!deviceHandle.IsValid)
            {
                return;
            }

            SpecificInfo specific = summary.Specific as SpecificInfo;

            if (specific == null)
            {
                return;
            }

            // Store the handle into the specific info so that we can retrieve device informations from the configuration dialog.
            specific.Handle = deviceHandle;

            GenApiEnum currentStreamFormat = PylonHelper.ReadEnumCurrentValue(deviceHandle, "PixelFormat");

            // Some properties can only be changed when the camera is opened but not streaming.
            // We store them in the summary when coming back from FormConfiguration, and we write them to the camera here.
            // Only do this if it's not the first time we open the camera, to respect any change that could have been done outside Kinovea.
            if (!firstOpen)
            {
                if (specific.StreamFormat != currentStreamFormat.Symbol)
                {
                    PylonHelper.WriteEnum(deviceHandle, "PixelFormat", specific.StreamFormat);
                }

                if (specific.CameraProperties != null && specific.CameraProperties.ContainsKey("framerate"))
                {
                    if (specific.CameraProperties.ContainsKey("enableFramerate") && specific.CameraProperties["enableFramerate"].Supported)
                    {
                        bool enabled = bool.Parse(specific.CameraProperties["enableFramerate"].CurrentValue);
                        if (!enabled && !specific.CameraProperties["enableFramerate"].ReadOnly)
                        {
                            specific.CameraProperties["enableFramerate"].CurrentValue = "true";
                            CameraPropertyManager.Write(deviceHandle, specific.CameraProperties["enableFramerate"]);
                        }
                    }

                    CameraPropertyManager.Write(deviceHandle, specific.CameraProperties["framerate"]);
                }

                if (specific.CameraProperties != null && specific.CameraProperties.ContainsKey("width") && specific.CameraProperties.ContainsKey("height"))
                {
                    CameraPropertyManager.Write(deviceHandle, specific.CameraProperties["width"]);
                    CameraPropertyManager.Write(deviceHandle, specific.CameraProperties["height"]);
                }
            }
            else
            {
                specific.StreamFormat = currentStreamFormat.Symbol;
            }
        }