public override IObservable <Mat> Process(IObservable <Mat> source) { return(Observable.Create <Mat>(observer => { var skipCount = 0; var count = Count; var skip = Skip.GetValueOrDefault(count); var activeBuffers = new List <SampleBuffer>(); return source.Subscribe(input => { try { // Update pending windows activeBuffers.RemoveAll(buffer => { buffer.Update(input, 0); if (buffer.Completed) { // Window is ready, emit observer.OnNext(buffer.Samples); return true; } return false; }); var index = 0; while ((index + skipCount) < input.Cols) { // Create new window and reset skip counter index += skipCount; skipCount = skip; var buffer = new SampleBuffer(input, count, index); buffer.Update(input, index); if (buffer.Completed) { // Window is ready, emit observer.OnNext(buffer.Samples); } // Window is missing data, add to list else { activeBuffers.Add(buffer); } } // Remove remainder of input samples from skip counter skipCount -= input.Cols - index; } catch (Exception ex) { observer.OnError(ex); } }, error => observer.OnError(error), () => observer.OnCompleted()); })); }
static SampleBuffer UpdateBuffer(SampleBuffer buffer, Mat source, int index, int delay, double threshold) { var samplesTaken = buffer.Update(source, index); if (buffer.Completed && !buffer.Refined) { double min, max; Point minLoc, maxLoc; var waveform = buffer.Samples; CV.MinMaxLoc(waveform, out min, out max, out minLoc, out maxLoc); var offset = threshold > 0 ? maxLoc.X - delay : minLoc.X - delay; if (offset > 0) { var offsetBuffer = new SampleBuffer(waveform, waveform.Cols, buffer.SampleIndex + offset); offsetBuffer.Refined = true; offsetBuffer.Update(waveform, offset); offsetBuffer.Update(source, index + samplesTaken + offset); return(offsetBuffer); } } return(buffer); }
public override IObservable <Mat> Process(IObservable <Tuple <Mat, Mat> > source) { return(Observable.Create <Mat>(observer => { bool active = false; var activeBuffers = new List <SampleBuffer>(); return source.Subscribe(input => { try { var data = input.Item1; var trigger = input.Item2; // Update pending windows activeBuffers.RemoveAll(buffer => { buffer.Update(data, 0); if (buffer.Completed) { // Window is ready, emit observer.OnNext(buffer.Samples); return true; } return false; }); // Check if new triggers have arrived var nonZero = CV.CountNonZero(trigger); if (nonZero <= 0) { active = false; } else { var triggerBuffer = new byte[trigger.Cols]; var triggerHandle = GCHandle.Alloc(triggerBuffer, GCHandleType.Pinned); using (var triggerHeader = new Mat(1, triggerBuffer.Length, Depth.U8, 1, triggerHandle.AddrOfPinnedObject())) { CV.Convert(trigger, triggerHeader); triggerHandle.Free(); } for (int i = 0; i < triggerBuffer.Length; i++) { var triggerHigh = triggerBuffer[i] > 0; if (triggerHigh && !active) { var buffer = new SampleBuffer(data, Count, i); buffer.Update(data, i); if (buffer.Completed) { // Window is ready, emit observer.OnNext(buffer.Samples); } // Window is missing data, add to list else { activeBuffers.Add(buffer); } } active = triggerHigh; } } } catch (Exception ex) { observer.OnError(ex); } }, error => observer.OnError(error), () => observer.OnCompleted()); })); }