Exemple #1
0
        // TODO: The order of data in the matrix is reverse of the channel index.
        // m[11] => channel 0, etc.
        protected override void Write(ONIContextTask ctx, Arr input)
        {
            var inputMatrix = input.GetMat();

            // Check dims
            var size = inputMatrix.Rows * inputMatrix.Cols;

            if (size % AnalogInputDataFrame.NumberOfChannels != 0)
            {
                throw new IndexOutOfRangeException("Source must contain a multiple of 12 elements.");
            }

            if (DataType == AnalogDataType.S16 && inputMatrix.Depth == Depth.S16)
            {
                var data = new Mat(inputMatrix.Size, Depth.U16, 1);
                CV.ConvertScale(inputMatrix, data, 1, 32768);
                ctx.Write((uint)DeviceAddress.Address, data.Data, 2 * size);
            }
            else if (DataType == AnalogDataType.Volts && (inputMatrix.Depth == Depth.F32 || inputMatrix.Depth == Depth.F64))
            {
                var data = new Mat(inputMatrix.Size, Depth.U16, 1);
                CV.ConvertScale(inputMatrix, data, 3276.75, 32768);
                ctx.Write((uint)DeviceAddress.Address, data.Data, 2 * size);
            }
            else
            {
                throw new Bonsai.WorkflowRuntimeException("Source element depth must Depth.S16 when " +
                                                          "DataType is S16 and either Depth.F32 or Depth.F64 when Datatype is Volts.");
            }
        }
Exemple #2
0
        private Mat GetEphysDataF32(short[,] data)
        {
            var output = new Mat(NumberOfEphysChannels, NumberOfSamples, Depth.F32, 1);

            using (var header = Mat.CreateMatHeader(data))
            {
                CV.ConvertScale(header, output, 0.195);
            }

            return(output);
        }
Exemple #3
0
 protected override IObservable <IplImage> GetImageSource(IObservable <IObservable <object> > dataSource)
 {
     return(imageSource.Select(image =>
     {
         if (image.Depth != IplDepth.U8)
         {
             var normalizedImage = new IplImage(image.Size, IplDepth.U8, image.Channels);
             var scale = byte.MaxValue / (double)ushort.MaxValue;
             CV.ConvertScale(image, normalizedImage, scale);
             image = normalizedImage;
         }
         return image;
     }));
 }
Exemple #4
0
        public override IObservable <IplImage> Process(IObservable <IplImage> source)
        {
            return(source.Select(input =>
            {
                double min, max;
                Point minLoc, maxLoc;
                var output = new IplImage(input.Size, IplDepth.F32, input.Channels);
                CV.MinMaxLoc(input, out min, out max, out minLoc, out maxLoc);

                var range = max - min;
                var scale = range > 0 ? 1.0 / range : 0;
                var shift = range > 0 ? -min : 0;
                CV.ConvertScale(input, output, scale, shift);
                return output;
            }));
        }
        public override IObservable <Mat> Process(IObservable <Mat> source)
        {
            return(source.Select(input =>
            {
                var channels = Channels;
                var output = new Mat(input.Size, input.Depth, input.Channels);
                var reference = new Mat(1, input.Cols, input.Depth, input.Channels);
                if (channels == null || channels.Length == 0)
                {
                    if (input.Depth != Depth.F32)
                    {
                        var temp = new Mat(reference.Rows, reference.Cols, Depth.F32, reference.Channels);
                        CV.Reduce(input, temp, 0, ReduceOperation.Avg);
                        CV.Convert(temp, reference);
                    }
                    else
                    {
                        CV.Reduce(input, reference, 0, ReduceOperation.Avg);
                    }
                }
                else if (channels.Length == 1)
                {
                    CV.Copy(input.GetRow(channels[0]), reference);
                }
                else
                {
                    var sum = input.Depth != Depth.F32
                        ? new Mat(reference.Rows, reference.Cols, Depth.F32, reference.Channels)
                        : reference;
                    sum.SetZero();
                    for (int i = 0; i < channels.Length; i++)
                    {
                        using (var referenceChannel = input.GetRow(channels[i]))
                        {
                            CV.Add(sum, referenceChannel, sum);
                        }
                    }

                    CV.ConvertScale(sum, reference, 1f / channels.Length);
                }

                CV.Repeat(reference, output);
                CV.Sub(input, output, output);
                return output;
            }));
        }
