From be63c89ef348e66982ceed3901d9b016eccf9219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=9A=D1=83=D0=B7=D0=BD?= =?UTF-8?q?=D0=B5=D1=86=D0=BE=D0=B2?= Date: Mon, 4 Mar 2024 20:51:55 +0300 Subject: [PATCH] 2 --- Test_img/Form1.Designer.cs | 92 +++++++-- Test_img/Form1.cs | 375 +++++++++++++++++++++++++++++++------ Test_img/Test_img.csproj | 1 + Test_img/olo1.cs | 219 +++++++++++++++------- 4 files changed, 552 insertions(+), 135 deletions(-) diff --git a/Test_img/Form1.Designer.cs b/Test_img/Form1.Designer.cs index 466f986..62e5557 100644 --- a/Test_img/Form1.Designer.cs +++ b/Test_img/Form1.Designer.cs @@ -59,8 +59,14 @@ this.img_search = new System.Windows.Forms.ToolStripMenuItem(); this.img_fon = new System.Windows.Forms.ToolStripMenuItem(); this.img_save = new System.Windows.Forms.ToolStripMenuItem(); + this.img_clusters = new System.Windows.Forms.ToolStripMenuItem(); + this.show_mass_center = new System.Windows.Forms.ToolStripMenuItem(); + this.minus_fon2 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); this.timer1 = new System.Windows.Forms.Timer(this.components); this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.trackbar1 = new Test_img.ToolStripMenuItem(); + this.Label1 = new Test_img.ToolStripLabel(); this.statusStrip1.SuspendLayout(); this.menu.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); @@ -212,16 +218,19 @@ // // MenuItem3 // - this.MenuItem3.AutoSize = false; this.MenuItem3.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.toolStripMenuItem5, this.img_smooth, this.img_center, this.img_search, this.img_fon, - this.img_save}); + this.img_save, + this.img_clusters, + this.toolStripSeparator2, + this.trackbar1, + this.Label1}); this.MenuItem3.Name = "MenuItem3"; - this.MenuItem3.Size = new System.Drawing.Size(122, 20); + this.MenuItem3.Size = new System.Drawing.Size(95, 20); this.MenuItem3.Text = "Инструменты"; // // toolStripMenuItem5 @@ -233,7 +242,7 @@ this.toolStripSeparator1, this.img_timer}); this.toolStripMenuItem5.Name = "toolStripMenuItem5"; - this.toolStripMenuItem5.Size = new System.Drawing.Size(180, 22); + this.toolStripMenuItem5.Size = new System.Drawing.Size(230, 22); this.toolStripMenuItem5.Text = "Демо-картинка"; // // img1 @@ -278,7 +287,7 @@ this.img_smooth.CheckOnClick = true; this.img_smooth.Image = global::Test_img.Properties.Resources.CheckBoxUnchecked; this.img_smooth.Name = "img_smooth"; - this.img_smooth.Size = new System.Drawing.Size(180, 22); + this.img_smooth.Size = new System.Drawing.Size(230, 22); this.img_smooth.Text = "Размытие"; this.img_smooth.Click += new System.EventHandler(this.img_smooth_Click); // @@ -289,7 +298,7 @@ this.minus_fon}); this.img_center.Image = global::Test_img.Properties.Resources.CheckBoxUnchecked; this.img_center.Name = "img_center"; - this.img_center.Size = new System.Drawing.Size(180, 22); + this.img_center.Size = new System.Drawing.Size(230, 22); this.img_center.Text = "Центр масс"; this.img_center.Click += new System.EventHandler(this.img_center_Click); // @@ -298,7 +307,7 @@ this.minus_fon.CheckOnClick = true; this.minus_fon.Image = global::Test_img.Properties.Resources.CheckBoxUnchecked; this.minus_fon.Name = "minus_fon"; - this.minus_fon.Size = new System.Drawing.Size(180, 22); + this.minus_fon.Size = new System.Drawing.Size(152, 22); this.minus_fon.Text = "Вычитать фон"; this.minus_fon.Click += new System.EventHandler(this.minus_fon_Click); // @@ -307,24 +316,59 @@ this.img_search.CheckOnClick = true; this.img_search.Image = global::Test_img.Properties.Resources.CheckBoxUnchecked; this.img_search.Name = "img_search"; - this.img_search.Size = new System.Drawing.Size(180, 22); - this.img_search.Text = "Поиск пятна"; + this.img_search.Size = new System.Drawing.Size(230, 22); + this.img_search.Text = "Поиск пикселей"; this.img_search.Click += new System.EventHandler(this.img_search_Click); // // img_fon // this.img_fon.Name = "img_fon"; - this.img_fon.Size = new System.Drawing.Size(180, 22); + this.img_fon.Size = new System.Drawing.Size(230, 22); this.img_fon.Text = "Фон"; this.img_fon.Click += new System.EventHandler(this.img_fon_Click); // // img_save // this.img_save.Name = "img_save"; - this.img_save.Size = new System.Drawing.Size(180, 22); + this.img_save.Size = new System.Drawing.Size(230, 22); this.img_save.Text = "Скриншот"; this.img_save.Click += new System.EventHandler(this.screenshot_Click); // + // img_clusters + // + this.img_clusters.CheckOnClick = true; + this.img_clusters.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.show_mass_center, + this.minus_fon2}); + this.img_clusters.Image = global::Test_img.Properties.Resources.CheckBoxUnchecked; + this.img_clusters.Name = "img_clusters"; + this.img_clusters.Size = new System.Drawing.Size(230, 22); + this.img_clusters.Text = "Поиск кластеров"; + this.img_clusters.Click += new System.EventHandler(this.img_clusters_Click); + // + // show_mass_center + // + this.show_mass_center.CheckOnClick = true; + this.show_mass_center.Image = global::Test_img.Properties.Resources.CheckBoxUnchecked; + this.show_mass_center.Name = "show_mass_center"; + this.show_mass_center.Size = new System.Drawing.Size(213, 22); + this.show_mass_center.Text = "Показывать центры масс"; + this.show_mass_center.Click += new System.EventHandler(this.show_mass_center_Click); + // + // minus_fon2 + // + this.minus_fon2.CheckOnClick = true; + this.minus_fon2.Image = global::Test_img.Properties.Resources.CheckBoxUnchecked; + this.minus_fon2.Name = "minus_fon2"; + this.minus_fon2.Size = new System.Drawing.Size(213, 22); + this.minus_fon2.Text = "Вычитать фон"; + this.minus_fon2.Click += new System.EventHandler(this.minus_fon2_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(227, 6); + // // timer1 // this.timer1.Enabled = true; @@ -348,6 +392,26 @@ this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseMove); this.pictureBox1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseUp); // + // trackbar1 + // + this.trackbar1.AutoSize = false; + this.trackbar1.Maximum = 255; + this.trackbar1.Name = "trackbar1"; + this.trackbar1.Size = new System.Drawing.Size(170, 20); + this.trackbar1.Text = "Порог"; + this.trackbar1.TickFrequency = 1; + this.trackbar1.TickStyle = System.Windows.Forms.TickStyle.None; + this.trackbar1.Value = 200; + this.trackbar1.ValueChanged += new System.EventHandler(this.trackbar1_ValueChanged); + // + // Label1 + // + this.Label1.AutoSize = false; + this.Label1.Name = "Label1"; + this.Label1.Size = new System.Drawing.Size(50, 15); + this.Label1.Text = "200"; + this.Label1.TextAlign = System.Drawing.ContentAlignment.TopLeft; + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -411,6 +475,12 @@ private System.Windows.Forms.ToolStripMenuItem img_timer; private System.Windows.Forms.ToolStripMenuItem img_smooth; private System.Windows.Forms.ToolStripMenuItem minus_fon; + private System.Windows.Forms.ToolStripMenuItem img_clusters; + private System.Windows.Forms.ToolStripMenuItem show_mass_center; + private System.Windows.Forms.ToolStripMenuItem minus_fon2; + private ToolStripMenuItem trackbar1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private ToolStripLabel Label1; } } diff --git a/Test_img/Form1.cs b/Test_img/Form1.cs index 60f0322..64ea6f5 100644 --- a/Test_img/Form1.cs +++ b/Test_img/Form1.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Reflection; using System.Windows.Forms; +using System.Windows.Forms.Design; using UTIL; namespace Test_img @@ -44,6 +46,12 @@ namespace Test_img public Form1() { InitializeComponent(); + //ToolStripControlHost trackBar1 = new ToolStripControlHost(new TrackBar()); + + //trackBar1.AutoSize = false; + //trackBar1.Size = new Size(150, 10); + //MenuItem3.DropDownItems.Add(trackBar1); + //statusStrip1.Items.Add(trackBar1); } private void Form1_Load(object sender, EventArgs e) @@ -51,14 +59,15 @@ namespace Test_img pictureBox1.MouseWheel += new MouseEventHandler(pictureBox1_MouseWheel); resolution = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Size; img_aspect.Text = $"Аспект: {zoomFactor:F3}"; - StaticData.ValueChanged += (sender1, e1) => - { - imgsearch = StaticData.DataBuffer; - //img_srch.Text = StaticData.DataBuffer.ToString(); - }; - StaticData.SHandlerSearch = new StaticData.SHandler(SearchPixel); + //StaticData.ValueChanged += (sender1, e1) => + //{ + // imgsearch = StaticData.DataBuffer; + // //img_srch.Text = StaticData.DataBuffer.ToString(); + //}; + //StaticData.SHandlerSearch = new StaticData.SHandler(SearchPixel); pictureBox1.Image = bm = new Bitmap(pictureBox1.Width, pictureBox1.Height); - StaticData.TrgEventHandler += SearchPixel2; + // StaticData.TrgEventHandler += SearchPixel2; + Label1.Text = trackbar1.Value.ToString(); } private void Form1_SizeChanged(object sender, EventArgs e) @@ -80,6 +89,8 @@ namespace Test_img movingPoint = new Point((pictureBox1.Width - bm.Width) / 2, (pictureBox1.Height - bm.Height) / 2); pictureBox1.Invalidate(); } + + #region Мышиные события private void pictureBox1_MouseEnter(object sender, EventArgs e) { pictureBox1.MouseWheel += pictureBox1_MouseWheel; @@ -186,6 +197,8 @@ namespace Test_img yyy.Text = $"{xPos:D4} {yPos:D4}"; } } + + #endregion private void pictureBox1_Paint(object sender, PaintEventArgs e) { e.Graphics.Clear(Color.White); @@ -195,18 +208,47 @@ namespace Test_img e.Graphics.DrawRectangle(new Pen(Color.Green, 1), nrect(startSelPoint, stopSelPoint)); if (img_center.Checked) { - e.Graphics.DrawLine(new Pen(Color.LimeGreen, 1), - BmToPb(MassCenter).X, - BmToPb(MassCenter).Y - 20, - BmToPb(MassCenter).X, - BmToPb(MassCenter).Y + 20); e.Graphics.DrawLine(new Pen(Color.LimeGreen, 1), - BmToPb(MassCenter).X - 20, - BmToPb(MassCenter).Y, - BmToPb(MassCenter).X + 20, - BmToPb(MassCenter).Y); - e.Graphics.DrawRectangle(new Pen(Color.LimeGreen, 1), BmToPb(MassCenter).X - 20, BmToPb(MassCenter).Y - 20, 40, 40); + PointBmToPb(MassCenter).X, + PointBmToPb(MassCenter).Y - 20, + PointBmToPb(MassCenter).X, + PointBmToPb(MassCenter).Y + 20); + e.Graphics.DrawLine(new Pen(Color.LimeGreen, 1), + PointBmToPb(MassCenter).X - 20, + PointBmToPb(MassCenter).Y, + PointBmToPb(MassCenter).X + 20, + PointBmToPb(MassCenter).Y); + e.Graphics.DrawRectangle(new Pen(Color.LimeGreen, 1), PointBmToPb(MassCenter).X - 20, PointBmToPb(MassCenter).Y - 20, 40, 40); + } + if (img_clusters.Checked) + { + SearchClusters((UInt16)imgsearch); + for (int m = 0; m < g_super_cluster_count; m++) + { + e.Graphics.DrawRectangle(new Pen(Color.Cyan, 1), + PointBmToPb(new Point(g_super_cluster_coords[m].rect.left, g_super_cluster_coords[m].rect.top)).X, + PointBmToPb(new Point(g_super_cluster_coords[m].rect.left, g_super_cluster_coords[m].rect.top)).Y, + (g_super_cluster_coords[m].rect.right - g_super_cluster_coords[m].rect.left) * zoomFactor, + (g_super_cluster_coords[m].rect.bottom - g_super_cluster_coords[m].rect.top) * zoomFactor); + if (show_mass_center.Checked) + { + Point r = CalcCenterMass(CLUSTER_COORD2Rect(g_super_cluster_coords[m])); + Point rct = PointBmToPb(r); + e.Graphics.DrawLine(new Pen(Color.LimeGreen, 1), rct.X, rct.Y - 20, rct.X, rct.Y + 20); + e.Graphics.DrawLine(new Pen(Color.LimeGreen, 1), rct.X - 20, rct.Y, rct.X + 20, rct.Y); + } + } + } + if (img_search.Checked) + { + foreach (var pnt in SearchPixel2(imgsearch)) + e.Graphics.DrawEllipse(new Pen(Color.Red), + PointBmToPb(pnt).X - 5 * zoomFactor, + PointBmToPb(pnt).Y - 5 * zoomFactor, + 10 * zoomFactor, + 10 * zoomFactor); } + GC.Collect(); } public Bitmap ResizeImage(Image image, float zoom) @@ -260,36 +302,36 @@ namespace Test_img return new Rectangle(p3, new Size(p4.X - p3.X, p2.Y - p3.Y)); return r; } - private void SearchPixel() - { - List points = new List(); - Stopwatch stopwatch = Stopwatch.StartNew(); - UnsafeBitmap btm = new UnsafeBitmap(bm); - btm.LockBitmap(); - for (int y = 0; y < bm.Height; y++) - { - for (int x = 0; x < bm.Width; x++) - { - PixelData c = btm.GetPixel(x, y); - if (c.blue >= imgsearch) - { - points.Add(new Point(x, y)); - //Console.WriteLine($"{x} {y}"); - } - } - } - stopwatch.Stop(); - Console.WriteLine(stopwatch.Elapsed.ToString()); - btm.Dispose(); - using (Graphics g = Graphics.FromImage(newbm)) - { - //g.Clear(Color.White); - for (int i = 0; i < points.Count; i++) - g.DrawEllipse(new Pen(Color.Red), points[i].X - 5, points[i].Y - 5, 10, 10); + //private void SearchPixel() + //{ + // List points = new List(); + // Stopwatch stopwatch = Stopwatch.StartNew(); + // UnsafeBitmap btm = new UnsafeBitmap(bm); + // btm.LockBitmap(); + // for (int y = 0; y < bm.Height; y++) + // { + // for (int x = 0; x < bm.Width; x++) + // { + // PixelData c = btm.GetPixel(x, y); + // if (c.blue >= imgsearch) + // { + // points.Add(new Point(x, y)); + // //Console.WriteLine($"{x} {y}"); + // } + // } + // } + // stopwatch.Stop(); + // Console.WriteLine(stopwatch.Elapsed.ToString()); + // btm.Dispose(); + // using (Graphics g = Graphics.FromImage(newbm)) + // { + // //g.Clear(Color.White); + // for (int i = 0; i < points.Count; i++) + // g.DrawEllipse(new Pen(Color.Red), points[i].X - 5, points[i].Y - 5, 10, 10); - } - pictureBox1.Invalidate(); - } + // } + // pictureBox1.Invalidate(); + //} private Point CalcCenterMass(Rectangle r) { Int32 sX = 0; @@ -305,7 +347,7 @@ namespace Test_img for (int x = r.X; x < r.Right; x++) { PixelData c = btm.GetPixel(x, y); - if (minus_fon.Checked) + if (minus_fon.Checked || minus_fon2.Checked) { sX += (Int32)((c.blue - fon) * x); sY += (Int32)((c.blue - fon) * y); @@ -327,16 +369,20 @@ namespace Test_img sX /= sZ; sY /= sZ; btm.Dispose(); - Console.WriteLine($"num: {num} num2: {r.Width * r.Height} x: {sX} y: {sY}"); + //Console.WriteLine($"num: {num} num2: {r.Width * r.Height} x: {sX} y: {sY}"); return new Point(sX, sY); } else return Point.Empty; } - private Point BmToPb(Point p) + private Point PointBmToPb(Point p) { return new Point((int)(p.X * zoomFactor + movingPoint.X), (int)(p.Y * zoomFactor + movingPoint.Y)); } + private Rectangle RectBmToPb(Rectangle p) + { + return new Rectangle((int)(p.X * zoomFactor + movingPoint.X), (int)(p.Y * zoomFactor + movingPoint.Y), (int)(p.Width * zoomFactor), (int)(p.Height * zoomFactor)); + } #region Меню private void img_load_Click(object sender, EventArgs e) @@ -382,13 +428,13 @@ namespace Test_img if (img_search.Checked) { img_search.Image = Properties.Resources.CheckBoxChecked; - srch.Show(); - StaticData.Fon?.Invoke(fon); + //srch.Show(); + //StaticData.Fon?.Invoke(fon); } else { img_search.Image = Properties.Resources.CheckBoxUnchecked; - srch.Hide(); + //srch.Hide(); } } private void img_save_Click(object sender, EventArgs e) @@ -467,8 +513,26 @@ namespace Test_img } #endregion - private void SearchPixel2() + private List SearchPixel2(int isrch) { + List points = new List(); + Stopwatch stopwatch = Stopwatch.StartNew(); + UnsafeBitmap btm = new UnsafeBitmap(bm); + btm.LockBitmap(); + for (int y = 0; y < bm.Height; y++) + { + for (int x = 0; x < bm.Width; x++) + { + PixelData c = btm.GetPixel(x, y); + if (c.blue >= isrch && c.red >= isrch && c.green >= isrch) + { + points.Add(new Point(x, y)); + } + } + } + stopwatch.Stop(); + btm.Dispose(); + return points; } private void img_fon_Click(object sender, EventArgs e) @@ -513,6 +577,8 @@ namespace Test_img btm.UnlockBitmap(); btm.Dispose(); fon = sc; + trackbar1.Value = (int)fon + 1; + imgsearch = (int)fon; StaticData.Fon?.Invoke(sc); } @@ -533,10 +599,6 @@ namespace Test_img private void timer1_Tick(object sender, EventArgs e) { newbm = (Bitmap)bm.Clone(); - if (img_search.Checked) - { - SearchPixel(); - } pictureBox1.Invalidate(); } @@ -563,5 +625,204 @@ namespace Test_img minus_fon.Image = Properties.Resources.CheckBoxUnchecked; } } + + private void img_clusters_Click(object sender, EventArgs e) + { + if (img_clusters.Checked) + { + img_clusters.Image = Properties.Resources.CheckBoxChecked; + } + else + { + img_clusters.Image = Properties.Resources.CheckBoxUnchecked; + minus_fon2.Image = Properties.Resources.CheckBoxUnchecked; + minus_fon2.Checked = false; + show_mass_center.Image = Properties.Resources.CheckBoxUnchecked; + show_mass_center.Checked = false; + } + SearchClusters((UInt16)imgsearch); + } + + private void show_mass_center_Click(object sender, EventArgs e) + { + if (show_mass_center.Checked) + { + show_mass_center.Image = Properties.Resources.CheckBoxChecked; + img_clusters.Image = Properties.Resources.CheckBoxChecked; + img_clusters.Checked = true; + SearchClusters((UInt16)imgsearch); + } + else + { + show_mass_center.Image = Properties.Resources.CheckBoxUnchecked; + //img_clusters.Image = Properties.Resources.CheckBoxUnchecked; + //img_clusters.Checked = false; + } + } + + private void minus_fon2_Click(object sender, EventArgs e) + { + if (show_mass_center.Checked) + { + minus_fon2.Image = Properties.Resources.CheckBoxChecked; + } + else + { + minus_fon2.Image = Properties.Resources.CheckBoxUnchecked; + } + } + + private void trackbar1_ValueChanged(object sender, EventArgs e) + { + Label1.Text = trackbar1.Value.ToString(); + imgsearch = trackbar1.Value; + } + } + + #region Компоненты меню + [System.ComponentModel.DesignerCategory("code")] + [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ContextMenuStrip | ToolStripItemDesignerAvailability.MenuStrip)] + public partial class ToolStripMenuItem : ToolStripControlHost + { + public ToolStripMenuItem() + : base(CreateControlInstance()) + { + } + /// + /// Create a strongly typed property called TrackBar - handy to prevent casting everywhere. + /// + public TrackBar TrackBar + { + get + { + return Control as TrackBar; + } + } + /// + /// Create the actual control, note this is static so it can be called from the + /// constructor. + /// + /// + /// + private static Control CreateControlInstance() + { + TrackBar t = new TrackBar(); + t.AutoSize = false; + // Add other initialization code here. + return t; + } + [DefaultValue(0)] + public int Value + { + get { return TrackBar.Value; } + set { TrackBar.Value = value; } + } + /// + /// Attach to events we want to re-wrap + /// + /// + [DefaultValue(0)] + public int Minimum + { + get { return TrackBar.Minimum; } + set { TrackBar.Minimum = value; } + } + [DefaultValue(100)] + public int Maximum + { + get { return TrackBar.Maximum; } + set { TrackBar.Maximum = value; } + } + [DefaultValue(10)] + public int TickFrequency + { + get { return TrackBar.TickFrequency; } + set { TrackBar.TickFrequency = value; } + } + public TickStyle TickStyle + { + get { return TrackBar.TickStyle; } + set { TrackBar.TickStyle = value; } + } + protected override void OnSubscribeControlEvents(Control control) + { + base.OnSubscribeControlEvents(control); + TrackBar trackBar = control as TrackBar; + trackBar.ValueChanged += new EventHandler(trackBar_ValueChanged); + } + /// + /// Detach from events. + /// + /// + protected override void OnUnsubscribeControlEvents(Control control) + { + base.OnUnsubscribeControlEvents(control); + TrackBar trackBar = control as TrackBar; + trackBar.ValueChanged -= new EventHandler(trackBar_ValueChanged); + } + /// + /// Routing for event + /// TrackBar.ValueChanged -> ToolStripTrackBar.ValueChanged + /// + /// + /// + void trackBar_ValueChanged(object sender, EventArgs e) + { + // when the trackbar value changes, fire an event. + if (this.ValueChanged != null) + { + ValueChanged(sender, e); + } + } + // add an event that is subscribable from the designer. + public event EventHandler ValueChanged; + // set other defaults that are interesting + protected override Size DefaultSize + { + get + { + return new Size(200, 16); + } + } + } + [System.ComponentModel.DesignerCategory("code")] + [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ContextMenuStrip | ToolStripItemDesignerAvailability.MenuStrip)] + public partial class ToolStripLabel : ToolStripControlHost + { + public ToolStripLabel() : base(CreateControlInstance()) + { + } + public Label Label + { + get + { + return Control as Label; + } + } + private static Control CreateControlInstance() + { + Label t = new Label(); + t.AutoSize = false; + // Add other initialization code here. + return t; + } + //public String Text + //{ + // get { return Label.Text; } + // set { Label.Text = value; } + //} + //public System.Drawing.ContentAlignment TextAlign + //{ + // get { return Label.TextAlign; } + // set { Label.TextAlign = value; } + //} + //protected override Size DefaultSize + //{ + // get + // { + // return new Size(200, 16); + // } + //} } + #endregion } diff --git a/Test_img/Test_img.csproj b/Test_img/Test_img.csproj index 947fa2a..bf43404 100644 --- a/Test_img/Test_img.csproj +++ b/Test_img/Test_img.csproj @@ -65,6 +65,7 @@ search.cs + Form1.cs diff --git a/Test_img/olo1.cs b/Test_img/olo1.cs index d6242a8..6e0ea41 100644 --- a/Test_img/olo1.cs +++ b/Test_img/olo1.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Drawing; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -35,138 +36,222 @@ namespace Test_img public UInt16 right; public UInt16 bottom; } + + const UInt16 CELL_SIZE = 8; // cluster cell size, in pix + const Byte __FALSE = 0; + const Byte __TRUE = 1; + const Byte NO_MARKER = 0; // 'no marker' cluster identifier + //static UInt16 IMAGE_CELL_CX = (UInt16)((IMAGE_CX + CELL_SIZE - 1) / CELL_SIZE); + //static UInt16 IMAGE_CELL_CY = (UInt16)((IMAGE_CY + CELL_SIZE - 1) / CELL_SIZE); + static UInt16 IMAGE_CELL_CX = 0; // (UInt16)((IMAGE_CX + CELL_SIZE - 1) / CELL_SIZE); + static UInt16 IMAGE_CELL_CY = 0; // (UInt16)((IMAGE_CY + CELL_SIZE - 1) / CELL_SIZE); + List v = new List(); List FIFO_ITEM_f = new List(); - static UInt16 IMAGE_CX = (320 - 1); - static UInt16 IMAGE_CY = (256 - 1); - static UInt16 CELL_SIZE = 8; // cluster cell size, in pix - UInt16 IMAGE_CELL_CX = (UInt16)((IMAGE_CX + CELL_SIZE - 1) / CELL_SIZE); - UInt16 IMAGE_CELL_CY = (UInt16)((IMAGE_CY + CELL_SIZE - 1) / CELL_SIZE); - private void GetPix() + static UInt16 IMAGE_CX = 0; + static UInt16 IMAGE_CY = 0; + static FIFO_ITEM[] g_shot_array = new FIFO_ITEM[4096]; // shot XY-coordinates from FIFO1 + static UInt16 g_shot_count; // number of shot XY-coordinate pairs in FIFO1 + static UInt16 g_cluster_count; // number of clusters (8x8) in FIFO1 + static UInt16 g_super_cluster_count; // number of super clusters in FIFO1 + static CLUSTER_COORD[] g_cluster_coords = null; // new CLUSTER_COORD[IMAGE_CELL_CX * IMAGE_CELL_CY]; // clusters mass centre & coordinates in FIFO1 + static CLUSTER_COORD[] g_cluster_ptrs = null; // new CLUSTER_COORD[IMAGE_CELL_CX * IMAGE_CELL_CY]; // + static CLUSTER_COORD[] g_super_cluster_coords = null; // new CLUSTER_COORD[IMAGE_CELL_CX * IMAGE_CELL_CY]; + + StreamWriter logsw = null; + + private void SearchClusters(UInt16 porog) + { + InitClusters(); + GetPix(porog); + BuildClustersArray(); + EnlargeClustersInArray(); + } + private void InitClusters() + { + IMAGE_CX = (UInt16)(bm.Width - 1); + IMAGE_CY = (UInt16)(bm.Height - 1); + IMAGE_CELL_CX = (UInt16)((IMAGE_CX + CELL_SIZE - 1) / CELL_SIZE); + IMAGE_CELL_CY = (UInt16)((IMAGE_CY + CELL_SIZE - 1) / CELL_SIZE); + g_cluster_coords = new CLUSTER_COORD[IMAGE_CELL_CX * IMAGE_CELL_CY]; // clusters mass centre & coordinates in FIFO1 + g_cluster_ptrs = new CLUSTER_COORD[IMAGE_CELL_CX * IMAGE_CELL_CY]; // + g_super_cluster_coords = new CLUSTER_COORD[IMAGE_CELL_CX * IMAGE_CELL_CY]; + + String logfilename = "log_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".log"; + //logsw = new StreamWriter(logfilename, false); + //logsw.WriteLine($"IMAGE_CX {IMAGE_CX}"); + //logsw.WriteLine($"IMAGE_CY {IMAGE_CY}"); + //logsw.WriteLine($"IMAGE_CELL_CX {IMAGE_CELL_CX}"); + //logsw.WriteLine($"IMAGE_CELL_CY {IMAGE_CELL_CY}"); + //logsw.WriteLine($"g_cluster_coords {IMAGE_CELL_CX * IMAGE_CELL_CY}"); + //logsw.WriteLine($"g_cluster_ptrs {IMAGE_CELL_CX * IMAGE_CELL_CY}"); + //logsw.WriteLine($"g_super_cluster_coords {IMAGE_CELL_CX * IMAGE_CELL_CY}"); + //logsw.WriteLine(); + } + private void GetPix(UInt16 porog) { UnsafeBitmap btm = new UnsafeBitmap(bm); btm.LockBitmap(); + g_shot_count = 0; for (int y = 0; y < bm.Height; y++) { for (int x = 0; x < bm.Width; x++) { PixelData c = btm.GetPixel(x, y); - if (c.blue >= imgsearch) + if (c.blue >= porog) { FIFO_ITEM t = new FIFO_ITEM(); t.x = (UInt16)x; t.y = (UInt16)y; + //logsw.WriteLine($"Shoot n={g_shot_count} x={x} y={y}"); + g_shot_array[g_shot_count++] = t; v.Add(t); } } } btm.UnlockBitmap(); btm.Dispose(); + //logsw.WriteLine(); } - unsafe private void BuildClustersArray() + private void BuildClustersArray() { Byte marker; UInt16 i, j, k, count; UInt16 l, t, r, b; - for (i = 0; i < g_shot_count1; i++) + for (i = 0; i < g_shot_count; i++) { - FIFO_ITEM* fi = &g_shot_array1[i]; - UInt16 x = fi->x / CELL_SIZE; - UInt16 y = fi->y / CELL_SIZE; - CLUSTER_COORD* pcc = &g_cluster_coords1[y * IMAGE_CELL_CX + x]; - - pcc->count++; - pcc->excluded = __FALSE; - pcc->marker = NO_MARKER; - pcc->rect.left = (x) * CELL_SIZE; - pcc->rect.top = (y) * CELL_SIZE; - pcc->rect.right = (x + 1) * CELL_SIZE; - pcc->rect.bottom = (y + 1) * CELL_SIZE; + FIFO_ITEM fi = g_shot_array[i]; + UInt16 x = (UInt16)(fi.x / CELL_SIZE); + UInt16 y = (UInt16)(fi.y / CELL_SIZE); + g_cluster_coords[y * IMAGE_CELL_CX + x].count++; + g_cluster_coords[y * IMAGE_CELL_CX + x].excluded = __FALSE; + g_cluster_coords[y * IMAGE_CELL_CX + x].marker = NO_MARKER; + g_cluster_coords[y * IMAGE_CELL_CX + x].rect.left = (UInt16)(x * CELL_SIZE); + g_cluster_coords[y * IMAGE_CELL_CX + x].rect.top = (UInt16)(y * CELL_SIZE); + g_cluster_coords[y * IMAGE_CELL_CX + x].rect.right = (UInt16)((x + 1) * CELL_SIZE); + g_cluster_coords[y * IMAGE_CELL_CX + x].rect.bottom = (UInt16)((y + 1) * CELL_SIZE); + + //logsw.WriteLine($"Cl_1 i={i} n={y * IMAGE_CELL_CX + x} " + + // $"count={g_cluster_coords[y * IMAGE_CELL_CX + x].count - 1} " + + // $"excluded={g_cluster_coords[y * IMAGE_CELL_CX + x].excluded} " + + // $"marker={g_cluster_coords[y * IMAGE_CELL_CX + x].marker} " + + // $"left={(UInt16)(x * CELL_SIZE)} " + + // $"top={(UInt16)(y * CELL_SIZE)} " + + // $"right={(UInt16)((x + 1) * CELL_SIZE)} " + + // $"bottom={(UInt16)((y + 1) * CELL_SIZE)}"); } + //logsw.WriteLine(); - memset(g_cluster_ptrs1, 0, sizeof(g_cluster_ptrs1)); - g_cluster_count1 = 0; + g_cluster_count = 0; for (i = 0; i < IMAGE_CELL_CX * IMAGE_CELL_CY; i++) { - if (g_cluster_coords1[i].count > 0) - g_cluster_ptrs1[g_cluster_count1++] = &g_cluster_coords1[i]; + if (g_cluster_coords[i].count > 0) + { + //logsw.WriteLine($"Cl_2 i={i} g_cluster_count{g_cluster_count} x={g_cluster_coords[i].rect.left} y={g_cluster_coords[i].rect.top}"); + g_cluster_ptrs[g_cluster_count++] = g_cluster_coords[i]; + } } + //logsw.WriteLine(); marker = NO_MARKER; - for (i = 0; i < g_cluster_count1; i++) + for (i = 0; i < g_cluster_count; i++) { - CLUSTER_COORD* pcc1 = g_cluster_ptrs1[i]; - S16 x1 = (pcc1->rect.left + pcc1->rect.right) / 2; - S16 y1 = (pcc1->rect.top + pcc1->rect.bottom) / 2; + Int16 x1 = (Int16)((g_cluster_ptrs[i].rect.left + g_cluster_ptrs[i].rect.right) / 2); + Int16 y1 = (Int16)((g_cluster_ptrs[i].rect.top + g_cluster_ptrs[i].rect.bottom) / 2); - if (pcc1->marker == NO_MARKER) - pcc1->marker = (++marker); + if (g_cluster_ptrs[i].marker == NO_MARKER) + g_cluster_ptrs[i].marker = (++marker); - for (j = i + 1; j < g_cluster_count1; j++) + for (j = (UInt16)(i + 1); j < g_cluster_count; j++) { - CLUSTER_COORD* pcc2 = g_cluster_ptrs1[j]; - S16 x2 = (pcc2->rect.left + pcc2->rect.right) / 2; - S16 y2 = (pcc2->rect.top + pcc2->rect.bottom) / 2; + Int16 x2 = (Int16)((g_cluster_ptrs[j].rect.left + g_cluster_ptrs[j].rect.right) / 2); + Int16 y2 = (Int16)((g_cluster_ptrs[j].rect.top + g_cluster_ptrs[j].rect.bottom) / 2); - if (abs(x1 - x2) <= CELL_SIZE && abs(y1 - y2) <= CELL_SIZE) + if (Math.Abs(x1 - x2) <= CELL_SIZE && Math.Abs(y1 - y2) <= CELL_SIZE) { - if (pcc2->marker == NO_MARKER) + if (g_cluster_ptrs[j].marker == NO_MARKER) { - pcc2->marker = pcc1->marker; + g_cluster_ptrs[j].marker = g_cluster_ptrs[i].marker; } else { - for (k = 0; k < g_cluster_count1; k++) + for (k = 0; k < g_cluster_count; k++) { - CLUSTER_COORD* pcc3 = g_cluster_ptrs1[k]; - - if (pcc3->marker == pcc2->marker) - pcc3->marker = pcc1->marker; + if (g_cluster_ptrs[k].marker == g_cluster_ptrs[j].marker) + { + g_cluster_ptrs[k].marker = g_cluster_ptrs[i].marker; + //logsw.WriteLine($"Cl_3 i={i} j={j} k={k} x={g_cluster_ptrs[k].rect.left} y={g_cluster_ptrs[k].rect.top} m={g_cluster_ptrs[k].marker}"); + } } } } } } + //logsw.WriteLine(); - memset(g_super_cluster_coords1, 0, sizeof(g_super_cluster_coords1)); - - g_super_cluster_count1 = 0; + g_super_cluster_count = 0; for (i = 1; i <= marker; i++) { count = 0; - l = 0x7fff, t = 0x7fff, r = 0, b = 0; + l = 0x7fff; + t = 0x7fff; + r = 0; + b = 0; - for (j = 0; j < g_cluster_count1; j++) + for (j = 0; j < g_cluster_count; j++) { - CLUSTER_COORD* pcc = g_cluster_ptrs1[j]; - - if (pcc->marker == i) + if (g_cluster_ptrs[j].marker == i) { - if (pcc->rect.left < l) l = pcc->rect.left; - if (pcc->rect.top < t) t = pcc->rect.top; - if (pcc->rect.right > r) r = pcc->rect.right; - if (pcc->rect.bottom > b) b = pcc->rect.bottom; + if (g_cluster_ptrs[j].rect.left < l) l = g_cluster_ptrs[j].rect.left; + if (g_cluster_ptrs[j].rect.top < t) t = g_cluster_ptrs[j].rect.top; + if (g_cluster_ptrs[j].rect.right > r) r = g_cluster_ptrs[j].rect.right; + if (g_cluster_ptrs[j].rect.bottom > b) b = g_cluster_ptrs[j].rect.bottom; - count += pcc->count; + count += g_cluster_ptrs[j].count; } } if (count > 0) { - printf("marker %d l %d t %d r %d b %d\r\n", i, l, t, r, b); - g_super_cluster_coords1[g_super_cluster_count1].count = count; - g_super_cluster_coords1[g_super_cluster_count1].excluded = __FALSE; - g_super_cluster_coords1[g_super_cluster_count1].marker = NO_MARKER; - g_super_cluster_coords1[g_super_cluster_count1].rect.left = l; - g_super_cluster_coords1[g_super_cluster_count1].rect.top = t; - g_super_cluster_coords1[g_super_cluster_count1].rect.right = r; - g_super_cluster_coords1[g_super_cluster_count1].rect.bottom = b; - g_super_cluster_count1++; - } + g_super_cluster_coords[g_super_cluster_count].count = count; + g_super_cluster_coords[g_super_cluster_count].excluded = __FALSE; + g_super_cluster_coords[g_super_cluster_count].marker = NO_MARKER; + g_super_cluster_coords[g_super_cluster_count].rect.left = l; + g_super_cluster_coords[g_super_cluster_count].rect.top = t; + g_super_cluster_coords[g_super_cluster_count].rect.right = r; + g_super_cluster_coords[g_super_cluster_count].rect.bottom = b; + g_super_cluster_count++; + } } + //for (int m = 0; m < g_super_cluster_count; m++) + //{ + // logsw.WriteLine($"Cl_5 m={m} " + + // $"count={g_super_cluster_coords[m].count} " + + // $"excluded={g_super_cluster_coords[m].excluded} " + + // $"marker={g_super_cluster_coords[m].marker} " + + // $"left={g_super_cluster_coords[m].rect.left} " + + // $"top={g_super_cluster_coords[m].rect.top} " + + // $"right={g_super_cluster_coords[m].rect.right} " + + // $"bottom={g_super_cluster_coords[m].rect.bottom}"); + //} + //logsw.Close(); + } + private void EnlargeClustersInArray() + { + UInt16 i; + for (i = 0; i < g_super_cluster_count; i++) + { + if (g_super_cluster_coords[i].rect.left >= CELL_SIZE) g_super_cluster_coords[i].rect.left -= CELL_SIZE; + if (g_super_cluster_coords[i].rect.top >= CELL_SIZE) g_super_cluster_coords[i].rect.top -= CELL_SIZE; + if (g_super_cluster_coords[i].rect.right <= IMAGE_CX - CELL_SIZE) g_super_cluster_coords[i].rect.right += CELL_SIZE; + if (g_super_cluster_coords[i].rect.bottom <= IMAGE_CY - CELL_SIZE) g_super_cluster_coords[i].rect.bottom += CELL_SIZE; + } + } + private Rectangle CLUSTER_COORD2Rect(CLUSTER_COORD c) + { + return new Rectangle(c.rect.left, c.rect.top, c.rect.right - c.rect.left, c.rect.bottom - c.rect.top); } - } }