示例#1
0
        public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
        {
            ((IPointData)this).DrawPointsAsFill(graphics, options);

            //  base drawing (border)
            base.Draw(graphics, options);
        }
        public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
        {
            // TODO: render click event


            // don't call base draw method because don't want the border
        }
        public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
        {
            this.Track.Draw(graphics, options);

            //  base drawing (border)
            base.Draw(graphics, options);
        }
示例#4
0
        public void DrawTest()
        {
            // arrange
            string specification = @"
⬇10
E10R80E10
78×E10RE78RE10
E10R80E10
⬇10
";

            this.ExpectedImage = TestImage.Create(100, 100, Color.Black, specification);

            var @event = new SpectralEvent()
            {
                EventEndSeconds    = 9,
                EventStartSeconds  = 1,
                HighFrequencyHertz = 900,
                LowFrequencyHertz  = 100,
            };
            var options = new EventRenderingOptions(new UnitConverters(0, 10, 1000, 100, 100));

            // act

            this.ActualImage.Mutate(x => @event.Draw(x, options));

            // assert
            this.AssertImagesEqual();
        }
示例#5
0
        public void DrawTest()
        {
            // arrange
            string specification = @"
⬇10
E10R80E10
78×E10RE78RE10
E10R80E10
⬇10
";
            var    p             = PixelOperations <Rgb24> .Instance.GetPixelBlender(new GraphicsOptions());

            var green = Color.FromRgba(0, 255, 0, 128);

            this.ExpectedImage = new TestImage(100, 100, Color.Black)
                                 .FillPattern(specification)

                                 // the point 5.1 seconds and 520 Hz should match 51, 48
                                 .GoTo(51, 48)
                                 .Fill(1, 1, p.Blend(Color.Black, green, 0.5f))
                                 .GoTo(52, 49)
                                 .Fill(2, 1, p.Blend(Color.Black, green, 0.5f))
                                 .GoTo(12, 87)
                                 .Fill(1, 1, p.Blend(Color.Black, green, 0.5f))
                                 .Finish();

            // BUG: with DrawPointsAsFill: overlaps are painted twice
            this.ExpectedImage[52, 49] = new Rgb24(0, 192, 0);

            var @event = new BlobEvent()
            {
                EventEndSeconds    = 9,
                EventStartSeconds  = 1,
                HighFrequencyHertz = 900,
                LowFrequencyHertz  = 100,
            };

            @event.Points.Add(new SpectralPoint((5.1, 5.2), (510, 520), 0.9));

            @event.Points.Add(new SpectralPoint((5.2, 5.3), (500, 510), 0.9));

            // double wide, overlaps with previous
            @event.Points.Add(new SpectralPoint((5.2, 5.4), (500, 510), 0.9));

            @event.Points.Add(new SpectralPoint((1.2, 1.3), (120, 130), 0.9));

            var options = new EventRenderingOptions(new UnitConverters(0, 10, 1000, 100, 100))
            {
                // disable the default blend to make testing easier
                FillOptions = new GraphicsOptions(),
                Fill        = Brushes.Solid(green),
            };

            // act

            this.ActualImage.Mutate(x => @event.Draw(x, options));

            // assert
            this.AssertImagesEqual();
        }
示例#6
0
        public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
        {
            this.Tracks.First().Draw(graphics, options);

            //  base drawing (border)
            // TODO: unless border is disabled
            base.Draw(graphics, options);
        }
示例#7
0
        public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
        {
            foreach (var @event in this.ComponentEvents)
            {
                @event.Draw(graphics, options);
            }

            // draw a border around all of it
            base.Draw(graphics, options);
        }
        //public double Duration => base.Duration;

        public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
        {
            // draw a border around this event
            var border = options.Converters.GetPixelRectangle(this);

            graphics.NoAA().DrawBorderInset(options.Border, border);

            // draw event title
            // TODO
        }
示例#9
0
        public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
        {
            // simply draw a full-height line
            var startPixel = options.Converters.SecondsToPixels(this.EventStartSeconds);

            graphics.NoAA().DrawLines(
                options.Border,
                new PointF(startPixel, 0),
                new PointF(startPixel, graphics.GetCurrentSize().Height));
        }
示例#10
0
        public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
        {
            // foreach (var track in tracks) {
            // track.Draw(...)
            // }

            //this.Track.Draw(graphics, options);

            //  base drawing (border)
            // TODO: unless border is disabled
            base.Draw(graphics, options);
        }
示例#11
0
        public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
        {
            // draw a border around this event
            if (options.DrawBorder)
            {
                var border = options.Converters.GetPixelRectangle(this);
                graphics.NoAA().DrawBorderInset(options.Border, border);
            }

            this.DrawScoreIndicator(graphics, options);

            this.DrawEventLabel(graphics, options);
        }
