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#
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)
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|