You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

310 lines
15 KiB
C#

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; }
}
/// <summary>
/// 视觉管理类
/// </summary>
public static class VisionManager
{
private static ModelParameter stockTrayHasProductModel;
private static ModelParameter upCameraScanBarCodeModel;
static VisionManager()
{
//加载模板和参数
//加载
//stockTrayHasProductModel = new ModelParameter("料仓料盘产品有无");
//upCameraScanBarCodeModel = new ModelParameter("周转盘产品定位");
}
/// <summary>
/// StockTray盘是否有料
/// 0 无料 1 有料 负数 错误返回错误码
/// </summary>
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<string>("UpCameraName"))
{
HOperatorSet.RotateImage(image, out hImage, SysConfigParam.GetValue<double>("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;
}
/// <summary>
/// 周转盘是否有料
/// 0 无料 1 有料 负数 错误返回错误码
/// </summary>
/// <returns></returns>
public static SlotProductHasOrNotResult TurnoverTrayHasProduct(Action<HObject> 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<string>("UpCameraName"))
{
HOperatorSet.RotateImage(image, out hImage, SysConfigParam.GetValue<double>("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;
}
/// <summary>
/// 检测周转盘放料是否OK
/// </summary>
/// <returns></returns>
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 "";
}
}
}
}