wsPlot

本文详细介绍了如何使用特定的编程技术与库,实现高效且专业的图表绘制与数据可视化功能,包括绘制曲线、标记关键点、添加网格、设置坐标轴标签等。通过实例演示,帮助开发者快速掌握图表绘制的核心技巧。
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace wsControls
{
    #region [ Classs ] wsPlot
    public class wsPlot
    {

        //public static void DrawArc(Graphics g, Pen pen, PointF center, decimal radius, decimal startangle, decimal sweepangle)
        //{
        //    decimal x = center.X - radius;
        //    decimal y = center.Y - radius;
        //    decimal w = radius + radius;
        //    decimal h = w;
        //    decimal start = (decimal)(startangle * Math.PI / 180);
        //    decimal sweep = (decimal)(sweepangle * Math.PI / 180);
        //    g.DrawArc(pen, x, y, w, h, start, sweep);
        //}


        public static void DrawConnection(Graphics g, Pen pen, float x1, float y1, float x2, float y2, float radius)
        {
            int offset = (int)pen.Width % 2 > 0 ? 0 : 1;
            float xn, yn; 
            if (y2 > y1&&x2>x1)
            {
                yn = y2 - radius;
                g.DrawLine(pen, x1, y1, x1, yn+offset);//|
                g.DrawArc(pen, x1 - offset, yn - radius, radius + radius, radius + radius, 90, 90);//|_
                xn = x1 + radius;
                g.DrawLine(pen, x2, y2,xn - offset, y2);//   _
            }
            else if (y2 < y1 && x2 > x1)
            {
                xn = x2 - radius;
                yn = y1 - radius;
                g.DrawLine(pen, x1, y1, xn, y1 + offset);//|
                g.DrawArc(pen, xn-radius, y1-radius-radius, radius + radius, radius + radius, 90, -90);//|_|               
                g.DrawLine(pen, x2, y2, x2, yn+offset);//   _
            }
            else if (y2 < y1 && x2 < x1)
            {
                xn = x1 - radius;
                yn = y2 + radius;
                g.DrawLine(pen,  x1, yn - offset,x1, y1);//|
                g.DrawArc(pen, xn - radius, y2, radius + radius, radius + radius, -90, 90);//|_|               
                g.DrawLine(pen, x2, y2, xn + offset, y2);//   _
            }
            else if (y2 > y1 && x2 < x1)
            {
                xn = x2 + radius;
                yn = y1 + radius;
                g.DrawLine(pen,  xn-offset, y1,x1, y1);//|
                g.DrawArc(pen, x2, y1, radius + radius, radius + radius, 180, 90);//|_|               
                g.DrawLine(pen,  x2, y2,x2, yn-offset);//   _
            }
        }

        float dx, dy;
        float Pxmin, Pxmax;
        float Pymin, Pymax;

        public double[] Fi;
        public float[] posx;

        #region [ Property ] Width. Height
        public int Width { get; set; }
        public int Height { get; set; }
        #endregion

        public wsPlot(int width, int height, wsPlotProperty property)
        {
            ReSize(width, height, property);
        }

        #region [ Function ] Resize
        public void ReSize(int width, int height, wsPlotProperty property)
        {
            Width = width;
            Height = height;

            Pxmin = property.LeftSpace;
            Pxmax = width - property.RightSpace;
            dx = (Pxmax - Pxmin) / 10f;

            Pymin = property.TopSpace;
            Pymax = height - property.BottomSpace;
            dy = (Pymax - Pymin) / property.Ydiv;
        }
        #endregion

        #region [ Function ] DrawBackground -- Grid & Text
        public void DrawBackground(Graphics g, wsPlotProperty property)
        {
            DrawGrid(g, property);
            UpdateText(g, property);
        }

        private void DrawGrid(Graphics g, wsPlotProperty property)
        {
            g.Clear(property.BackColor);
            Pen gridpen = new Pen(property.GridColor);
            float Px, Py;
            for (int i = 0; i < 11; i++)
            {
                Px = (float)(Pxmin + i * dx);
                g.DrawLine(gridpen, new PointF(Px, Pymin), new PointF(Px, Pymax));
            }
            for (int i = 0; i <= property.Ydiv; i++)
            {
                Py = Pymin + i * dy;
                g.DrawLine(gridpen, new PointF(Pxmin, Py), new PointF(Pxmax, Py));
            }

        }

        public string Format = "N2";

        private void UpdateText(Graphics g, wsPlotProperty property)
        {
            Brush brush = new SolidBrush(property.ForeColor);
            Font font = property.TitleFont;

            //Title...
            SizeF sf = g.MeasureString(property.Title, font);
            g.DrawString(property.Title, font, brush,
                new PointF((this.Width - sf.Width) / 2f, (Pymin - sf.Height) / 2F));

            //Label Y...
            font = property.Font;
            sf = g.MeasureString(property.yLabel, font);
            g.DrawString(property.yLabel, font, brush,
                new PointF(Pxmin, (Pymin - 1 - sf.Height)));

            //Label X...
            sf = g.MeasureString(property.xLabel, font);
            g.DrawString(property.xLabel, font, brush,
                new PointF(Pxmin + 5*dx - sf.Width / 2f, Pymax + 1));



            //X Scale...
            string V = property.xMin.ToString(Format);
            g.DrawString(V, font, brush, new PointF(Pxmin, Pymax + 1));

            V = property.xMax.ToString(Format);
            sf = g.MeasureString(V, font);
            g.DrawString(V, font, brush, new PointF(Pxmax - sf.Width, Pymax + 1));

            //Y Scale...
            for (int i = 0; i <= property.Ydiv; i++)
            {
                V = (property.Refer - i * property.Scale).ToString(Format);
                sf = g.MeasureString(V, font);
                g.DrawString(V, font, brush,
                    new PointF(Pxmin - 1 - sf.Width, Pymin - sf.Height / 2 + i * dy));
            }
            brush.Dispose();
        }
        #endregion

        #region [ Function ] Update Frequency & Position
        public float[] GetPositionX(decimal[] f, wsPlotProperty property)
        {
            int ilength = f.Length;
            float[] pos = new float[ilength];

            decimal k =(decimal) dx * 10 / (property.xMax - property.xMin);
            for (int i = 0; i < ilength; i++)
                pos[i] = Pxmin + (float)((f[i] - property.xMin) * k);

            return pos;
        }

        public float[] GetPositionX(int N, wsPlotProperty property)
        {
            int ilength = N;
            float[] pos = new float[ilength];

            decimal k = (decimal)dx * 10 / (ilength - 1);
            for (int i = 0; i < ilength; i++)
                pos[i] = Pxmin + (float)(i * k);

            return pos;
        }
        #endregion

        #region [ Function ] Add Trace
        public PointF[] AddTrace(Graphics g, decimal[] data, Color color, string name, wsPlotProperty property)
        {
            PointF[] path = AddTrace(g, data, color, property);
            //Trace name
            SizeF sf = g.MeasureString(name, property.Font);
            g.DrawString(name, property.Font, new SolidBrush(color), new PointF(Pxmax + 1, path[path.Length - 1].Y - sf.Height / 2));
            return path;
        }

        public PointF[] AddTrace(Graphics g, decimal[] data, Color color, wsPlotProperty property)
        {
            decimal ymin = property.Refer - property.Ydiv * property.Scale;
            int length = data.Length;

            PointF[] path = new PointF[length];

            for (int i = 0; i < length; i++)
            {
                path[i].X =(float) posx[i];
                path[i].Y = Pymax - (float)((data[i] - ymin) *(decimal) dy / property.Scale);

                if (path[i].Y < Pymin)
                    path[i].Y = Pymin;
                else if (path[i].Y > Pymax)
                    path[i].Y = Pymax;
            }
            g.DrawLines(new Pen(color, 1F), path);

            return path;
        }

        public PointF[] AddTrace(Graphics g, decimal[] data, Color color, wsPlotProperty property, int istart, int istop)
        {
            decimal ymin = property.Refer - property.Ydiv * property.Scale;
            int length = istop - istart + 1;

            PointF[] path = new PointF[length];

            for (int i = 0; i < length; i++)
            {
                path[i].X = (float)posx[i];
                path[i].Y = Pymax - (float)((data[i+istart] - ymin) * (decimal)dy / property.Scale);

                if (path[i].Y < Pymin)
                    path[i].Y = Pymin;
                else if (path[i].Y > Pymax)
                    path[i].Y = Pymax;
            }
            g.DrawLines(new Pen(color, 1F), path);

            return path;
        }

        public PointF[] AddTrace(Graphics g, Collection<decimal>data, Color color, wsPlotProperty property)
        {
            decimal ymin = property.Refer - property.Ydiv * property.Scale;
            int length = data.Count;

            PointF[] path = new PointF[length];

            for (int i = 0; i < length; i++)
            {
                path[i].X = (float)posx[i];
                path[i].Y = Pymax - (float)((data[i] - ymin) * (decimal)dy / property.Scale);

                if (path[i].Y < Pymin)
                    path[i].Y = Pymin;
                else if (path[i].Y > Pymax)
                    path[i].Y = Pymax;
            }
            g.DrawLines(new Pen(color, 1F), path);

            return path;
        }

        public PointF[] AddTrace(Graphics g, Collection<decimal> data, Color color, wsPlotProperty property, int istart, int istop)
        {
            decimal ymin = property.Refer - property.Ydiv * property.Scale;
            int length = istop - istart + 1;

            PointF[] path = new PointF[length];

            for (int i = 0; i <length; i++)
            {
                path[i].X = (float)posx[i];
                path[i].Y = Pymax - (float)((data[i+istart] - ymin) * (decimal)dy / property.Scale);

                if (path[i].Y < Pymin)
                    path[i].Y = Pymin;
                else if (path[i].Y > Pymax)
                    path[i].Y = Pymax;
            }
            g.DrawLines(new Pen(color, 1F), path);

            return path;
        }

        public PointF[] AddTrace(Graphics g, decimal[] Fi, decimal[] data, Color color, wsPlotProperty property)
        {
            posx = GetPositionX(Fi, property);
            int length = data.Length;

            decimal ymin = property.Refer - property.Ydiv * property.Scale;
            PointF[] path = new PointF[length];

            for (int i = 0; i < length; i++)
            {
                path[i].X = posx[i];
                path[i].Y = Pymax - (float)((data[i] - ymin) *(decimal) dy / property.Scale);

                if (path[i].Y < Pymin)
                    path[i].Y = Pymin;
                else if (path[i].Y > Pymax)
                    path[i].Y = Pymax;
            }
            g.DrawLines(new Pen(color, 1F), path);

            return path;
        }
        #endregion

        #region [ Function ] Add Marker
        public void AddMarker(Graphics g, wsMarker marker, wsPlotProperty property)
        {
            SizeF sf = g.MeasureString(marker.Value, property.Font);
            g.DrawString(marker.Value, property.Font, new SolidBrush(marker.Color),
                new PointF(marker.PointF.X - sf.Width / 2F, marker.PointF.Y - dy / 3 - sf.Height));

        }

        public void AddMarker(Graphics g, PointF[] path, decimal[] trace, int[] indexes, wsPlotProperty property)
        {
            int markerysize = property.MarkerSize + property.MarkerSize;
            Point[] markerpath;
            GraphicsPath gpath;
            Font font = new Font(property.MarkerFont.FontFamily, markerysize, FontStyle.Bold);
            SizeF sf = g.MeasureString("1MHz dBm", font);
            string mkrtext; string mkrtextfmt = "F" + property.MarkerDecimals.ToString();
            float mpx;
            float dpy = 4;
            float mpy = Pymin - sf.Height - dpy / 2;
            for (int i = 0; i < indexes.Length; i++)
            {
                if (indexes[i] >= trace.Length) continue;
                markerpath = new Point[] 
                {
                    new Point((int)path[indexes[i]].X-property.MarkerSize,(int)path[indexes[i]].Y),
                    new Point((int)path[indexes[i]].X,(int)path[indexes[i]].Y-markerysize),
                    new Point((int)path[indexes[i]].X+property.MarkerSize,(int)path[indexes[i]].Y),
                    new Point((int)path[indexes[i]].X,(int)path[indexes[i]].Y+markerysize),
                };
                gpath = new GraphicsPath();
                gpath.AddLines(markerpath);
                gpath.CloseFigure();

                if (property.MarkerFill)
                    g.FillPath(new SolidBrush(property.MarkerColor), gpath);
                else
                    g.DrawPath(new Pen(property.MarkerColor, property.MarkerLineWidth), gpath);

                //Marker Index
                mkrtext = (i + 1).ToString();
                sf = g.MeasureString(mkrtext, font);
                g.DrawString(mkrtext, font, new SolidBrush(property.MarkerColor), new PointF(posx[indexes[i]] + property.MarkerSize, path[indexes[i]].Y - sf.Height));

                //Marker X Text
                mkrtext = "[Mkr" + mkrtext + "]  " + wsArray.GetValue(property.xMin, property.xMax, posx.Length, indexes[i]).ToString() + " " + property.MarkerUnitX + ":  "
                    + trace[indexes[i]].ToString(mkrtextfmt) + " " + property.MarkerUnitY;
                sf = g.MeasureString(mkrtext, font);
                g.DrawString(mkrtext, font, new SolidBrush(property.MarkerColor), Pxmax - sf.Width, mpy); mpy += sf.Height + dpy;

            }
        }

        public void AddMarker(Graphics g, PointF[] path, Collection<decimal> trace, int[] indexes, wsPlotProperty property)
        {
            int markerysize = property.MarkerSize + property.MarkerSize;
            Point[] markerpath;
            GraphicsPath gpath;
            Font font = new Font(property.MarkerFont.FontFamily, markerysize, FontStyle.Bold);
            SizeF sf = g.MeasureString("1MHz dBm", font);
            string mkrtext; string mkrtextfmt = "F" + property.MarkerDecimals.ToString();
            float mpx;
            float dpy = 4;
            float mpy = Pymin - sf.Height - dpy / 2;
            for (int i = 0; i < indexes.Length; i++)
            {
                if (indexes[i] >= trace.Count) continue;

                markerpath = new Point[] 
                {
                    new Point((int)path[indexes[i]].X-property.MarkerSize,(int)path[indexes[i]].Y),
                    new Point((int)path[indexes[i]].X,(int)path[indexes[i]].Y-markerysize),
                    new Point((int)path[indexes[i]].X+property.MarkerSize,(int)path[indexes[i]].Y),
                    new Point((int)path[indexes[i]].X,(int)path[indexes[i]].Y+markerysize),
                };
                gpath = new GraphicsPath();
                gpath.AddLines(markerpath);
                gpath.CloseFigure();

                if (property.MarkerFill)
                    g.FillPath(new SolidBrush(property.MarkerColor), gpath);
                else
                    g.DrawPath(new Pen(property.MarkerColor, property.MarkerLineWidth), gpath);

                //Marker Index
                mkrtext = (i + 1).ToString();
                sf = g.MeasureString(mkrtext, font);
                g.DrawString(mkrtext, font, new SolidBrush(property.MarkerColor), new PointF(posx[indexes[i]] + property.MarkerSize, path[indexes[i]].Y - sf.Height));

                //Marker X Text
                mkrtext = "[Mkr" + mkrtext + "]  " + wsArray.GetValue(property.xMin, property.xMax, posx.Length, indexes[i]).ToString() + " " + property.MarkerUnitX + ":  "
                    + trace[indexes[i]].ToString(mkrtextfmt) + " " + property.MarkerUnitY;
                sf = g.MeasureString(mkrtext, font);
                g.DrawString(mkrtext, font, new SolidBrush(property.MarkerColor), Pxmax - sf.Width, mpy); mpy += sf.Height + dpy;

            }
        }

        public void AddMarker(Graphics g, PointF[] path, int index, string mkrtext, wsPlotProperty property)
        {
            if (index >= path.Length) return;

            int markerysize = property.MarkerSize + property.MarkerSize;
            Point[] markerpath = new Point[] 
            {
                new Point((int)path[index].X-property.MarkerSize,(int)path[index].Y),
                new Point((int)path[index].X,(int)path[index].Y-markerysize),
                new Point((int)path[index].X+property.MarkerSize,(int)path[index].Y),
                new Point((int)path[index].X,(int)path[index].Y+markerysize),
            };

            GraphicsPath gpath = new GraphicsPath();
            gpath.AddLines(markerpath);
            gpath.CloseFigure();

            if (property.MarkerFill)
                g.FillPath(new SolidBrush(property.MarkerColor), gpath);
            else
                g.DrawPath(new Pen(property.MarkerColor), gpath);

            Font font = new Font(property.MarkerFont.FontFamily, markerysize);
            SizeF sf = g.MeasureString(index.ToString(), font);

            g.DrawString(mkrtext, font, new SolidBrush(property.MarkerColor), new PointF(posx[index] + property.MarkerSize, path[index].Y - sf.Height));
        }

        public void AddMarker(Graphics g, PointF pos, string text, wsPlotProperty property)
        {
            int markerysize = property.MarkerSize + property.MarkerSize;
            Point[] markerpath = new Point[] 
            {
                new Point((int)pos.X-property.MarkerSize,(int)pos.Y),
                new Point((int)pos.X,(int)pos.Y-markerysize),
                new Point((int)pos.X+property.MarkerSize,(int)pos.Y),
                new Point((int)pos.X,(int)pos.Y+markerysize),
            };

            GraphicsPath gpath = new GraphicsPath();
            gpath.AddLines(markerpath);
            gpath.CloseFigure();

            if (property.MarkerFill)
                g.FillPath(new SolidBrush(property.MarkerColor), gpath);
            else
                g.DrawPath(new Pen(property.MarkerColor), gpath);

            Font font = new Font(property.MarkerFont.FontFamily, markerysize);
            SizeF sf = g.MeasureString(text, font);

            g.DrawString(text, font, new SolidBrush(property.MarkerColor), new PointF(pos.X + property.MarkerSize, pos.Y - sf.Height));
        }

        public void AddMarker(Graphics g, PointF pos, string text, Font font)
        {
            int markersize = 6;
            int markerysize = markersize * 2;
            Color markercolor = Color.Green;
            bool markerfill = false;

            Point[] markerpath = new Point[] 
            {
                new Point((int)pos.X-markersize,(int)pos.Y),
                new Point((int)pos.X,(int)pos.Y-markerysize),
                new Point((int)pos.X+markersize,(int)pos.Y),
                new Point((int)pos.X,(int)pos.Y+markerysize),
            };

            GraphicsPath gpath = new GraphicsPath();
            gpath.AddLines(markerpath);
            gpath.CloseFigure();

            if (markerfill)
                g.FillPath(new SolidBrush(markercolor), gpath);
            else
                g.DrawPath(new Pen(markercolor), gpath);

            SizeF sf = g.MeasureString(text, font);

            g.DrawString(text, font, new SolidBrush(markercolor), new PointF(pos.X + markersize, pos.Y - sf.Height));
        }

        #endregion
		
    }
    #endregion

    #region [ Class ] wsPlotProperty with Type Converter
    [TypeConverter(typeof(wsPlotPropertyTypeConverter)), Description("PlotProperty"), DisplayName("PlotProperty")]
    public class wsPlotProperty
    {
        #region [ Constructor ]
        public wsPlotProperty()
        {
            Title = "Spectrum Analyze";
            TitleFont = new System.Drawing.Font("Arial", 12F, FontStyle.Bold);
            Font = new System.Drawing.Font("Arial", 8F, FontStyle.Regular);
            xLabel = "Frequency [ MHz ]";
            yLabel = "dBm";
            BackColor = Color.Black;
            ForeColor = Color.Gold;
            GridColor = Color.LightGray;

            xMin = 0;
            xMax = 100;
            Refer = 0;
            Ydiv = 10;
            Scale = 10;

            LeftSpace = 50;
            RightSpace = 10;
            TopSpace = 50;
            BottomSpace = 30;

            TraceColor = Color.Yellow;
            Alpha = 192;

            MarkerSize = 6;
            MarkerColor = Color.Lime;
            MarkerFill = false;
            MarkerFont = new Font("Tahoma", 10f);
            MarkerUnitX = "MHz";
            MarkerUnitY = "dBm";
            MarkerLineWidth = 2;
            MarkerDecimals = 2;
        }
        #endregion

        public event EventHandler BackgroundChanged;
        #region [ Property ] Display: Tittle, TittleFont, Font, xLabel, yLabey, BackColor, ForeColor, GridColor
        string title;
        [Category("Diaplay"), DisplayName("标题")]
        public string Title
        {
            get { return title; }
            set
            {
                title = value;
                if (BackgroundChanged != null) BackgroundChanged(this, new EventArgs());
            }
        }

        [Category("Diaplay"), DisplayName("标题字体")]
        public Font TitleFont { get; set; }

        [Category("Diaplay"), DisplayName("字体")]
        public Font Font { get; set; }

        string xlabel;
        [Category("Diaplay"), DisplayName("X坐标标示"), Description("X Axis Label Text"), Browsable(true)]
        public string xLabel
        {
            get
            { return xlabel; }
            set
            {
                xlabel = value;
                if (BackgroundChanged != null) BackgroundChanged(this, new EventArgs());
            }
        }

        string ylabel;
        [Category("Diaplay"), DisplayName("Y坐标标示"), Description("Y Axis Label Text"), Browsable(true)]
        public string yLabel
        {
            get
            { return ylabel; }
            set
            {
                ylabel = value;
                if (BackgroundChanged != null) BackgroundChanged(this, new EventArgs());
            }
        }


        Color backcolor;
        [Category("Diaplay"), DisplayName("背景色"), Description("Background Color")]
        public Color BackColor
        {
            get
            {
                return backcolor;
            }
            set
            {
                backcolor = value;
                if (BackgroundChanged != null) BackgroundChanged(this, new EventArgs());
            }
        }


        Color forecolor;
        [Category("Diaplay"), DisplayName("前景色"), Description("Foreground Color")]
        public Color ForeColor
        {
            get
            {
                return forecolor;
            }
            set
            {
                forecolor = value;
                if (BackgroundChanged != null) BackgroundChanged(this, new EventArgs());
            }
        }

        Color gridcolor;
        [Category("Diaplay"), DisplayName("分割线色"), Description("Grid Line Color")]
        public Color GridColor
        {
            get
            { return gridcolor; }
            set
            {
                gridcolor = value;
                if (BackgroundChanged != null) BackgroundChanged(this, new EventArgs());
            }
        }
        #endregion

        public event EventHandler ScaleChanged;

        decimal xmin;
        #region [ Property ] Scale: xMin, xMax, Refer, Scale
        [Category("Scale / Div"), DisplayName("X最小坐标值"), Description("Min Frequency"), Browsable(true)]
        public decimal xMin
        {
            get
            {
                return xmin;
            }
            set
            {
                xmin = value;
                if (ScaleChanged != null) ScaleChanged(this, new EventArgs());
            }
        }

        decimal xmax;
        [Category("Scale / Div"), DisplayName("X最大坐标值"), Description("Max Frequency"), Browsable(true)]
        public decimal xMax
        {
            get
            {
                return xmax;
            }

            set
            {
                xmax = value;
                if (ScaleChanged != null) ScaleChanged(this, new EventArgs());
            }
        }

        decimal refer;
        [Category("Scale / Div"), DisplayName("Y Reference")]
        public decimal Refer
        {
            get
            {
                return refer;
            }
            set
            {
                refer = value;
                if (ScaleChanged != null) ScaleChanged(this, new EventArgs());
            }
        }

        int ydiv;
        [Category("Scale / Div"),DisplayName("Y Div")]
        public int Ydiv
        {
            get
            {
                return ydiv;
            }
            set
            {
                ydiv = value;
                ydiv = ydiv < 1 ? 2 : ydiv;
                if (ScaleChanged != null) ScaleChanged(this, new EventArgs());
            }
        }

        decimal scale;
        [Category("Scale / Div"), DisplayName("Y Scale/Div")]
        public decimal Scale
        {
            get
            {
                return scale;
            }
            set
            {
                scale = value;
                if (ScaleChanged != null) ScaleChanged(this, new EventArgs());
            }
        }
        #endregion

        #region [ Location ] 
        [Category("Location"), DefaultValue(75), Browsable(true),DisplayName("左侧间隙")]
        public int LeftSpace { get; set; }
        [Category("Location"), DefaultValue(75), Browsable(true), DisplayName("右侧间隙")]
        public int RightSpace { get; set; }
        [Category("Location"), DefaultValue(50), Browsable(true),DisplayName("顶部间隙")]
        public int TopSpace { get; set; }
        [Category("Location"), DefaultValue(50), Browsable(true), DisplayName("底部间隙")]
        public int BottomSpace { get; set; }
        #endregion

        #region [Trace ]
        [Category("Trace"),  Browsable(true), DisplayName("Trace Color")]
        public Color TraceColor { get; set; }

        [Category("Trace"), Browsable(true), DisplayName("Alpha")]
        public int Alpha { get; set; }
        #endregion

        #region [ Marker ]
        [Category("Marker"), DefaultValue(6), Browsable(true), DisplayName("Marker Size")]
        public int MarkerSize { get; set; }

        [Category("Marker"), Browsable(true), DisplayName("Marker Color")]
        public Color MarkerColor { get; set; }

        [Category("Marker"), DefaultValue(1), Browsable(true), DisplayName("Marker Line Width")]
        public float MarkerLineWidth { get; set; }

        [Category("Marker"), DefaultValue(false), Browsable(true), DisplayName("Marker Fill")]
        public bool MarkerFill { get; set; }

        [Category("Marker"), Browsable(false)]
        public Font MarkerFont { get; set; }

        [Category("Marker"), DefaultValue(2), Browsable(true), DisplayName("Marker Decimal Places")]
        public int MarkerDecimals { get; set; }

        [Category("Marker"), DefaultValue("MHz"), Browsable(true), DisplayName("Marker Unit X ")]
        public string MarkerUnitX { get; set; }

        [Category("Marker"), DefaultValue("dBm"), Browsable(true), DisplayName("Marker Unit Y")]
        public string MarkerUnitY { get; set; }
        #endregion

        public override string ToString()
        {
            return string.Empty;
        }

        #region [ Function ] From / To StringX
        public StringX ToStringX()
        {
            string str = string.Empty;
            char t = (char)220;

            str += this.BackColor.ToArgb().ToString() + t;
            str += this.ForeColor.ToArgb().ToString() + t;
            str += this.GridColor.ToArgb().ToString() + t;
            str += this.LeftSpace.ToString() + t;
            str += this.RightSpace.ToString() + t;
            str += this.Refer.ToString() + t;
            str += this.Scale.ToString() + t;
            str += this.Title + t;
            str += this.TopSpace.ToString() + t;
            str += this.BottomSpace.ToString() + t;
            str += this.xLabel + t;
            str += this.xMax.ToString() + t;
            str += this.xMin.ToString() + t;
            str += this.yLabel + t;
            str += this.ydiv.ToString() + t;
            str += this.TraceColor.ToArgb().ToString() + t;
            str += this.Alpha.ToString() + t;

            str += this.MarkerSize.ToString() + t;
            str += this.MarkerColor.ToArgb().ToString() + t;
            str += this.MarkerLineWidth.ToString() + t;
            str += this.MarkerFill.ToString() + t;
            str += this.MarkerDecimals.ToString() + t;
            str += this.MarkerUnitX + t;
            str += this.MarkerUnitY + t;

            StringX sx = new StringX("Plot");
            sx.String = str;
            return sx;
        }

        public void FromStringX(StringX str)
        {
            string[] s = str.String.Split((char)220);
            if(s.Length<17)
                s = str.String.Split((char)252);
            int i = 0;
            this.BackColor = Color.FromArgb(Convert.ToInt32(s[i])); i++;
            this.ForeColor = Color.FromArgb(Convert.ToInt32(s[i])); i++;
            ///////////////////

            this.GridColor = Color.FromArgb(Convert.ToInt32(s[i])); i++;
            this.LeftSpace = Convert.ToInt32(s[i]); i++;
            this.RightSpace = Convert.ToInt32(s[i]); i++;
            this.Refer = Convert.ToDecimal(s[i]); i++;
            this.Scale = Convert.ToDecimal(s[i]); i++;
            this.Title = s[i]; i++;
            this.TopSpace = Convert.ToInt32(s[i]); i++;
            this.BottomSpace = Convert.ToInt32(s[i]); i++;
            this.xLabel = s[i]; i++;
            this.xMax = Convert.ToDecimal(s[i]); i++;
            this.xMin = Convert.ToDecimal(s[i]); i++;
            this.yLabel = s[i]; i++;
            this.Ydiv = Convert.ToInt32(s[i]); i++;
            this.TraceColor = Color.FromArgb(Convert.ToInt32(s[i])); i++;
            this.Alpha = Convert.ToInt32(s[i]); i++;

            this.MarkerSize = Convert.ToInt32(s[i]); i++;
            this.MarkerColor = Color.FromArgb(Convert.ToInt32(s[i])); i++;
            this.MarkerLineWidth = Convert.ToSingle(s[i]); i++;
            this.MarkerFill = Convert.ToBoolean(s[i]); i++;
            this.MarkerDecimals = Convert.ToInt32(s[i]); i++;
            this.MarkerUnitX = s[i]; i++;
            this.MarkerUnitY = s[i]; i++;
        }
        #endregion
    }

    public class wsPlotPropertyTypeConverter : ExpandableObjectConverter
    {
        #region Can Convert
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(wsPlotProperty))
                return true;
            return base.CanConvertTo(context, destinationType);
        }

        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(StringX))
                return true;
            return base.CanConvertFrom(context, sourceType);
        }
        #endregion

        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(StringX) && value is wsPlotProperty)
                return ((wsPlotProperty)value).ToStringX();
            return base.ConvertTo(context, culture, value, destinationType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is StringX)
            {
                try
                {
                    wsPlotProperty p = new wsPlotProperty();
                    p.FromStringX((StringX)value);
                    return p;
                }
                catch (Exception ex)
                {
                    throw new ArgumentException(ex.ToString());
                }
            }
            return base.ConvertFrom(context, culture, value);
        }
    }
    #endregion

    #region [ Class ] wsMarker
    public class wsMarker
    {
        public PointF PointF { get; set; }
        public Color Color { get; set; }
        public string Value { get; set; }

        public wsMarker(PointF pf, Color cor, string val)
        {
            PointF = pf;
            Color = cor;
            Value = val;
        }
    }
    #endregion
}

