using Bro.Common.Base; using Bro.Common.Helper; using Bro.Common.Model; using Bro.Common.UI; using HalconDotNet; using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace Bro.Common.Calibration { public partial class CalibrationStatic9PointFrm : Form { /// /// 标定点位信息 /// public List CPoints { get { return canvas1.Elements.Where(p => p.IsEnabled && (p is CrossHair)).Select(p => ((CrossHair)p).CenterPoint).ToList(); } } /// /// 运动点位信息 /// public CustomizedPoint MovingPosition { get; set; } = new CustomizedPoint(); Canvas canvas1 = new Canvas(); PLCBase PLC = null; CameraBase Camera = null; Bitmap Image = null; CalibrationStatic9PointConfig Config = null; HDevEngineTool tool = null; public CalibrationStatic9PointFrm() { InitializeComponent(); canvas1 = new Canvas(); canvas1.Dock = DockStyle.Fill; plCanvas.Controls.Add(canvas1); } public CalibrationStatic9PointFrm(string display, CameraBase camera, PLCBase plc, Bitmap image, CalibrationStatic9PointConfig config) { InitializeComponent(); if (!string.IsNullOrWhiteSpace(display)) { this.Text = display; } Camera = camera; PLC = plc; Image = image; propCalibrationConfig.SelectedObject = Config = config; Camera.OnImageUpdated -= Camera_UpdateShowImage; Camera.OnImageUpdated += Camera_UpdateShowImage; canvas1.LoadImage(Image); LoadHalconTool(); } AutoResetEvent _imgShowedHandle = new AutoResetEvent(true); private void Camera_UpdateShowImage(CameraBase camera, Bitmap image) { if (this.InvokeRequired) { this.Invoke(new Action(() => LoadImage(image))); } else { LoadImage(image); } } private void LoadImage(Bitmap image) { canvas1.LoadImage(image); _imgShowedHandle.Set(); } private void PointTest() { canvas1.Elements.Clear(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { PointF p = new PointF(); p.X = 300 + i * 100; p.Y = 500 + j * 150; CrossHair ch = new CrossHair(new CalibrationPoint(p)); ch.Index = i * 3 + j + 1; ch.Name = p.X.ToString() + "--" + p.Y.ToString(); canvas1.Elements.Add(ch); } } } private void LoadHalconTool() { if (string.IsNullOrWhiteSpace(Config.CameraOpConfig.AlgorithemPath)) { return; } txtAlgorithemPath.Text = Config.CameraOpConfig.AlgorithemPath; string directoryPath = Path.GetDirectoryName(Config.CameraOpConfig.AlgorithemPath); string fileName = Path.GetFileNameWithoutExtension(Config.CameraOpConfig.AlgorithemPath); tool = new HDevEngineTool(directoryPath); tool.LoadProcedure(fileName); Thread.Sleep(1000); } private void btnCancel_Click(object sender, EventArgs e) { this.DialogResult = DialogResult.Cancel; } private void btnDone_Click(object sender, EventArgs e) { if (CPoints.Count < 9) { if (MessageBox.Show("一般需设置至少9个标定点的信息,是否确认完成", "完成确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK) return; } if (CPoints.Count(p => p.X == 0 && p.Y == 0) > 1) { if (MessageBox.Show("标定点的XY信息未设置完成,是否确认完成", "完成确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK) return; } GetCurrentPosition(); if (Config.IsEnableROIFilter) { Config.ROIList.Clear(); CPoints.ForEach(u => { ROI_Circle circle = new ROI_Circle(); if (u.IsBasePoint) { circle.ROI_Index = "1"; } circle.Center = new CustomizedPoint(u.U, u.V); circle.Radius = Config.ROI_Radius; Config.ROIList.Add(circle); }); } this.DialogResult = DialogResult.OK; } public virtual void GetCurrentPosition() { //if (Config.PLCSetting.IsRealTimeDataFromPLC) //{ // int x = PLC.Read(Config.PLCSetting.XAddress, 2).ParseUnsignShortListToInt()[0]; // int y = PLC.Read(Config.PLCSetting.YAddress, 2).ParseUnsignShortListToInt()[0]; // MovingPosition = new CustomizedPoint(x, y); // Config.PLCSetting.LocationX = x; // Config.PLCSetting.LocationY = y; //} //else //{ // MovingPosition = new CustomizedPoint(Config.PLCSetting.LocationX, Config.PLCSetting.LocationY); //} } private void btnCalibrate_Click(object sender, EventArgs e) { DoCalibration(); } private void DoCalibration() { canvas1.Elements.Clear(); if (Config.IsEnableROIFilter) { Config.ROIList.ForEach(r => { canvas1.Elements.Add(r); }); } try { HTuple outputX = new HTuple(); HTuple outputY = new HTuple(); using (HObject hImage = canvas1.MAP.ConvertBitmapToHObject()) { tool.InputImageDic.Clear(); tool.InputImageDic["INPUT_Image"] = hImage; tool.RunProcedure(); if (!tool.IsSuccessful) throw new ProcessException($"{Config.CameraOpConfig.AlgorithemPath}算法运行失败"); outputX = tool.GetResultTuple("OUTPUT_X"); outputY = tool.GetResultTuple("OUTPUT_Y"); } List chList = new List(); for (int i = 0; i < outputX.DArr.Length; i++) { CalibrationPoint point = new CalibrationPoint(new PointF((float)outputX.DArr[i], (float)outputY.DArr[i])); if (Config.IsEnableROIFilter && Config.ROIList.Count > 0) { var roi = Config.ROIList.FirstOrDefault(r => r.IsMouseInSide(new Point((int)point.U, (int)point.V))); if (roi != null) { CrossHair ch = new CrossHair(point); ch.IsShowRemark = Config.IsShowRemark; ch.Index = i + 1; ch.Name = point.U.ToString("f3") + "--" + point.V.ToString("f3"); if (roi.ROI_Index == "1") { ch.CenterPoint.IsBasePoint = true; } chList.Add(ch); } } else { CrossHair ch = new CrossHair(point); ch.IsShowRemark = Config.IsShowRemark; ch.Index = i + 1; ch.Name = point.U.ToString("f3") + "--" + point.V.ToString("f3"); chList.Add(ch); } } Config.ROIList.ForEach(r => { canvas1.Elements.Add(r); }); } catch (Exception ex) { MessageBox.Show(ex.GetExceptionMessage()); } } private void btnQuickSetXY_Click(object sender, EventArgs e) { if (MessageBox.Show("快捷设置XY坐标仅适用于标定坐标系和相机坐标系基本平行情况下", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk) != DialogResult.OK) { return; } if (CPoints.Count(p => p.IsBasePoint) > 1) { MessageBox.Show("基准点只能选择一个"); return; } var basePoint = CPoints.FirstOrDefault(p => p.IsBasePoint); if (basePoint == null) { MessageBox.Show("请选择一个基准点"); return; } List uList = CPoints.Select(p => Math.Abs(p.U - basePoint.U)).OrderBy(u => u).ToList(); List vList = CPoints.Select(p => Math.Abs(p.V - basePoint.V)).OrderBy(u => u).ToList(); float intervalU = uList.FirstOrDefault(u => u > Config.IgnorePixel); float intervalV = vList.FirstOrDefault(u => u > Config.IgnorePixel); CPoints.ForEach(p => { if (!p.IsBasePoint) { if (Config.IsInvert) { p.X = (int)(Math.Round((p.V - basePoint.V) / intervalV)) * Config.IntervalX + basePoint.X; p.Y = (int)(Math.Round((p.U - basePoint.U) / intervalU)) * Config.IntervalY + basePoint.Y; } else { p.X = (int)(Math.Round((p.U - basePoint.U) / intervalU)) * Config.IntervalX + basePoint.X; p.Y = (int)(Math.Round((p.V - basePoint.V) / intervalV)) * Config.IntervalY + basePoint.Y; } } else { if (Config.IsEnableROIFilter) { var roi1st = Config.ROIList.FirstOrDefault(u => u.IsMouseInSide(new Point((int)p.U, (int)p.V))); if (roi1st != null) { roi1st.ROI_Index = "1"; } } } }); MessageBox.Show("快捷配置完成!"); } private void btnReSnap_Click(object sender, EventArgs e) { Camera.Snapshot(Config.CameraOpConfig, out HObject hImage); hImage.Dispose(); } private void chkContinueMode_CheckedChanged(object sender, EventArgs e) { if (chkContinueMode.Checked) { Task.Run(() => { while (chkContinueMode.Checked) { Camera.Snapshot(Config.CameraOpConfig, out HObject hImage); hImage.Dispose(); _imgShowedHandle.WaitOne(3000); } }); } } private void btnTest_Click(object sender, EventArgs e) { PointTest(); } private void btnReadLocation_Click(object sender, EventArgs e) { //int x = PLC.Read(Config.PLCSetting.XAddress, 2).ParseUnsignShortListToInt()[0]; //int y = PLC.Read(Config.PLCSetting.YAddress, 2).ParseUnsignShortListToInt()[0]; //string msg = string.Format("X:{0};Y:{1}", x, y); //if (MessageBox.Show(msg + "\r\n是否保存到配置?", "坐标获取", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) //{ // Config.PLCSetting.LocationX = x; // Config.PLCSetting.LocationY = y; //} GetCurrentPosition(); } private void btnReloadAlgorithem_Click(object sender, EventArgs e) { LoadHalconTool(); MessageBox.Show("算法重新载入完成"); } private void btnClearROI_Click(object sender, EventArgs e) { Config.ROIList.Clear(); DoCalibration(); } private void CalibrationProcessFrm_FormClosing(object sender, FormClosingEventArgs e) { chkContinueMode.Checked = false; } } }