Exemple #6
0
 private Mat GetAuxiliaryData(ushort[,] data)
 {
     using (var header = Mat.CreateMatHeader(data))
     {
         if (AuxFormat == RHD2164Configuration.AuxDataFormat.Volts)
         {
             var output = new Mat(NumberOfAuxChannels, NumberOfSamples, Depth.F32, 1);
             CV.ConvertScale(header, output, 0.0000374);
             return(output);
         }
         else
         {
             var output = new Mat(NumberOfAuxChannels, NumberOfSamples, Depth.U16, 1);
             CV.Convert(header, output);
             return(output);
         }
     }
 }
        public override IObservable <IplImage> Process(IObservable <IplImage> source)
        {
            return(Observable.Defer(() =>
            {
                int averageCount = 0;
                IplImage image = null;
                IplImage difference = null;
                IplImage background = null;
                return source.Select(input =>
                {
                    if (background == null || background.Size != input.Size)
                    {
                        averageCount = 0;
                        image = new IplImage(input.Size, IplDepth.F32, input.Channels);
                        difference = new IplImage(input.Size, IplDepth.F32, input.Channels);
                        background = new IplImage(input.Size, IplDepth.F32, input.Channels);
                        background.SetZero();
                    }

                    var output = new IplImage(input.Size, IplDepth.U8, input.Channels);
                    if (averageCount < BackgroundFrames)
                    {
                        averageCount++;
                        output.SetZero();
                        CV.Acc(input, background);
                        if (averageCount == BackgroundFrames)
                        {
                            CV.ConvertScale(background, background, 1.0 / averageCount, 0);
                        }
                    }
                    else
                    {
                        CV.Convert(input, image);
                        switch (SubtractionMethod)
                        {
                        case SubtractionMethod.Bright:
                            CV.Sub(image, background, difference);
                            break;

                        case SubtractionMethod.Dark:
                            CV.Sub(background, image, difference);
                            break;

                        case SubtractionMethod.Absolute:
                        default:
                            CV.AbsDiff(image, background, difference);
                            break;
                        }

                        if (AdaptationRate > 0)
                        {
                            CV.RunningAvg(image, background, AdaptationRate);
                        }

                        CV.Threshold(difference, output, ThresholdValue, 255, ThresholdType);
                    }

                    return output;
                });
            }));
        }