农业作物成熟度实例分割数据集 一、基础信息 • 数据集名称:农业作物成熟度实例分割数据集 • 图片数量: 训练集:563张图片 验证集:161张图片 测试集:80张图片 总计:804张图片 • 训练集:563张图片 • 验证集:161张图片 • 测试集:80张图片 • 总计:804张图片 • 分类类别: bfullyripened: b类作物完全成熟状态 bgreen: b类作物绿色未成熟状态 bhalfripened: b类作物半成熟状态 lfullyripened: l类作物完全成熟状态 lgreen: l类作物绿色未成熟状态 lhalfripened: l类作物半成熟状态 • bfullyripened: b类作物完全成熟状态 • bgreen: b类作物绿色未成熟状态 • bhalfripened: b类作物半成熟状态 • lfullyripened: l类作物完全成熟状态 • lgreen: l类作物绿色未成熟状态 • lhalfripened: l类作物半成熟状态 • 标注格式:YOLO格式,包含实例分割多边形点标注,适用于实例分割任务。 • 数据格式:图片来源于农业图像数据库,细节清晰,适用于模型训练。 二、适用场景 • 农业AI监测系统开发:数据集支持实例分割任务,帮助构建能够自动识别作物部分并分类成熟度的AI模型,辅助农民进行精准农业管理。 • 精准农业应用研发:集成至农业智能平台,提供实时作物状态识别功能,优化灌溉、施肥和收获时间。 • 学术研究与创新:支持农业科学与人工智能交叉领域的研究,助力发表高水平农业AI论文。 • 农业教育与培训:数据集可用于农业院校或培训机构,作为学生学习作物识别和成熟度评估的重要资源。 三、数据集优势 • 精准标注与多样性:每张图片均经过精确标注,确保实例分割边界准确,类别分类正确。涵盖两种作物类型(b和l)和三种成熟度状态(完全成熟、绿色未成熟、半成熟),具有高度多样性,提升模型泛化能力。 • 任务适配性强:标注兼容主流深度学习框架(如YOLO等),可直接加载使用,支持实例分割任务,并可扩展到其他计算机视觉任务。 • 农业价值突出:专注于作物成熟度检测,为智能农业、自动化收获和作物健康监测提供关键数据支持,具有重要的实际应用价值。
本资源包提供了针对STM32F103C8微控制器的MPU6050加速度计和陀螺仪的软件I2C驱动程序。通过集成数字运动处理(DMP)技术,能够实现高精度的姿态解算,适用于需要实时感知设备方向和动作的应用场景。此驱动还支持OLED显示屏,直接在设备上展示姿态信息,如俯仰、滚转和偏航角度,非常适合飞行器、机器人或是任何需要姿态监测的项目。 主要特点 软件I2C实现:无需专用的硬件I2C接口,适用于资源有限的STM32F103C8开发板。 DMP姿态解算:利用MPU6050内置的DMP,提供准确的姿态估计。 OLED显示集成:可以直接在OLED屏幕上显示加速度和角速度等姿态数据,便于实时监控。 兼容性说明:已验证与匿名地面站通信协议6.0版本兼容,特别适合与V6.56版本的地面站软件配合使用。 示例代码:包含完整的演示代码,方便用户快速上手并进行二次开发。 使用指南 环境配置:确保你的开发环境支持STM32F103C8,推荐使用STM32CubeIDE或Keil uVision等IDE。 库文件导入:将提供的源码文件夹导入到你的工程中。 配置I2C和OLED:根据你具体的硬件连接调整I2C引脚配置及OLED初始化设置。 连接MPU6050:按照电路图正确连接MPU6050传感器至STM32F103C8的I2C线路上。 编译与调试:编译项目,并通过ST-LINK或其他编程器将固件烧录到STM32F103C8。 测试与应用:运行程序,观察OLED屏幕上的姿态数据显示,可通过匿名地面站软件进行远程监控(需符合通信协议)。
内容概要:本文介绍了在MATLAB平台上实现的基于CNN-SVM融合模型的多特征分类预测项目,通过结合卷积神经网络(CNN)强大的自动特征提取能力与支持向量机(SVM)优异的分类泛化性能,构建了一种高精度、强鲁棒性的混合分类框架。项目详细阐述了模型的整体架构,包括数据预处理、CNN特征提取、全连接层输出、特征降维与标准化、SVM分类决策等模块,并针对多源高维特征融合、小样本不平衡、特征空间不匹配、模型效率与可解释性等实际挑战提出相应解决方案。文中还提供了部分代码示例和性能评估方法,展示了该模型在图像、医疗、金融等多领域的应用潜力。; 适合人群:具备一定机器学习和MATLAB编程基础,从事数据分析、智能系统开发或相关研究工作的高校师生、科研人员及工程技术人员;适合有一定深度学习背景、希望探索模型融合技术的中级开发者。; 使用场景及目标:①应用于多特征、小样本、类别不平衡的复杂分类任务,如医学图像识别、金融欺诈检测、工业故障诊断等;②提升分类准确率与模型泛化能力,同时增强决策可解释性;③为实际业务场景提供可复用、可扩展的智能分类解决方案。; 阅读建议:建议结合MATLAB深度学习工具箱动手实践,重点关注CNN特征提取与SVM分类的衔接流程,理解特征降维与标准化的关键作用,并通过调整网络结构、核函数参数等进行模型优化实验,深入掌握融合模型的设计思想与调参技巧。
源码地址: https://pan.quark.cn/s/a4b39357ea24 @TOC MatlabSimulinkBookExample 图书:《Matlab/Simulink与控制系统仿真》 Matlab 计算基础 表2.1 Matlab 常用文件管理命令 表2.2 Matlab 常用帮助命令 表2.3 Matlab 默认常量 表2.4 Matlab 的数据显示格式 表2.5 Matlab 常用特殊矩阵生成函数 表2.6 矩阵基本运算 表2.7 常用矩阵函数运算 表2.8 常用矩阵分解运算函数 表2.9 关系运算符 表2.10 逻辑运算符 表2.11 关系运算函数 表2.12 逻辑运算函数 6 符号运算 定义符号变量(表达式) 表示 f 关于 x 求 n 阶导数 表示 f 关于 r 求从 x0 到 x1 的定积分 7 复数运算基础 对符号函数中自变量进行赋值 e.g. subs(f, {x,y}, {-1,2}) 对函数 f 中自变量 x 和 y 分别赋值 -1 和 2 绘制极坐标图 表2.13 复数的结构操作函数 求有理式的留数 拉氏变换 拉氏反变换 Z变换 Z反变换 8 Matlab 常用绘图命令 所有画二维图形的命令 所有画三维图形的命令 图形窗口 分割图形 9 Matlab 程序设计 Simulink 仿真 控制系统数学模型 微分方程求解 微分方程求解 分子多项式 分母多项式 多项式乘法函数 多项式求根函数 由根创建多项式函数 求多项式在给定点的值函数 建立传递函数模型的函数 提取模型中分子分母多项式系数的函数 建立零极点形式的数学模型 提取模型中零极点和增益向量的函数 传递函数模型部分分式展开的函数 建立状态空间模型的函数 提取模型中状态空...
数据集介绍:绝缘子孔洞检测数据集 一、基础信息 数据集名称:绝缘子孔洞检测数据集 图片数量: - 训练集:443张图片 - 验证集:101张图片 - 测试集:23张图片 - 总计:567张图片 分类类别: - 孔洞(hole):表示绝缘子上存在的孔洞缺陷区域。 - 无孔洞(not_hole):表示绝缘子正常或无缺陷的区域。 标注格式:YOLO格式,包含实例分割的多边形坐标,适用于实例分割任务。 数据格式:JPEG图片,来源于工业检查场景。 二、适用场景 电力设施绝缘子缺陷自动检测系统开发: 数据集支持实例分割任务,帮助构建AI模型自动识别并分割绝缘子上的孔洞缺陷,辅助维护人员快速定位问题。 工业自动化与无人机巡检: 集成至自动化检查系统,如无人机拍摄的绝缘子图像,实现实时缺陷检测和报警。 学术研究与技术创新: 支持计算机视觉在工业检测领域的应用研究,推动AI技术在电力行业的落地。 安全维护与风险评估: 用于电力线路的定期检查,预防因绝缘子损坏引发的安全事故,提升电网可靠性。 三、数据集优势 精准标注与实例分割: 每张图片均采用YOLO格式进行实例分割标注,多边形坐标精确勾勒缺陷区域,确保模型学习准确。 类别简单明确: 专注于孔洞缺陷的二分类,模型训练高效,适用于实际工业场景中的缺陷检测需求。 数据覆盖全面: 包含567张图片,涵盖训练、验证和测试集,支持模型开发和评估。 任务适配性强: 标注兼容主流深度学习框架,可直接用于实例分割任务,并可扩展至目标检测或分类任务。 实际应用价值高: 直接针对电力行业绝缘子检查需求,有助于提高检查效率、降低人工成本,并提升电网安全。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值