using OpenCvSharp; using PaintDotNet.Adjust.BaseImage; using PaintDotNet.ImageCollect; using System; using System.Drawing; using System.Windows.Forms; namespace PaintDotNet.Instrument { /// /// 像素跟踪 /// internal class PixelTrackingDialog : FloatingToolForm { #region 控件 private Label label6; private Label label5; private Label label4; private Label label3; private Label label2; private Label label1; private CustomControl.LinearColorPickerControl panel1; private PictureBox pictureBox1; private Label label7; private Label label8; private NumericUpDown numericUpDown1; private TrackBar trackBar1; private Label label9; #endregion private AppWorkspace appWorkspace; /// /// 原图、hls(可优化)、鹰眼图(从经过缩放的图片获取)、经过缩放的图片 /// private Mat ImageROI, bmat = new Mat(); /// /// rgb像素点 /// private Vec3b bgr; /// /// hls像素点 /// private double h, s, v; /// /// 缩放倍数 /// private int scale; /// /// 中间十字和圆的颜色 /// 根据左侧的panel的被选中的背景色变化 /// private Color color = Color.Red; private Mat mat; public Mat Mat { set { this.mat = value; } } private void trackBar1_ValueChanged(object sender, EventArgs e) { if (mat != null) { scale = this.trackBar1.Value; this.numericUpDown1.Value = this.trackBar1.Value; //Cv2.Resize(mat, bmat, new OpenCvSharp.Size(mat.Width * scale, mat.Height * scale)); //Mat temp = new Mat(new OpenCvSharp.Size(bmat.Width + 100, bmat.Height + 100), bmat.Type()); //Cv2.CopyMakeBorder(bmat, temp, 50, 50, 50, 50, BorderTypes.Constant, Scalar.All(255)); //bmat = temp; } } private void numericUpDown1_ValueChanged(object sender, EventArgs e) { if (mat != null) { scale = (int)this.numericUpDown1.Value; this.trackBar1.Value = scale; //Cv2.Resize(mat, bmat, new OpenCvSharp.Size(mat.Width * scale, mat.Height * scale)); //Mat temp = new Mat(new OpenCvSharp.Size(bmat.Width + 100, bmat.Height + 100), bmat.Type()); //Cv2.CopyMakeBorder(bmat, temp, 50, 50, 50, 50, BorderTypes.Constant, Scalar.All(255)); //bmat = temp; } } /// /// 构造函数 /// /// public PixelTrackingDialog(AppWorkspace appWorkspace) { this.appWorkspace = appWorkspace; InitializeComponent(); this.label9.Text = PdnResources.GetString("Menu.Times.text"); this.Text = PdnResources.GetString("Menu.Tools.PixelTracking.Text"); this.label7.Parent = this.pictureBox1; this.label8.Parent = this.pictureBox1; this.label7.Location = new System.Drawing.Point(0, 0); this.label8.Location = new System.Drawing.Point(0, 17); this.pictureBox1.Paint += new PaintEventHandler(PictureBox1_Paint); } private void PixelTrackingDialog_FormClosing(object sender, FormClosingEventArgs e) { this.appWorkspace.toolBar.RefreshBtnSelect(false, "PixelTracking"); this.appWorkspace.toolsPanel.RefreshBtnSelect(false, "PixelTracking"); } /// /// PictureBox的绘制事件 /// /// /// private void PictureBox1_Paint(object sender, PaintEventArgs e) { e.Graphics.DrawLine(new Pen(color), 0, 50, 100, 50); e.Graphics.DrawLine(new Pen(color), 50, 0, 50, 100); e.Graphics.DrawEllipse(new Pen(color), new Rectangle(25, 25, 50, 50)); } ///// ///// 左侧panel,渐变背景色 ///// ///// ///// //private void Panel1_Paint(object sender, PaintEventArgs e) //{ // LinearGradientBrush brush = new LinearGradientBrush(e.ClipRectangle, Color.Yellow, Color.Blue, LinearGradientMode.Vertical); // ColorBlend colorBlend = new ColorBlend(); // colorBlend.Colors = new Color[]{ Color.Yellow, Color.Red, Color.Green, Color.Blue }; // colorBlend.Positions = new float[] { 0 / 3f, 1 / 3f, 2 / 3f, 3 / 3f }; // brush.InterpolationColors = colorBlend; // e.Graphics.FillRectangle(brush, e.ClipRectangle); //} private void Panel1_ValueChanged(object sender, IndexEventArgs ce) { color = panel1.ValueToColor(panel1.Value); pictureBox1.Refresh(); } private void InitializeComponent() { this.pictureBox1 = new System.Windows.Forms.PictureBox(); this.label6 = new System.Windows.Forms.Label(); this.label5 = new System.Windows.Forms.Label(); this.label4 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label(); this.panel1 = new PaintDotNet.CustomControl.LinearColorPickerControl(); this.label7 = new System.Windows.Forms.Label(); this.label8 = new System.Windows.Forms.Label(); this.numericUpDown1 = new System.Windows.Forms.NumericUpDown(); this.trackBar1 = new System.Windows.Forms.TrackBar(); this.label9 = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit(); this.SuspendLayout(); // // pictureBox1 // this.pictureBox1.Location = new System.Drawing.Point(21, 8); this.pictureBox1.Name = "pictureBox1"; this.pictureBox1.Size = new System.Drawing.Size(100, 100); this.pictureBox1.TabIndex = 1; this.pictureBox1.TabStop = false; // // label6 // this.label6.AutoSize = true; this.label6.Location = new System.Drawing.Point(124, 95); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(11, 12); this.label6.TabIndex = 14; this.label6.Text = "V"; // // label5 // this.label5.AutoSize = true; this.label5.Location = new System.Drawing.Point(124, 79); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(11, 12); this.label5.TabIndex = 13; this.label5.Text = "S"; // // label4 // this.label4.AutoSize = true; this.label4.Location = new System.Drawing.Point(124, 63); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(11, 12); this.label4.TabIndex = 12; this.label4.Text = "H"; // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(124, 41); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(11, 12); this.label3.TabIndex = 11; this.label3.Text = "B"; // // label2 // this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(124, 25); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(11, 12); this.label2.TabIndex = 10; this.label2.Text = "G"; // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(124, 9); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(35, 12); this.label1.TabIndex = 9; this.label1.Text = "R=255"; // // panel1 // this.panel1.Count = 1; this.panel1.CustomGradient = new System.Drawing.Color[] { System.Drawing.Color.White, System.Drawing.Color.Yellow, System.Drawing.Color.Red, System.Drawing.Color.Green, System.Drawing.Color.Blue, System.Drawing.Color.Black}; this.panel1.DrawFarNub = true; this.panel1.DrawNearNub = true; this.panel1.Location = new System.Drawing.Point(3, 8); this.panel1.MaxColor = System.Drawing.Color.White; this.panel1.MinColor = System.Drawing.Color.Black; this.panel1.Name = "panel1"; this.panel1.Orientation = System.Windows.Forms.Orientation.Vertical; this.panel1.Size = new System.Drawing.Size(14, 100); this.panel1.TabIndex = 17; this.panel1.TabStop = false; this.panel1.Value = 153; this.panel1.ValueChanged += new PaintDotNet.IndexEventHandler(this.Panel1_ValueChanged); // // label7 // this.label7.AutoSize = true; this.label7.BackColor = System.Drawing.Color.Transparent; this.label7.Location = new System.Drawing.Point(24, 11); this.label7.Name = "label7"; this.label7.Size = new System.Drawing.Size(17, 12); this.label7.TabIndex = 18; this.label7.Text = "X="; // // label8 // this.label8.AutoSize = true; this.label8.BackColor = System.Drawing.Color.Transparent; this.label8.Location = new System.Drawing.Point(24, 27); this.label8.Name = "label8"; this.label8.Size = new System.Drawing.Size(17, 12); this.label8.TabIndex = 19; this.label8.Text = "Y="; // // numericUpDown1 // this.numericUpDown1.Location = new System.Drawing.Point(4, 114); this.numericUpDown1.Maximum = new decimal(new int[] { 10, 0, 0, 0}); this.numericUpDown1.Minimum = new decimal(new int[] { 1, 0, 0, 0}); this.numericUpDown1.Name = "numericUpDown1"; this.numericUpDown1.Size = new System.Drawing.Size(37, 21); this.numericUpDown1.TabIndex = 20; this.numericUpDown1.Value = new decimal(new int[] { 1, 0, 0, 0}); this.numericUpDown1.ValueChanged += new System.EventHandler(this.numericUpDown1_ValueChanged); // // trackBar1 // this.trackBar1.Location = new System.Drawing.Point(68, 114); this.trackBar1.Minimum = 1; this.trackBar1.Name = "trackBar1"; this.trackBar1.Size = new System.Drawing.Size(91, 45); this.trackBar1.TabIndex = 21; this.trackBar1.TickStyle = System.Windows.Forms.TickStyle.None; this.trackBar1.Value = 1; this.trackBar1.ValueChanged += new System.EventHandler(this.trackBar1_ValueChanged); // // label9 // this.label9.AutoSize = true; this.label9.Location = new System.Drawing.Point(45, 118); this.label9.Name = "label9"; this.label9.Size = new System.Drawing.Size(0, 12); this.label9.TabIndex = 22; // // PixelTrackingDialog // this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.ClientSize = new System.Drawing.Size(164, 141); this.Controls.Add(this.label9); this.Controls.Add(this.trackBar1); this.Controls.Add(this.numericUpDown1); this.Controls.Add(this.label8); this.Controls.Add(this.label7); this.Controls.Add(this.panel1); this.Controls.Add(this.label6); this.Controls.Add(this.label5); this.Controls.Add(this.label4); this.Controls.Add(this.label3); this.Controls.Add(this.label2); this.Controls.Add(this.label1); this.Controls.Add(this.pictureBox1); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; this.Name = "PixelTrackingDialog"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.PixelTrackingDialog_FormClosing); this.Controls.SetChildIndex(this.pictureBox1, 0); this.Controls.SetChildIndex(this.label1, 0); this.Controls.SetChildIndex(this.label2, 0); this.Controls.SetChildIndex(this.label3, 0); this.Controls.SetChildIndex(this.label4, 0); this.Controls.SetChildIndex(this.label5, 0); this.Controls.SetChildIndex(this.label6, 0); this.Controls.SetChildIndex(this.panel1, 0); this.Controls.SetChildIndex(this.label7, 0); this.Controls.SetChildIndex(this.label8, 0); this.Controls.SetChildIndex(this.numericUpDown1, 0); this.Controls.SetChildIndex(this.trackBar1, 0); this.Controls.SetChildIndex(this.label9, 0); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } public bool IsPreview() { bool iss = CameraPreviewDialog.cameraPreviewDialog != null && CameraPreviewDialog.cameraPreviewDialog.IsLeave() && CameraPreviewDialog.cameraPreviewDialog.documentWorkspace.CompositionSurface != null; return iss; } /// /// 设置像素跟踪的数据 /// public unsafe void SetImageAndData(System.Drawing.Point point, DocumentView doc) { mat = doc.CompositionSurface.CreatedAliasedMat(); scale = int.Parse(this.numericUpDown1.Value.ToString()); if (point.X >= 0 && point.Y >= 0 && point.X <= mat.Width && point.Y <= mat.Height) { /*if (point.X < 50 || point.X > mat.Width - 50 || point.Y < 50 || point.Y > mat.Height - 50) { int direction = CalcDirection(point, mat); Mat temp_1 = CalcCropMat(direction, point, mat); bmat = CalcCopyMakeBorder(direction, temp_1); } else*/ { int x = point.X - 50; int y = point.Y - 50; if (x < 0) x = 0; if (y < 0) y = 0; int offsetX = (mat.Width - x) > 100 ? 100 : (mat.Width - x); int offsetY = (mat.Height - y) > 100 ? 100 : (mat.Height - y); if (x == 0) offsetX = 100 - 50 + point.X; if (y == 0) offsetY = 100 - 50 + point.Y; //if (x + offsetX > mat.Width) offsetX = x + offsetX - mat.Width; //if (y + offsetY > mat.Height) offsetY = y + offsetY - mat.Height; if (x + offsetX > mat.Width) offsetX = mat.Width - x; if (y + offsetY > mat.Height) offsetY = mat.Height - y; bmat = new Mat(mat, new Rect(x, y, offsetX, offsetY)); //bmat = new Mat(mat, new Rect(point.X - 50, point.Y - 50, 100, 100)); } //如果不足100*100,补足100*100 if(bmat.Width<100 || bmat.Height<100) { bmat = CalcCopyMakeBorder(CalcDirection1(point, mat), bmat); //Cv2.CopyMakeBorder(bmat, bmat, 100 - bmat.Height, 0, 100 - bmat.Width, 0, BorderTypes.Constant, Scalar.All(255)); } } this.label7.Text = "X=" + point.X.ToString(); this.label8.Text = "Y=" + point.Y.ToString(); if (point.X > 0 && point.Y > 0 && point.X < mat.Width && point.Y < mat.Height) { bgr = mat.At(point.Y, point.X); this.label1.Text = "R=" + bgr[2]; this.label2.Text = "G=" + bgr[1]; this.label3.Text = "B=" + bgr[0]; BaseTools.RgbToHsv(bgr, out h, out s, out v); this.label4.Text = "H=" + (int)(h / 2); this.label5.Text = "S=" + (int)(s * 255); this.label6.Text = "V=" + (int)(v * 255); //设置源图像ROI ImageROI = bmat; //按缩放比例截取小图像 Rect roi1 = new Rect((100 - 100 / scale) / 2, (100 - 100 / scale) / 2, 100 / scale, 100 / scale); ImageROI = new Mat(ImageROI, roi1); //按固定宽高放大图像 Cv2.Resize(ImageROI, ImageROI, new OpenCvSharp.Size(100, 100)); this.pictureBox1.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(ImageROI); } GC.Collect(); this.Refresh(); } /// /// 计算方向 1上 2右上 3右 4右下 5下 6左下 7左 8左上 /// /// private int CalcDirection(System.Drawing.Point point, Mat mat) { int direction = 1; if (point.Y < 100) direction = 1; if (point.X > mat.Width - 100) direction = 3; if (point.Y > mat.Height - 100) direction = 5; if (point.X < 100) direction = 7; if (point.Y < 100 && point.X > mat.Width - 100) direction = 2; if (point.X > mat.Width - 100 && point.Y > mat.Height - 100) direction = 4; if (point.X < 100 && point.Y > mat.Height - 100) direction = 6; if (point.Y < 100 && point.X < 100) direction = 8; return direction; } private int CalcDirection1(System.Drawing.Point point, Mat mat) { int direction = 1; if (point.Y < 50) direction = 1; if (point.X > mat.Width - 50) direction = 3; if (point.Y > mat.Height - 50) direction = 5; if (point.X < 50) direction = 7; if (point.Y < 50 && point.X > mat.Width - 50) direction = 2; if (point.X > mat.Width - 50 && point.Y > mat.Height - 50) direction = 4; if (point.X < 50 && point.Y > mat.Height - 50) direction = 6; if (point.Y < 50 && point.X < 50) direction = 8; return direction; } /// /// 截取部分mat /// 1上 2右上 3右 4右下 5下 6左下 7左 8左上 /// /// /// /// private Mat CalcCropMat(int direction, System.Drawing.Point point, Mat mat) { Mat temp = new Mat(mat, new Rect(point.X - 50, point.Y, 100, point.Y < 50 ? 50 : point.Y)); /*Mat temp = null; int x, y, x_off, y_off; switch (direction) { case 1: //上 temp = new Mat(mat, new Rect(point.X - 50, point.Y, 100, point.Y < 50 ? 50 : point.Y)); break; case 2: //右上 x = point.X - 50; y = point.Y; x_off = (mat.Width - x) > 100 ? 100 : (mat.Width - x); y_off = 50; temp = new Mat(mat, new Rect(x, y, x_off, y_off)); break; case 3: //右 temp = new Mat(mat, new Rect(point.X - 50, point.Y - 50, point.X > mat.Width - 50 ? 50 : mat.Width - point.X, 100)); break; case 4: //右下 x = point.X - 50; y = point.Y - 50; if (y < 0) y = point.Y; x_off = (mat.Width - x) > 100 ? 100 : (mat.Width - x); y_off = (mat.Height - y) > 100 ? 100 : (mat.Height - y); temp = new Mat(mat, new Rect(x, y, x_off, y_off)); break; case 5: //下 y = point.Y - 50; if (y < 0) y = point.Y; temp = new Mat(mat, new Rect(point.X - 50, y, 100, (mat.Height - y) > 100 ? 100 : (mat.Height - y))); break; case 6: //左下 x = point.X; y = (point.Y - 50) < 0 ? point.Y : (point.Y - 50); x_off = (mat.Width - x) > 50 ? 50 : (mat.Width - x); y_off = (mat.Height - y) > 100 ? 100 : (mat.Height - y); temp = new Mat(mat, new Rect(x, y, x_off, y_off)); break; case 7: //左 x = point.X; y = (point.Y - 50) < 0 ? point.Y : (point.Y - 50); temp = new Mat(mat, new Rect(x, y, (mat.Width - x) > 50 ? 50 : (mat.Width - x), (mat.Height - y) > 100 ? 100 : (mat.Height - y))); break; case 8: //左上 temp = new Mat(mat, new Rect(point.X, point.Y, (mat.Width - point.X) > 50 ? 50 : (mat.Width - point.X), (mat.Height - point.Y) > 50 ? 50 : (mat.Height - point.Y))); break; }*/ return temp; } /// /// 扩展边界 /// 1上 2右上 3右 4右下 5下 6左下 7左 8左上 /// /// /// /// private Mat CalcCopyMakeBorder(int direction, Mat temp_1) { switch (direction) { case 1: Cv2.CopyMakeBorder(temp_1, temp_1, 100 - temp_1.Height, 0, 0, 0, BorderTypes.Constant, Scalar.All(255)); break; case 2: Cv2.CopyMakeBorder(temp_1, temp_1, 100 - temp_1.Height, 0, 0, 100 - temp_1.Width, BorderTypes.Constant, Scalar.All(255)); break; case 3: Cv2.CopyMakeBorder(temp_1, temp_1, 0, 0, 0, 100 - temp_1.Width, BorderTypes.Constant, Scalar.All(255)); break; case 4: Cv2.CopyMakeBorder(temp_1, temp_1, 0, 100 - temp_1.Height, 0, 100 - temp_1.Width, BorderTypes.Constant, Scalar.All(255)); break; case 5: Cv2.CopyMakeBorder(temp_1, temp_1, 0, 100 - temp_1.Height, 0, 0, BorderTypes.Constant, Scalar.All(255)); break; case 6: Cv2.CopyMakeBorder(temp_1, temp_1, 0, 100 - temp_1.Height, 100 - temp_1.Width, 0, BorderTypes.Constant, Scalar.All(255)); break; case 7: Cv2.CopyMakeBorder(temp_1, temp_1, 0, 0, 100 - temp_1.Width, 0, BorderTypes.Constant, Scalar.All(255)); break; case 8: Cv2.CopyMakeBorder(temp_1, temp_1, 100 - temp_1.Height, 0, 100 - temp_1.Width, 0, BorderTypes.Constant, Scalar.All(255)); break; } return temp_1; } } }