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.

249 lines
10 KiB
C#

using ChoiceTech.Halcon.Control;
using HalconDotNet;
using Rs.Controls;
using Rs.Framework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Rs.MotionPlat.Commom
{
public class MatchResult
{
public MatchResult(HTuple modelParm) {
ModelParam=modelParm;
if(ModelParam != null )
{
ModelRow = ModelParam[0];
ModelCol = ModelParam[1];
ModelAngle = ModelParam[2];
ModelScore = ModelParam[3];
}
}
public MatchResult() { }
public HObject Himage { get; set; }
public HTuple ModelParam { get; set; }
public double ModelRow { get; set; } = 0.0;
public double ModelCol { get; set; } = 0.0;
public double ModelAngle { get; set; } = 0.0;
public double ModelScore { get; set; } = 0.0;
public HObject ContourXld { get; set; }
public double Row { get; set; } = 0.0;
public double Col { get; set; } = 0.0;
public double Angle { get; set; } = 0.0;
public double Score { get; set; } = 0.0;
public string SN { get; set; }
public bool IsOK { get; set; } = false;
public bool LocationOk { get; set; } = false;
public bool ScanOK { get; set; } = false;
private double _OffsetRow;
public double OffsetRow
{
get {
if (LocationOk)
return -1 * (Row - ModelRow) * GlobalVar.DownCameraMmPerPixel;
else
return 0;
}
}
private double _OffsetCol;
public double OffsetCol
{
get {
if (LocationOk)
return -1*(Col - ModelCol) * GlobalVar.DownCameraMmPerPixel;
else return 0;
}
}
public double OffsetA
{
get {
if (LocationOk)
return (-1 * AngleTool.Rad2Deg(Angle - ModelAngle));
else return 0;
}
}
}
/// <summary>
/// 视觉处理类
/// </summary>
public class VisionProcess
{
private HTuple downCamModelID;
private HObject downCamSearchRegion;
private string AngleStart;
private string AngleExtent;
private string Score;
private HTuple modelParam;
private VisionProcess() {
//先加载模板
IniHelper ini = new IniHelper(Path.Combine("Recipe",GlobalVar.CurRecipe,"下定位相机", "default.ini"));
AngleStart = ini.ReadValue("ModelParam", "AngleStart", "-10");
AngleExtent = ini.ReadValue("ModelParam", "AngleExtent", "10");
Score = ini.ReadValue("ModelParam", "Score", "0.5");
string paramPath = Path.Combine("Recipe", GlobalVar.CurRecipe, "下定位相机", "param.tup");
HOperatorSet.ReadTuple(paramPath, out modelParam);
string filePath = Path.Combine("Recipe", GlobalVar.CurRecipe, "下定位相机", "model.shm");
HOperatorSet.ReadShapeModel(filePath, out downCamModelID);
HOperatorSet.ReadRegion(out downCamSearchRegion, Path.Combine("Recipe", GlobalVar.CurRecipe, "下定位相机" + "\\search.reg"));
}
public void Reload()
{
//先加载模板
IniHelper ini = new IniHelper(Path.Combine("Recipe", GlobalVar.CurRecipe, "下定位相机", "default.ini"));
AngleStart = ini.ReadValue("ModelParam", "AngleStart", "-10");
AngleExtent = ini.ReadValue("ModelParam", "AngleExtent", "10");
Score = ini.ReadValue("ModelParam", "Score", "0.5");
string paramPath = Path.Combine("Recipe", GlobalVar.CurRecipe, "下定位相机", "param.tup");
HOperatorSet.ReadTuple(paramPath, out modelParam);
string filePath = Path.Combine("Recipe", GlobalVar.CurRecipe, "下定位相机", "model.shm");
HOperatorSet.ReadShapeModel(filePath, out downCamModelID);
HOperatorSet.ReadRegion(out downCamSearchRegion, Path.Combine("Recipe", GlobalVar.CurRecipe, "下定位相机" + "\\search.reg"));
}
private static VisionProcess _instance;
public static VisionProcess Instance
{
get
{
if(_instance == null)
_instance = new VisionProcess();
return _instance;
}
}
static int grabNum = 0;
public List<MatchResult> MatchDownCam(HObject[] images,bool needRotate=true)
{
string paramPath = Path.Combine("Recipe", GlobalVar.CurRecipe, "下定位相机", "param.tup");
HOperatorSet.ReadTuple(paramPath, out modelParam);
HObject hImage = new HObject();
List<MatchResult > matches = new List<MatchResult>();
foreach (var image in images)
{
hImage = image;
HObject hratImage = new HObject();
if(image==null)
continue;
if(needRotate)
{
HOperatorSet.RotateImage(image, out hImage, SysConfigParam.GetValue<double>("DownLocationCameraRotate"), "constant");
}
if (downCamSearchRegion.IsInitialized())
{
MatchResult mr = new MatchResult(modelParam);
HOperatorSet.ReduceDomain(hImage, downCamSearchRegion, out HObject searchImg);
HOperatorSet.GetShapeModelContours(out HObject modelContours, downCamModelID, 1);
HOperatorSet.FindShapeModel(searchImg, downCamModelID, AngleTool.Deg2Rad(double.Parse(AngleStart)), AngleTool.Deg2Rad(Math.Abs((double.Parse(AngleExtent) - double.Parse(AngleStart)))), new HTuple(0.5), 1, 0.5, "least_squares", 0, 0.9, out HTuple row, out HTuple column, out HTuple angle, out HTuple score);
if (score != null && score.Length > 0)
{
HOperatorSet.VectorAngleToRigid(0, 0, 0, row[0].D, column[0].D, angle[0].D, out HTuple homMat2D);
HOperatorSet.AffineTransContourXld(modelContours, out HObject contoursAffineTrans, homMat2D);
mr.ContourXld= contoursAffineTrans;
mr.Row = row.DArr[0];
mr.Col = column.DArr[0];
mr.Angle = angle.DArr[0];
mr.Score = score.DArr[0];
mr.Himage = hImage;
mr.LocationOk = true;
FindCode(hImage, ref mr);
string dirname = $"d://images/{DateTime.Now.ToString("yyyyMMdd")}";
if(!Directory.Exists(dirname))
{
Directory.CreateDirectory(dirname);
}
if(mr.ScanOK)
{
mr.IsOK= true;
HOperatorSet.WriteImage(hImage, "bmp", 0, $"{dirname}//{mr.SN.Replace("\\", "").Replace("\"", "")+"_"+ DateTime.Now.ToString("yyyyMMddHHmmssfff")}");
}
else
{
HOperatorSet.WriteImage(hImage, "bmp", 0, $"{dirname}//{DateTime.Now.ToString("yyyyMMddHHmmssfff")}");
}
matches.Add(mr);
}
else
{
mr.ScanOK = false;
mr.LocationOk = false;
mr.IsOK = false;
mr.Row = 0;
mr.Col = 0;
mr.Angle = 0;
mr.Score = 0;
mr.Himage = hImage;
matches.Add(mr);
}
}
}
return matches;
}
public void FindCode(HObject images,ref MatchResult mr)
{
try
{
// HOperatorSet.GenRectangle1(out HObject searchRegion, new HTuple(1533), new HTuple(731), new HTuple(1751), new HTuple(1071));
HOperatorSet.GenRectangle1(out HObject searchRegion, new HTuple(SysConfigParam.GetValue<int>("CodeRow1")), new HTuple(SysConfigParam.GetValue<int>("CodeColumn1")), new HTuple(SysConfigParam.GetValue<int>("CodeRow2")), new HTuple(SysConfigParam.GetValue<int>("CodeColumn2")));
HOperatorSet.ReduceDomain(images, searchRegion, out HObject imgReduaced);
HTuple decodedDataStrings = "";
HObject xlds = new HObject();
string[] modes = new string[] { "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)
{
mr.SN = decodedDataStrings.ToString().Replace("\"","");
mr.ScanOK = true;
HOperatorSet.ClearDataCode2dModel(dataCodeHandle);
return;
}
else
{
if (mode == "maximum_recognition")
{
mr.ScanOK = false;
HOperatorSet.ClearDataCode2dModel(dataCodeHandle);
}
}
}
}
catch (Exception ex)
{
}
}
}
}