Exemple #8
0
        public override IObservable <Mat> Process(IObservable <Mat> source)
        {
            return(Observable.Create <Mat>(observer =>
            {
                var carry = 0;
                var index = 0;
                var offset = 0;
                var lottery = 0;
                var scaleFactor = 0.0;
                var currentFactor = 0;
                var buffer = default(Mat);
                var carryBuffer = default(Mat);
                var downsampling = Downsampling;
                var random = downsampling == DownsamplingMethod.Dithering ? new Random() : null;
                var reduceOp = (ReduceOperation)(downsampling - DownsamplingMethod.Sum);
                if (reduceOp == ReduceOperation.Avg)
                {
                    reduceOp = ReduceOperation.Sum;
                }
                var downsample = downsampling == DownsamplingMethod.LowPass ? filter.Process(source) : source;
                return downsample.Subscribe(input =>
                {
                    try
                    {
                        var bufferLength = BufferLength;
                        if (bufferLength == 0)
                        {
                            bufferLength = input.Cols;
                        }
                        if (buffer == null || buffer.Rows != input.Rows || currentFactor != factor)
                        {
                            index = 0;
                            currentFactor = factor;
                            if (downsampling >= DownsamplingMethod.Sum)
                            {
                                carry = currentFactor;
                                carryBuffer = new Mat(input.Rows, 1, input.Depth, input.Channels);
                                if (downsampling == DownsamplingMethod.Avg)
                                {
                                    scaleFactor = 1.0 / currentFactor;
                                }
                                else
                                {
                                    scaleFactor = 0;
                                }
                            }
                            else if (random != null)
                            {
                                lottery = random.Next(currentFactor);
                                offset = lottery;
                            }
                            else
                            {
                                offset = 0;
                            }
                            buffer = CreateBuffer(bufferLength, input);
                        }

                        while (offset < input.Cols)
                        {
                            // Process decimation data on this buffer
                            Rect outputRect;
                            if (downsampling > DownsamplingMethod.LowPass)
                            {
                                outputRect = new Rect(index, 0, 1, input.Rows);
                            }
                            else
                            {
                                var samples = input.Cols - offset;
                                var whole = samples / currentFactor;
                                outputRect = new Rect(index, 0, Math.Min(buffer.Cols - index, whole), input.Rows);
                            }

                            if (downsampling >= DownsamplingMethod.Sum)
                            {
                                // Reduce decimate
                                var inputSamples = Math.Min(input.Cols - offset, carry);
                                var inputRect = new Rect(offset, 0, inputSamples, input.Rows);
                                using (var inputBuffer = input.GetSubRect(inputRect))
                                    using (var outputBuffer = buffer.GetCol(index))
                                    {
                                        if (carry < currentFactor)
                                        {
                                            CV.Reduce(inputBuffer, carryBuffer, 1, reduceOp);
                                            switch (reduceOp)
                                            {
                                            case ReduceOperation.Sum:
                                                CV.Add(outputBuffer, carryBuffer, outputBuffer);
                                                break;

                                            case ReduceOperation.Max:
                                                CV.Max(outputBuffer, carryBuffer, outputBuffer);
                                                break;

                                            case ReduceOperation.Min:
                                                CV.Min(outputBuffer, carryBuffer, outputBuffer);
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            CV.Reduce(inputBuffer, outputBuffer, 1, reduceOp);
                                        }

                                        offset += inputRect.Width;
                                        carry -= inputSamples;
                                        if (carry <= 0)
                                        {
                                            index++;
                                            carry = currentFactor;
                                            if (scaleFactor > 0)
                                            {
                                                CV.ConvertScale(outputBuffer, outputBuffer, scaleFactor);
                                            }
                                        }
                                    }
                            }
                            else if (outputRect.Width > 1)
                            {
                                // Block decimate
                                var inputRect = new Rect(offset, 0, outputRect.Width * currentFactor, input.Rows);
                                using (var inputBuffer = input.GetSubRect(inputRect))
                                    using (var outputBuffer = buffer.GetSubRect(outputRect))
                                    {
                                        CV.Resize(inputBuffer, outputBuffer, SubPixelInterpolation.NearestNeighbor);
                                    }

                                index += outputRect.Width;
                                offset += inputRect.Width;
                            }
                            else
                            {
                                // Decimate single time point
                                using (var inputBuffer = input.GetCol(offset))
                                    using (var outputBuffer = buffer.GetCol(index))
                                    {
                                        CV.Copy(inputBuffer, outputBuffer);
                                    }

                                index++;
                                if (random != null)
                                {
                                    offset += currentFactor - lottery;
                                    lottery = random.Next(currentFactor);
                                    offset += lottery;
                                }
                                else
                                {
                                    offset += currentFactor;
                                }
                            }

                            if (index >= buffer.Cols)
                            {
                                index = 0;
                                observer.OnNext(buffer);
                                buffer = CreateBuffer(bufferLength, input);
                            }
                        }

                        offset -= input.Cols;
                    }
                    catch (Exception ex)
                    {
                        observer.OnError(ex);
                    }
                },
                                            observer.OnError,
                                            () =>
                {
                    // Emit pending buffer
                    if (index > 0)
                    {
                        observer.OnNext(buffer.GetCols(0, index));
                    }

                    buffer = null;
                    observer.OnCompleted();
                });
            }));
        }