using HalconDotNet; using Rs.Camera; using Rs.Controls; using Rs.Framework; using Rs.Motion; using Rs.MotionPlat.Commom; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace Rs.MotionPlat.Flow.Camera { public class SlotProductHasOrNotResult { public bool HasProduct { get; set; } = false; public HObject SearchRegion { get; set; } public HObject SourceImage { get; set; } } /// /// 视觉管理类 /// public static class VisionManager { private static ModelParameter stockTrayHasProductModel; private static ModelParameter upCameraScanBarCodeModel; static VisionManager() { //加载模板和参数 //加载 //stockTrayHasProductModel = new ModelParameter("料仓料盘产品有无"); //upCameraScanBarCodeModel = new ModelParameter("周转盘产品定位"); } /// /// StockTray盘是否有料 /// 0 无料 1 有料 负数 错误返回错误码 /// public static SlotProductHasOrNotResult StockTrayHasProduct() { SlotProductHasOrNotResult result = new SlotProductHasOrNotResult(); string cameraName = "upCamera"; //1、拍照 string m_savePath = Path.Combine("Recipe", GlobalVar.CurRecipe, "料仓料盘产品有无"); HOperatorSet.ReadRegion(out HObject searchRegion, Path.Combine(m_savePath , "搜索区域.reg")); if(searchRegion.IsInitialized()) { result.SearchRegion = searchRegion; ImageProcess.ClearManualTrigger(); HikCamera.Instance.SetTrigger(cameraName, ETriggerMode.Manual); HikCamera.Instance.SetExposure(cameraName, GlobalVar.UpCameraExposureTime); HikCamera.Instance.SetGain(cameraName, GlobalVar.UpCameraGain); AxisControl.LoadX.ComparePulse(2, false); //2、等待相机返回结果 bool cameraOk = ImageProcess.manualTriggerEvent.WaitOne(3000); if (cameraOk) { HObject hImage = new HObject(); HObject image = ImageProcess.GetManualImage(); if (cameraName == SysConfigParam.GetValue("UpCameraName")) { HOperatorSet.RotateImage(image, out hImage, SysConfigParam.GetValue("UpCameraRotate"), "constant"); } result.SourceImage = hImage; HOperatorSet.ReduceDomain(hImage, searchRegion, out HObject searchImg); HOperatorSet.Threshold(searchImg, out HObject whiteRegion, new HTuple(GlobalVar.StockTrayHaveOrNotGrayMin), new HTuple(GlobalVar.StockTrayHaveOrNotGrayMax)); HOperatorSet.AreaCenter(whiteRegion, out HTuple area, out HTuple row, out HTuple column); if (area.D > GlobalVar.StockTrayHaveOrNotGrayArea) { result.HasProduct = true; } else { result.HasProduct = false; } } } //3、返回结果 return result; } /// /// 周转盘是否有料 /// 0 无料 1 有料 负数 错误返回错误码 /// /// public static SlotProductHasOrNotResult TurnoverTrayHasProduct(Action checkFinishedEvent) { SlotProductHasOrNotResult result = new SlotProductHasOrNotResult(); string cameraName = "upCamera"; //1、拍照 ImageProcess.ClearManualTrigger(); string m_savePath = Path.Combine("Recipe", GlobalVar.CurRecipe, "周转盘产品有无"); HOperatorSet.ReadRegion(out HObject searchRegion, Path.Combine(m_savePath, "搜索区域.reg")); result.SearchRegion = searchRegion; ImageProcess.ClearManualTrigger(); HikCamera.Instance.SetTrigger(cameraName, ETriggerMode.Manual); HikCamera.Instance.SetExposure(cameraName, GlobalVar.UpCameraExposureTime); HikCamera.Instance.SetGain(cameraName, GlobalVar.UpCameraGain); AxisControl.LoadX.ComparePulse(2, false); //2、等待相机返回结果 bool cameraOk = ImageProcess.manualTriggerEvent.WaitOne(3000); if (cameraOk) { HObject hImage = new HObject(); HObject image = ImageProcess.GetManualImage(); if (cameraName == SysConfigParam.GetValue("UpCameraName")) { HOperatorSet.RotateImage(image, out hImage, SysConfigParam.GetValue("UpCameraRotate"), "constant"); } checkFinishedEvent?.Invoke(hImage); result.SourceImage = hImage; if (searchRegion.IsInitialized()) { HOperatorSet.ReduceDomain(hImage, searchRegion, out HObject searchImg); HOperatorSet.Threshold(searchImg, out HObject whiteRegion, new HTuple(GlobalVar.TurnoverTrayHaveOrNotGrayMin), new HTuple(GlobalVar.TurnoverTrayHaveOrNotGrayMax)); HOperatorSet.AreaCenter(whiteRegion, out HTuple area, out HTuple row1, out HTuple column1); if(area.D>GlobalVar.TurnoverTrayHaveOrNotGrayArea) { result.HasProduct = true; } else { result.HasProduct = false; } } } //3、返回结果 return result; } /// /// 检测周转盘放料是否OK /// /// public static VisionResult TurnoverTrayDumpProductOK(HObject image,bool bNeedLocation=true,bool bNeedScanBarcode=true,int slotIndex=0) { upCameraScanBarCodeModel = new ModelParameter("周转盘产品定位"); VisionResult vr = new VisionResult(); vr.SourceImage = image; HObject searchImg = new HObject(); if (upCameraScanBarCodeModel.SearchRegion.IsInitialized()) HOperatorSet.ReduceDomain(image, upCameraScanBarCodeModel.SearchRegion, out searchImg); else searchImg = image; if(bNeedLocation) { HOperatorSet.GetShapeModelContours(out HObject modelContours, upCameraScanBarCodeModel.ModelID, 1); HOperatorSet.FindShapeModel(searchImg, upCameraScanBarCodeModel.ModelID, AngleTool.Deg2Rad(double.Parse(upCameraScanBarCodeModel.AngleStart)), AngleTool.Deg2Rad(Math.Abs((double.Parse(upCameraScanBarCodeModel.AngleExtent) - double.Parse(upCameraScanBarCodeModel.AngleStart)))), new HTuple(double.Parse(upCameraScanBarCodeModel.Score)), 1, 0.5, "least_squares", 0, 0.9, out HTuple row, out HTuple column, out HTuple angle, out HTuple score); if (score.Length > 0) { vr.OffsetX = (column.D - upCameraScanBarCodeModel.ModelMatchResult[1].D) * GlobalVar.UpCameraMmPerPixel; vr.OffsetY = -1 * (row.D - upCameraScanBarCodeModel.ModelMatchResult[0].D) * GlobalVar.UpCameraMmPerPixel; vr.OffsetR = AngleTool.Rad2Deg((angle.D - upCameraScanBarCodeModel.ModelMatchResult[2].D)); vr.SourceImage = image; vr.SearchModelOK = true; //if (Math.Abs(vr.OffsetX) < GlobalVar.TurnoverTrayLocateXRange // && Math.Abs(vr.OffsetY) < GlobalVar.TurnoverTrayLocateYRange // && Math.Abs(vr.OffsetR) < GlobalVar.TurnoverTrayLocateRRange) //{ // vr.SearchModelOK = true; //} } else { vr.SearchModelOK = false; } } else { vr.SearchModelOK = true; } if(bNeedScanBarcode) { //只有定位成功的才去扫二维码 if (vr.SearchModelOK && !GlobalVar.EnableScanBarCodeByDownCamera) { string sn = FindCode(image, upCameraScanBarCodeModel.BarCodeRegion); if (string.IsNullOrEmpty(sn)) { vr.ScanBarCodeOK = false; } else { string dirname = $"d://images/{DateTime.Now.ToString("yyyyMMdd")}/scanbarcode"; if (!Directory.Exists(dirname)) { Directory.CreateDirectory(dirname); } HOperatorSet.WriteImage(image, "bmp", 0, $"{dirname}//{sn}_{DateTime.Now.ToString("yyyyMMddHHmmssfff")}_{slotIndex}"); vr.ScanBarCodeOK = true; vr.SN = sn; } } } return vr; } public static VisionResult TurnoverTrayLocateAndScan(HObject image) { VisionResult vr = TurnoverTrayDumpProductOK(image); if(vr.SearchModelOK) { //扫码 } return vr; } public static string FindCode(HObject images,HObject _barCodeRegion) { try { // HOperatorSet.GenRectangle1(out HObject searchRegion, new HTuple(1533), new HTuple(731), new HTuple(1751), new HTuple(1071)); //HOperatorSet.GenRectangle1(out HObject searchRegion,row1, col1, row2, col2); HOperatorSet.ReduceDomain(images, _barCodeRegion, out HObject imgReduaced); //HOperatorSet.Emphasize(imgReduaced, out HObject imageEmphasize, new HTuple(7), new HTuple(7), new HTuple(1)); //HOperatorSet.CropDomain(imgReduaced, out HObject imagePart); //HOperatorSet.WriteImage(imagePart, "bmp", 0, "d://images/11"); //HOperatorSet.Threshold(imagePart, out HObject region, new HTuple(200), new HTuple(255)); //HOperatorSet.Connection(region, out HObject connectedRegions); //HOperatorSet.FillUp(connectedRegions, out HObject regionFillUp); //HOperatorSet.ShapeTrans(regionFillUp, out HObject regionTrans, "rectangle1"); //HOperatorSet.SelectShape(regionTrans, out HObject selectedRegions, "area", "and", new HTuple(7000), new HTuple(9000)); //HOperatorSet.SelectShape(selectedRegions, out HObject searchRegions, "outer_radius", "and", new HTuple(50), new HTuple(70)); //if (searchRegions.IsInitialized() && searchRegions.CountObj() == 1) { //找到了二维码区域 //HOperatorSet.DilationRectangle1(searchRegions, out HObject regionDilation, new HTuple(40), new HTuple(40)); //HOperatorSet.ReduceDomain(imagePart, regionDilation, out HObject imageReduacedQrcode); //HOperatorSet.InvertImage(imageReduacedQrcode, out HObject imageInvert); //HOperatorSet.ScaleImage(imageInvert, out HObject imageScaled, 2, 0); //HOperatorSet.WriteImage(imageScaled, "bmp", 0, "d://images/22"); //HOperatorSet.ZoomImageFactor(imageScaled, out HObject imageZoomed, new HTuple(10), new HTuple(10), "constant"); HTuple decodedDataStrings = ""; HObject xlds = new HObject(); string[] modes = new string[] { "enhanced_recognition", "maximum_recognition" }; foreach (string mode in modes) { HOperatorSet.CreateDataCode2dModel("Data Matrix ECC 200", "default_parameters", mode, out HTuple dataCodeHandle); HOperatorSet.FindDataCode2d(imgReduaced, out xlds, dataCodeHandle, new HTuple(), new HTuple(), out HTuple resultHandles, out decodedDataStrings); if (decodedDataStrings.Length > 0) { HOperatorSet.ClearDataCode2dModel(dataCodeHandle); return decodedDataStrings.ToString().Replace("\"", ""); } else { HOperatorSet.ClearDataCode2dModel(dataCodeHandle); //增强对比度之后再识别一次 HOperatorSet.MultImage(imgReduaced, imgReduaced, out HObject imageMulti, new HTuple(0.005), new HTuple(0)); HOperatorSet.CreateDataCode2dModel("Data Matrix ECC 200", "default_parameters", mode, out dataCodeHandle); HOperatorSet.FindDataCode2d(imageMulti, out xlds, dataCodeHandle, new HTuple(), new HTuple(), out resultHandles, out decodedDataStrings); if (decodedDataStrings.Length > 0) { HOperatorSet.ClearDataCode2dModel(dataCodeHandle); return decodedDataStrings.ToString().Replace("\"", ""); } else { HOperatorSet.ClearDataCode2dModel(dataCodeHandle); } if (mode == "maximum_recognition") { string saveDir = $"d://images//{DateTime.Now.ToString("yyyyMMdd")}//Ng"; if(!Directory.Exists(saveDir)) { Directory.CreateDirectory(saveDir); } HOperatorSet.WriteImage(images, "bmp", 0, $"{saveDir}/{DateTime.Now.ToString("yyyy-MM-dd HHmmss ffff")}"); HOperatorSet.ClearDataCode2dModel(dataCodeHandle); } } } return ""; } //else //{ // HOperatorSet.WriteImage(images, "bmp", 0, $"d://images/scanfail/{DateTime.Now.ToString("yyyy-MM-dd HHmmss ffff")}"); // mr.ScanOK = false; //} } catch (Exception ex) { LogHelper.Error(ex.Message, ex); return ""; } } } }