示例#12
0
        public void TestSonogramWithEventsOverlay()
        {
            // make a substitute sonogram image
            var imageWidth         = 100;
            var imageHeight        = 256;
            var substituteSonogram = Drawing.NewImage(imageWidth, imageHeight, Color.Black);

            // set the time/freq scales
            var segmentDuration = 10.0;  //seconds
            var nyquist         = 11025; //Hertz

            // set a max score to normalize.
            double maxScore = 10.0;

            // make a list of two events
            var events           = new List <SpectralEvent>();
            var segmentStartTime = TimeSpan.FromSeconds(10);
            var event1           = new SpectralEvent(segmentStartOffset: segmentStartTime, eventStartRecordingRelative: 11.0, eventEndRecordingRelative: 16.0, minFreq: 1000, maxFreq: 8000)
            {
                Score      = 10.0,
                ScoreRange = (0, maxScore),
                Name       = "Event1",
            };

            events.Add(event1);
            var event2 = new SpectralEvent(segmentStartOffset: segmentStartTime, eventStartRecordingRelative: 17.0, eventEndRecordingRelative: 19.0, minFreq: 1000, maxFreq: 8000)
            {
                Score      = 1.0,
                ScoreRange = (0, maxScore),
                Name       = "Event2",
            };

            events.Add(event2);

            // now add events into the spectrogram image with score.
            var options = new EventRenderingOptions(new UnitConverters(segmentStartTime.TotalSeconds, segmentDuration, nyquist, imageWidth, imageHeight));

            foreach (var ev in events)
            {
                // because we are testing placement of box not text.
                ev.Name = string.Empty;
                substituteSonogram.Mutate(x => ev.Draw(x, options));
            }

            this.ActualImage = substituteSonogram;
            var path = PathHelper.ResolveAssetPath("EventTests_SuperimposeEventsOnImage.png");

            this.ExpectedImage = Image.Load <Rgb24>(path);
            this.AssertImagesEqual();
        }
示例#13
0
        public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
        {
            foreach (var @event in this.ComponentEvents)
            {
                // disable border
                var newOptions = new EventRenderingOptions(options.Converters)
                {
                    DrawLabel  = false,
                    DrawBorder = false,
                    DrawScore  = false,
                };

                @event.Draw(graphics, newOptions);
            }

            // draw a border around all of it
            base.Draw(graphics, options);
        }
示例#14
0
        /// <summary>
        /// This method draws a spectrogram with other useful information attached.
        /// </summary>
        /// <param name="sonogram">of BaseSonogram class.</param>
        /// <param name="events">a list of acoustic events.</param>
        /// <param name="plots">a list of plots relevant to the spectrogram scores.</param>
        /// <param name="hits">not often used - can be null.</param>
        public static Image <Rgb24> GetSonogramPlusCharts(
            BaseSonogram sonogram,
            List <EventCommon> events,
            List <Plot> plots,
            double[,] hits)
        {
            var spectrogram = sonogram.GetImage(doHighlightSubband: false, add1KHzLines: true, doMelScale: false);

            Contract.RequiresNotNull(spectrogram, nameof(spectrogram));

            var height    = spectrogram.Height;
            var width     = spectrogram.Width;
            var frameSize = sonogram.Configuration.WindowSize;
            //var segmentDuration = sonogram.Duration;
            var spectrogramDuration = width * sonogram.FrameStep;

            // init with linear frequency scale and draw freq grid lines on image
            int hertzInterval = 1000;

            if (height < 200)
            {
                hertzInterval = 2000;
            }

            var nyquist   = sonogram.NyquistFrequency;
            var freqScale = new FrequencyScale(nyquist, frameSize, hertzInterval);

            FrequencyScale.DrawFrequencyLinesOnImage(spectrogram, freqScale.GridLineLocations, includeLabels: true);

            // draw event outlines onto spectrogram.
            if (events != null && events.Count > 0)
            {
                foreach (SpectralEvent ev in events)
                {
                    var options = new EventRenderingOptions(new UnitConverters(ev.SegmentStartSeconds, spectrogramDuration, nyquist, width, height));
                    spectrogram.Mutate(x => ev.Draw(x, options));
                }
            }

            // now add in hits to the spectrogram image.
            if (hits != null)
            {
                spectrogram = Image_MultiTrack.OverlayScoresAsRedTransparency(spectrogram, hits);
            }

            int pixelWidth = spectrogram.Width;
            var titleBar   = LDSpectrogramRGB.DrawTitleBarOfGrayScaleSpectrogram("TITLE", pixelWidth);
            var timeTrack  = ImageTrack.DrawTimeTrack(sonogram.Duration, pixelWidth);

            var imageList = new List <Image <Rgb24> >
            {
                titleBar,
                timeTrack,
                spectrogram,
                timeTrack,
            };

            if (plots != null)
            {
                foreach (var plot in plots)
                {
                    // Next line assumes plot data normalised in 0,1
                    var plotImage = plot.DrawAnnotatedPlot(ImageTrack.DefaultHeight);

                    // the following draws same plot without the title.
                    //var plotImage = ImageTrack.DrawScoreArrayTrack(plot.data, plot.threshold, pixelWidth);
                    imageList.Add(plotImage);
                }
            }

            var compositeImage = ImageTools.CombineImagesVertically(imageList);

            return(compositeImage);
        }
