在定位项目中,经常会在生产的时候出现模板匹配找不到或者匹配错误的情况,在匹配不正确的时候需要快速人工确认方向,所以就需要一个人工选点的功能——NG选点
使用方式,将NG选点窗口复制到项目中,并链接好完成NG选点按钮控件,和picbox控件。通过使用提前将NG原图保存下来,并将路径传入方法中,在从NG选点窗口中创建的CSV进行获取到数据即可。获取数据经过处理,可以直接输出图像上的坐标而不是控件坐标。
//选点窗口
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace NGPOINT
{
public partial class Form2 : Form
{
private float x;//定义当前窗体的宽度
private float y;//定义当前窗体的高度
bool bFirstSetup = true;//开启工作
double TX, TY;//获取拉伸比例
Point start; //起始点
Point end; //结束点
bool blnDraw; //在MouseMove事件中判断是否绘制矩形框
public Form2()
{
InitializeComponent();
x = this.Width;
y = this.Height;
setUniformScale(this);
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
start = e.Location;
blnDraw = true;
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (blnDraw)
{
if (e.Button != MouseButtons.Left) return;
end = e.Location;
pictureBox1.Invalidate();//此代码不可省略
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
end = e.Location;
blnDraw = false;
}
}
double xe, ye,resultX,resultY;
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
using (var g = pictureBox1.CreateGraphics())
{
var p = e.Location;
int r = 15;//圆的半径
g.DrawEllipse(Pens.Red, p.X - r, p.Y - r, 2 * r, 2 * r);
g.Flush();
}
xe = e.Location.X;
ye = e.Location.Y;
resultX= xe*TX;
resultY= ye*TY;
Console.WriteLine(xe * TX + ",,," + ye * TY);
Console.WriteLine(TX + ",,," + TY);
//保存的CSV路径
string str = ("D:\\UpperComputer\\");
using (FileStream fsWrite = new FileStream(str+ "CSV.csv", FileMode.OpenOrCreate, FileAccess.Write))
{
List<double> list = new List<double>();
list.Add(resultX);
list.Add(resultY);
//写入题头
string title=null;
foreach (var item in list)
{
title = title + item + ",";
}
byte[] buffer = Encoding.UTF8.GetBytes(title);
fsWrite.Write(buffer, 0, buffer.Length);//会将初始位置开始的字节进行覆盖
fsWrite.Close();
}
}
//完成NG选点按钮事件
private void Finish_NG_Click(object sender, EventArgs e)
{
Form1 form1 = new Form1();
this.Close();
form1.ShowDialog();
}
public void beginNG(string str)
{
pictureBox1.Image = Image.FromFile(str);
TX = Math.Round((Convert.ToDouble(pictureBox1.Image.Width) / Convert.ToDouble(pictureBox1.Width)), 4);
TY = Math.Round((Convert.ToDouble(pictureBox1.Image.Height) / Convert.ToDouble(pictureBox1.Height)), 4);
//图片拉伸 适应控件尺寸
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
}
#region // 控件大小随窗体大小等比例缩放
// 控件大小随窗体大小等比例缩放
private void setUniformScale(Control cons)
{
foreach (Control con in cons.Controls)
{
con.Tag = con.Width + ";" + con.Height + ";" + con.Left + ";" + con.Top + ";" + con.Font.Size;
if (con.Controls.Count > 0)
{
setUniformScale(con);
}
}
}
private void setControls(float newx, float newy, Control cons)
{
//遍历窗体中的控件,重新设置控件的值
foreach (Control con in cons.Controls)
{
//获取控件的Tag属性值,并分割后存储字符串数组
if (con.Tag != null)
{
string[] mytag = con.Tag.ToString().Split(new char[] {
';' });
//根据窗体缩放的比例确定控件的值
con.Width = Convert.ToInt32(System.Convert.ToSingle(mytag[0]) * newx);//宽度
con.Height = Convert.ToInt32(System.Convert.ToSingle(mytag[1]) * newy);//高度
con.Left = Convert.ToInt32(System.Convert.ToSingle(mytag[2]) * newx);//左边距
con.Top = Convert.ToInt32(System.Convert.ToSingle(mytag[3]) * newy);//顶边距
Single currentSize = System.Convert.ToSingle(mytag[4]) * newy;//字体大小
con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
if (con.Controls.Count > 0)
{
setControls(newx, newy, con);
}
}
//调节参数比例
if (pictureBox1.Image != null)
{
TX = Math.Round((Convert.ToDouble(pictureBox1.Image.Width) / Convert.ToDouble(pictureBox1.Width)), 4);
TY = Math.Round((Convert.ToDouble(pictureBox1.Image.Height) / Convert.ToDouble(pictureBox1.Height)), 4);
}
}
}
private void MainForm_Resize(object sender, EventArgs e)
{
float newx = (this.Width) / x;
float newy = (this.Height) / y;
setControls(newx, newy, this);
if (bFirstSetup)
return;
}
#endregion
}
}
主窗口
namespace NGPOINT
{
public partial class Form1 : Form
{
//定义NG选点变量,并创建对象
Form2 ng_point = new Form2();
double NGX=0, NGY=0;
public Form1()
{
InitializeComponent();
}
//获取NG选点数据
private void button2_Click(object sender, EventArgs e)
{
string CSVDate = null;
string str = ("D:\\UpperComputer\\CSV.csv");
using (StreamReader sr = new StreamReader(str, Encoding.UTF8))
{
while (!sr.EndOfStream)//判断是否读到文件最后,返回bool
{
CSVDate = sr.ReadLine();
}
}
string NGx = null; string NGy = null;
int num = 0;
foreach (var item in CSVDate)
{
if (item == ',')
{
for (int i = num+1; i < CSVDate.Length - 1; i++)
{
if (CSVDate[i] == ',') break;
NGy = NGy + CSVDate[i];
}
break;
}
NGx =NGx+ item;
num++;
}
//XY的输出结果
NGX = System.Convert.ToDouble(NGx);
NGY = System.Convert.ToDouble(NGy);
}
//开启NG选点
public void button1_Click(object sender, EventArgs e)
{
//传入参数,有NG选点的图像
string str = ("D:\\UpperComputer\\NG.bmp");
//父窗口隐藏
this.Hide();
//NG选点窗口显示
ng_point.Show();
//开启NG选点,并传入图像路径
ng_point.beginNG(str);
}
}
}