示例#15
0
        /// <summary>
        /// WARNING: graphics.DrawImage() or GDI cannot draw an image that is too big, typically
        /// with an area larger than 10,385,000 pixels (Jiro estimated > 40000 pixels).
        /// This means it cannot handle recording sonograms longer than 2 minutes.
        /// Therefore call a recursive method to draw the image.
        /// </summary>
        public Image <Rgb24> GetImage()
        {
            // Calculate total height of the bmp
            var height = this.CalculateImageHeight();

            // set up a new image having the correct dimensions
            var imageToReturn = new Image <Rgb24>(this.SonogramImage.Width, height);

            // need to do this before get Graphics because cannot PutPixels into Graphics object.
            if (this.SuperimposedRedTransparency != null)
            {
                this.SonogramImage = this.OverlayRedTransparency((Image <Rgb24>) this.SonogramImage);
            }

            if (this.SuperimposedMatrix != null)
            {
                this.SonogramImage = this.OverlayMatrix((Image <Rgb24>) this.SonogramImage);
            }

            // create new graphics canvas and add in the sonogram image
            imageToReturn.Mutate(g =>
            {
                g.DrawImage(this.SonogramImage, 1f);

                // draw events first because their rectangles can cover other features
                if (this.EventList != null)
                {
                    var hitImage = new Image <Rgb24>(imageToReturn.Width, height);

                    //hitImage.MakeTransparent();
                    foreach (AcousticEvent e in this.EventList)
                    {
                        // TODO TODO Fix this call. I am having problem with managing SixLabors.ImageSharp
                        e.DrawEvent(hitImage, this.framesPerSecond, this.freqBinWidth, this.SonogramImage.Height);
                    }

                    g.DrawImage(hitImage, 0, 0);
                }

                // draw events first because their rectangles can cover other features
                if (this.Points != null)
                {
                    // var stats = new StatDescriptive(this.points.Select(p => p.Item2).ToArray());
                    // stats.Analyze();
                    foreach (PointOfInterest poi in this.Points)
                    {
                        //poi.DrawPoint(g, this.Points, this.sonogramImage.Height);
                        const int radius = 12;
                        poi.DrawBox(g, this.Points, radius);
                    }
                }

                if (this.SpectralTracks != null)
                {
                    var converter = new UnitConverters(
                        segmentStartOffset: 0.0,
                        segmentDuration: this.framesPerSecond * this.SonogramImage.Width,
                        nyquistFrequency: this.freqBinWidth * this.SonogramImage.Height,
                        imageWidth: this.SonogramImage.Width,
                        imageHeight: this.SonogramImage.Height);

                    var renderingOptions = new EventRenderingOptions(converter);

                    foreach (var t in this.SpectralTracks)
                    {
                        t.Draw(g, renderingOptions);
                    }
                }

                if (this.freqHits != null)
                {
                    this.DrawFreqHits(g);
                }

                if (this.SuperimposedRainbowTransparency != null)
                {
                    this.OverlayRainbowTransparency(g, (Image <Rgb24>) this.SonogramImage);
                }

                if (this.SuperimposedDiscreteColorMatrix != null)
                {
                    this.OverlayDiscreteColorMatrix(g);
                }
            });

            // now add tracks to the image
            int offset = this.SonogramImage.Height;

            foreach (ImageTrack track in this.tracks)
            {
                track.topOffset    = offset;
                track.bottomOffset = offset + track.Height - 1;
                track.DrawTrack(imageToReturn.CloneAs <Rgb24>());
                offset += track.Height;
            }

            return(imageToReturn);
        }
示例#16
0
 public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
 {
     this.Tracks.First().Draw(graphics, options);
     base.Draw(graphics, options);
 }
示例#17
0
 /// <summary>
 /// Draw this event on an image.
 /// </summary>
 /// <param name="graphics">The image prcessing context to draw an event on.</param>
 /// <param name="options">The options associated with this render request.</param>
 public abstract void Draw(IImageProcessingContext graphics, EventRenderingOptions options);