using HalconDotNet;
|
using Microsoft.Extensions.Logging.Abstractions;
|
using LB_VisionProcesses.Alogrithms.Halcon;
|
using Newtonsoft.Json;
|
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Serialization;
|
using OpenCvSharp;
|
using OpenCvSharp.XFeatures2D;
|
using System;
|
using System.Collections.Generic;
|
using System.Data.Common;
|
using System.Diagnostics;
|
using System.Drawing;
|
using System.Drawing.Drawing2D;
|
using System.Drawing.Imaging;
|
using System.IO;
|
using System.Linq;
|
using System.Net;
|
using System.Reflection.Metadata;
|
using System.Runtime.InteropServices;
|
using System.Runtime.Intrinsics.X86;
|
using System.Text;
|
using System.Threading.Tasks;
|
using System.Windows.Forms;
|
using System.Xml.Linq;
|
using ZXing;
|
using ZXing.Common;
|
using ZXing.Windows.Compatibility;
|
using static System.Collections.Specialized.BitVector32;
|
using static System.Net.Mime.MediaTypeNames;
|
using static System.Resources.ResXFileRef;
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
using Extensions = OpenCvSharp.Extensions;
|
using Point = OpenCvSharp.Point;
|
using LB_VisionControl;
|
|
namespace LB_VisionProcesses.Alogrithms
|
{
|
public class TAlgorithm : IProcess
|
{
|
/// <summary>
|
/// 读写锁
|
/// </summary>
|
public static readonly object lockObj = new object();
|
|
/// <summary>
|
/// 裁切图片为hoDomainImage(保留原坐标系,其余填充为空)
|
/// </summary>
|
/// <returns></returns>
|
public virtual bool ReduceDomainImage(object InputImage, ref object image)
|
{
|
image = null;
|
if (InputImage == null)
|
{
|
image = null;
|
Msg = "输入图片为空";
|
Result = false;
|
return false;
|
}
|
|
lock (InputImage)
|
{
|
try
|
{
|
if (InputImage is Bitmap)
|
{
|
TAlgorithm.Bitmap2Mat((Bitmap)InputImage, out Mat src);
|
|
if (Params.Fixture == null)
|
Params.Fixture = new Fixture();
|
else if (dicFixtures.ContainsKey(Params.Fixture.strName))
|
Params.Fixture = dicFixtures[Params.Fixture.strName];
|
|
switch (Params.ROI?.GetType().Name)
|
{
|
case "HRectangle2":
|
// 1. 定义旋转矩形(中心点、大小、角度)
|
RotatedRect rotatedRect = new RotatedRect(
|
new Point2f(Convert.ToSingle(Params.ROI.X + Params.Fixture.X)
|
, Convert.ToSingle(Params.ROI.Y + Params.Fixture.Y)), // 中心坐标
|
new Size2f(Convert.ToSingle(((HRectangle2)Params.ROI).Width)
|
, Convert.ToSingle(((HRectangle2)Params.ROI).Height)), // 宽度和高度
|
Convert.ToSingle(((HRectangle2)Params.ROI).Angle + Params.Fixture.Angle) // 旋转角度(度)
|
);
|
|
// 2. 获取旋转矩形的4个顶点
|
Point2f[] vertices = rotatedRect.Points();
|
// 3. 修正超出边界的点坐标(关键步骤)
|
Point2f[] clampedPoints = vertices.Select(p =>
|
{
|
float x = Clamp(p.X, 0, src.Width - 1);
|
float y = Clamp(p.Y, 0, src.Height - 1);
|
return new Point2f(x, y);
|
}).ToArray();
|
Rect boundingRect = Cv2.BoundingRect(clampedPoints);
|
|
// 4. 创建与原图大小相同的Mat,并初始化无效值
|
image = new Mat(src.Size(), src.Type());
|
((Mat)image).SetTo(TAlgorithm.GetInvalidValueForMat(src)); // 全部初始化为无效值
|
|
// 5. 创建遮罩:在result上绘制旋转矩形(白色填充)
|
using (Mat cropped = new Mat(src, boundingRect))
|
{
|
cropped.CopyTo(new Mat(((Mat)image), boundingRect));
|
}
|
|
break;
|
case "HCircle":
|
// 1. 定义圆形(圆心、半径)
|
Point center = new Point(Params.ROI.X + Params.Fixture.X
|
, Params.ROI.Y + Params.Fixture.Y);
|
int radius = Convert.ToInt16(((HCircle)Params.ROI).Radius);
|
|
// 2. 创建与原图大小相同的Mat,并初始化无效值
|
image = new Mat(src.Size(), src.Type());
|
((Mat)image).SetTo(TAlgorithm.GetInvalidValueForMat(src)); // 全部初始化为无效值
|
|
// 3. 创建圆形遮罩
|
using (Mat mask = Mat.Zeros(src.Rows, src.Cols, MatType.CV_8UC1))
|
{
|
Cv2.Circle(mask, center, radius, Scalar.White, -1);
|
src.CopyTo(((Mat)image), mask);
|
}
|
break;
|
case "ROI":
|
default:
|
image = ((Bitmap)InputImage)?.Clone();
|
return true;
|
}
|
TAlgorithm.Mat2Bitmap((Mat)image, out Bitmap bmp);
|
image = bmp;
|
return true;
|
}
|
else if (InputImage is HObject ho_image)
|
{
|
if (!ho_image.IsInitialized())
|
return false;
|
|
if (Params.Fixture == null)
|
Params.Fixture = new Fixture();
|
|
HObject hoDomainImage = null;
|
|
switch (Params.ROI?.GetType().Name)
|
{
|
case "HRectangle2":
|
HOperatorSet.GenRectangle2(out HObject hRectangle2, (HTuple)(Params.ROI.Row + Params.Fixture.Row), (HTuple)(Params.ROI.Column + Params.Fixture.Column)
|
, (HTuple)(Params.ROI.Phi + Params.Fixture.Phi), (HTuple)((HRectangle2)Params.ROI).SemiLength1, (HTuple)((HRectangle2)Params.ROI).SemiLength2);
|
HOperatorSet.ReduceDomain(ho_image, hRectangle2, out hoDomainImage);
|
break;
|
case "HCircle":
|
HOperatorSet.GenCircle(out HObject hCircle, (HTuple)(Params.ROI.Row + Params.Fixture.Row), (HTuple)(Params.ROI.Column + Params.Fixture.Column)
|
, (HTuple)((HCircle)Params.ROI).Radius);
|
HOperatorSet.ReduceDomain(ho_image, hCircle, out hoDomainImage);
|
break;
|
case "ROI":
|
default:
|
image = ho_image.CopyObj(1, -1);
|
return true;
|
}
|
|
image = hoDomainImage;
|
return true;
|
}
|
else if (InputImage is Mat)
|
{
|
Mat src = ((Mat)InputImage);
|
|
if (Params.Fixture == null)
|
Params.Fixture = new Fixture();
|
switch (Params.ROI?.GetType().Name)
|
{
|
case "HRectangle2":
|
// 1. 定义旋转矩形(中心点、大小、角度)
|
RotatedRect rotatedRect = new RotatedRect(
|
new Point2f(Convert.ToSingle(Params.ROI.X + Params.Fixture.X)
|
, Convert.ToSingle(Params.ROI.Y + Params.Fixture.Y)), // 中心坐标
|
new Size2f(Convert.ToSingle(((HRectangle2)Params.ROI).Width)
|
, Convert.ToSingle(((HRectangle2)Params.ROI).Height)), // 宽度和高度
|
Convert.ToSingle(((HRectangle2)Params.ROI).Angle + Params.Fixture.Angle) // 旋转角度(度)
|
);
|
|
// 2. 获取旋转矩形的4个顶点
|
Point2f[] vertices = rotatedRect.Points();
|
// 3. 修正超出边界的点坐标(关键步骤)
|
Point2f[] clampedPoints = vertices.Select(p =>
|
{
|
float x = Clamp(p.X, 0, src.Width - 1);
|
float y = Clamp(p.Y, 0, src.Height - 1);
|
return new Point2f(x, y);
|
}).ToArray();
|
Rect boundingRect = Cv2.BoundingRect(clampedPoints);
|
|
// 4. 创建与原图大小相同的Mat,并初始化无效值
|
image = new Mat(src.Size(), src.Type());
|
((Mat)image).SetTo(TAlgorithm.GetInvalidValueForMat(src)); // 全部初始化为无效值
|
|
// 5. 创建遮罩:在result上绘制旋转矩形(白色填充)
|
using (Mat cropped = new Mat(src, boundingRect))
|
{
|
cropped.CopyTo(new Mat(((Mat)image), boundingRect));
|
}
|
|
break;
|
case "HCircle":
|
// 1. 定义圆形(圆心、半径)
|
Point center = new Point(Params.ROI.X + Params.Fixture.X
|
, Params.ROI.Y + Params.Fixture.Y);
|
int radius = Convert.ToInt16(((HCircle)Params.ROI).Radius);
|
|
// 2. 创建与原图大小相同的Mat,并初始化无效值
|
image = new Mat(src.Size(), src.Type());
|
((Mat)image).SetTo(TAlgorithm.GetInvalidValueForMat(src)); // 全部初始化为无效值
|
|
// 3. 创建圆形遮罩
|
using (Mat mask = Mat.Zeros(src.Rows, src.Cols, MatType.CV_8UC1))
|
{
|
Cv2.Circle(mask, center, radius, Scalar.White, -1);
|
src.CopyTo(((Mat)image), mask);
|
}
|
break;
|
case "ROI":
|
default:
|
image = ((Mat)InputImage)?.Clone();
|
return true;
|
}
|
return true;
|
}
|
else
|
{
|
image = null;
|
Msg = $"输入格式不正确{InputImage.GetType()}";
|
Result = false;
|
return false;
|
}
|
}
|
catch (Exception ex)
|
{
|
image = null;
|
Msg = $"裁剪区域失败,原因是:{ex.ToString()}";
|
Result = false;
|
return false;
|
}
|
}
|
}
|
|
public override void Dispose()
|
{
|
if (InputImage != null)
|
{
|
if (InputImage is HObject)
|
((HObject)InputImage).Dispose();
|
else if (InputImage is Mat)
|
((Mat)InputImage).Dispose();
|
else if (InputImage is Bitmap)
|
((Bitmap)InputImage).Dispose();
|
|
InputImage = null;
|
}
|
|
if (OutputImage != null)
|
{
|
if (OutputImage is HObject)
|
((HObject)OutputImage).Dispose();
|
else if (OutputImage is Mat)
|
((Mat)OutputImage).Dispose();
|
else if (OutputImage is Bitmap)
|
((Bitmap)OutputImage).Dispose();
|
|
OutputImage = null;
|
}
|
|
if (Record != null)
|
{
|
Record.Dispose();
|
Record = null;
|
}
|
}
|
|
public override object Clone()
|
{
|
try
|
{
|
var obj = (TAlgorithm)MemberwiseClone(); // 浅拷贝
|
|
// 手动处理引用类型
|
if (InputImage != null)
|
{
|
if (InputImage is HObject ho_image && ho_image.IsInitialized())
|
obj.InputImage = ho_image.CopyObj(1, -1);
|
else if (InputImage is Mat mat && !mat.Empty())
|
obj.InputImage = mat.Clone();
|
else if (InputImage is Bitmap bitmap)
|
obj.InputImage = bitmap.Clone();
|
}
|
|
return obj;
|
}
|
catch { return (TAlgorithm)MemberwiseClone(); }
|
}
|
|
public override void InitRunParams()
|
{
|
Result = true;
|
bCompleted = false;
|
Msg = "";
|
if (OutputImage != null)
|
{
|
if (OutputImage is HObject)
|
((HObject)OutputImage).Dispose();
|
else if (OutputImage is Mat)
|
((Mat)OutputImage).Dispose();
|
else if (OutputImage is Bitmap)
|
((Bitmap)OutputImage).Dispose();
|
OutputImage = null;
|
}
|
|
if (Record != null)
|
Record.Dispose();
|
}
|
|
public override bool Run()
|
{
|
DateTime StartTime = DateTime.Now;
|
|
InitRunParams();
|
HOperatorSet.GenEmptyObj(out HObject EmptyObj);
|
OutputImage = EmptyObj;
|
|
// 创建并启动任务
|
Task.Factory.StartNew(() => { TAlgorithmMain(); });
|
|
while ((DateTime.Now - StartTime).TotalMilliseconds <= MaxTimeOut)
|
{
|
if (bCompleted)
|
{
|
RunTime = (DateTime.Now - StartTime).TotalMilliseconds;
|
return Result;
|
}
|
|
Thread.Sleep(30);
|
}
|
|
Msg = "运行超时";
|
Result = false;
|
RunTime = (DateTime.Now - StartTime).TotalMilliseconds;
|
return false;
|
}
|
|
/// <summary>
|
/// 算子逻辑
|
/// </summary>
|
public virtual void TAlgorithmMain()
|
{
|
bCompleted = true;
|
Debug.WriteLine("任务完成");
|
}
|
|
/// <summary>
|
/// 加载算法
|
/// </summary>
|
/// <param name="fullPath">完整路径带.json</param>
|
/// <returns></returns>
|
public override bool Load(string fullPath = "")
|
{
|
try
|
{
|
if (string.IsNullOrEmpty(fullPath))
|
return false;
|
|
if (!fullPath.Contains(".json"))
|
{
|
Debug.WriteLine("文件路径不完整");
|
return false;
|
}
|
if (string.IsNullOrEmpty(fullPath) || fullPath.Trim() == "")
|
{
|
Debug.WriteLine("文件路径不完整");
|
return false;
|
}
|
|
// 获取不带文件名的目录路径
|
string directoryPath = Path.GetDirectoryName(fullPath);
|
strProcessName = Path.GetFileNameWithoutExtension(fullPath);
|
|
if (!File.Exists(fullPath))
|
{
|
Debug.WriteLine("文件不存在创建空文件");
|
Save(directoryPath);
|
return true;
|
}
|
|
string strJson = string.Empty;
|
using (StreamReader streamReader = new StreamReader(fullPath, Encoding.UTF8))
|
{
|
strJson = streamReader.ReadToEnd();
|
streamReader.Close();
|
}
|
Params = JsonConvert.DeserializeObject<ProcessParams>(strJson);
|
if (Params == null)
|
return false;
|
|
Params.FixDeserializedData();
|
return true;
|
}
|
catch { return false; }
|
}
|
|
/// <summary>
|
/// 保存算法
|
/// </summary>
|
/// <param name="filePath">不带.json</param>
|
/// <returns></returns>
|
public override bool Save(string filePath = "")
|
{
|
try
|
{
|
if (string.IsNullOrEmpty(filePath) || filePath.Trim() == "")
|
{
|
Debug.WriteLine("文件路径不完整");
|
return false;
|
}
|
|
string strJson = string.Empty;
|
var settings = new JsonSerializerSettings
|
{
|
Formatting = Newtonsoft.Json.Formatting.Indented,
|
// 自定义缩进(4空格)
|
ContractResolver = new DefaultContractResolver
|
{
|
NamingStrategy = new CamelCaseNamingStrategy()
|
}
|
};
|
strJson = JsonConvert.SerializeObject(Params, settings);
|
|
Params = JsonConvert.DeserializeObject<ProcessParams>(strJson);
|
//判断文件夹是否存在,防呆输入为文件名称
|
if (!Directory.Exists(filePath))
|
{
|
try
|
{
|
Directory.CreateDirectory(filePath);
|
}
|
catch (Exception)
|
{ }
|
}
|
File.WriteAllText(filePath + "//" + strProcessName + ".json", strJson, Encoding.UTF8);
|
return true;
|
}
|
catch { return false; }
|
}
|
|
#region 自定义的算法
|
// 通用版本的 Clamp 方法
|
public static T Clamp<T>(T value, T min, T max) where T : IComparable<T>
|
{
|
if (value.CompareTo(min) < 0)
|
return min;
|
else if (value.CompareTo(max) > 0)
|
return max;
|
else
|
return value;
|
}
|
|
public static void Bitmap2HObject(Bitmap bmp, out HObject image)
|
{
|
BitmapData srcBmpData;
|
|
try
|
{
|
if (bmp == null || bmp.Width == 0 || bmp.Height == 0)
|
{
|
image = null;
|
return;
|
}
|
|
lock (bmp)
|
{
|
switch (bmp.PixelFormat)
|
{
|
case PixelFormat.Format24bppRgb:
|
srcBmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
|
|
int width = bmp.Width;
|
int height = bmp.Height;
|
int stride = srcBmpData.Stride;
|
|
if (stride == width * 3)
|
HOperatorSet.GenImageInterleaved(out image, srcBmpData.Scan0, "bgr", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0);
|
else
|
image = HandleStrideAlignmentBest(srcBmpData.Scan0, width, height, stride);
|
|
bmp.UnlockBits(srcBmpData);
|
break;
|
default:
|
srcBmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
|
HOperatorSet.GenImage1(out image, "byte", bmp.Width, bmp.Height, srcBmpData.Scan0);
|
bmp.UnlockBits(srcBmpData);
|
break;
|
}
|
}
|
return;
|
}
|
catch
|
{
|
image = null;
|
return;
|
}
|
}
|
|
private static HObject HandleStrideAlignmentBest(IntPtr scan0, int width, int height, int stride)
|
{
|
int expectedStride = width * 3;
|
byte[] alignedData = new byte[width * height * 3];
|
|
unsafe
|
{
|
byte* srcPtr = (byte*)scan0;
|
fixed (byte* dstPtr = alignedData)
|
{
|
// 使用最快速的复制方法
|
|
// .NET Core 3.0+ 使用 Buffer.MemoryCopy
|
for (int y = 0; y < height; y++)
|
{
|
Buffer.MemoryCopy(
|
srcPtr + y * stride,
|
dstPtr + y * expectedStride,
|
expectedStride,
|
expectedStride
|
);
|
}
|
HOperatorSet.GenImageInterleaved(out HObject ho_img, new IntPtr(dstPtr), "bgr", width, height, 0, "byte", width, height, 0, 0, -1, 0);
|
return ho_img;
|
}
|
}
|
}
|
|
public static unsafe void HObject2Bitmap(HObject hObject, out Bitmap bmp)
|
{
|
try
|
{
|
if (hObject == null || !hObject.IsInitialized())
|
{
|
bmp = null;
|
return;
|
}
|
|
// 获取图像信息
|
HOperatorSet.GetImageSize(hObject, out HTuple width, out HTuple height);
|
HOperatorSet.CountChannels(hObject, out HTuple channels);
|
|
if (channels.I == 1)
|
{
|
// 灰度图处理
|
HTuple ptr, type;
|
HOperatorSet.GetImagePointer1(hObject, out ptr, out type, out width, out height);
|
|
bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
|
|
// 设置灰度调色板
|
ColorPalette palette = bmp.Palette;
|
for (int i = 0; i < 256; i++)
|
palette.Entries[i] = Color.FromArgb(i, i, i);
|
bmp.Palette = palette;
|
|
// 直接内存拷贝
|
BitmapData bmpData = bmp.LockBits(
|
new Rectangle(0, 0, width, height),
|
ImageLockMode.WriteOnly,
|
PixelFormat.Format8bppIndexed);
|
|
Buffer.MemoryCopy(
|
(void*)ptr.L,
|
(void*)bmpData.Scan0,
|
width * height,
|
width * height);
|
|
bmp.UnlockBits(bmpData);
|
return;
|
}
|
else
|
{
|
// 彩色图处理(BGR顺序)
|
HTuple ptrR, ptrG, ptrB, type;
|
HOperatorSet.GetImagePointer3(hObject, out ptrR, out ptrG, out ptrB, out type, out width, out height);
|
|
bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
|
BitmapData bmpData = bmp.LockBits(
|
new Rectangle(0, 0, width, height),
|
ImageLockMode.WriteOnly,
|
PixelFormat.Format24bppRgb);
|
|
byte* dstPtr = (byte*)bmpData.Scan0;
|
byte* srcR = (byte*)ptrR.L;
|
byte* srcG = (byte*)ptrG.L;
|
byte* srcB = (byte*)ptrB.L;
|
|
Parallel.For(0, height.I, y =>
|
{
|
int srcOffset = y * width;
|
int dstOffset = y * bmpData.Stride;
|
|
for (int x = 0; x < width; x++)
|
{
|
dstPtr[dstOffset + x * 3] = srcB[srcOffset + x]; // B
|
dstPtr[dstOffset + x * 3 + 1] = srcG[srcOffset + x]; // G
|
dstPtr[dstOffset + x * 3 + 2] = srcR[srcOffset + x]; // R
|
}
|
});
|
|
bmp.UnlockBits(bmpData);
|
return;
|
}
|
}
|
catch
|
{
|
bmp = null;
|
return;
|
}
|
}
|
|
public static void Mat2HObject(Mat mat, out HObject image)
|
{
|
try
|
{
|
if (mat == null || mat.Empty())
|
{
|
image = null;
|
return;
|
}
|
|
if (mat.Type() == MatType.CV_8UC3) // 彩色图像 (BGR)
|
{
|
HOperatorSet.GenImageInterleaved(
|
out image,
|
mat.Data,
|
"bgr",
|
mat.Width,
|
mat.Height,
|
0,
|
"byte",
|
0, 0, 0, 0, -1, 0);
|
}
|
else if (mat.Type() == MatType.CV_8UC1) // 灰度图像
|
{
|
HOperatorSet.GenImage1(
|
out image,
|
"byte",
|
mat.Width,
|
mat.Height,
|
mat.Data);
|
}
|
else
|
{
|
throw new ArgumentException($"Mat2HObject不支持的图像格式:{mat.Type()}");
|
return;
|
}
|
return;
|
}
|
catch
|
{
|
image = null;
|
return;
|
}
|
}
|
|
public static void HObject2Mat(HObject image, out Mat mat)
|
{
|
try
|
{
|
if (image == null || !image.IsInitialized())
|
{
|
mat = null;
|
return;
|
}
|
|
// 获取图像类型信息
|
HOperatorSet.CountChannels(image, out HTuple channels);
|
|
// 根据通道数选择不同的处理方式
|
if (channels.I == 1)
|
{
|
mat = ConvertGrayImage(image);
|
}
|
else if (channels.I == 3)
|
{
|
mat = ConvertColorImage(image);
|
}
|
else
|
{
|
mat = null;
|
return;
|
}
|
}
|
catch
|
{
|
mat = null;
|
return;
|
}
|
}
|
|
public static Mat ConvertColorImage(HObject colorimage)
|
{
|
// 获取Halcon图像指针
|
HOperatorSet.GetImagePointer3(colorimage,
|
out HTuple ptrR, out HTuple ptrG, out HTuple ptrB,
|
out HTuple type, out HTuple width, out HTuple height);
|
|
// 创建OpenCV Mat(注意BGR顺序)
|
Mat mat = new Mat(height.I, width.I, MatType.CV_8UC3);
|
|
unsafe
|
{
|
byte* matPtr = (byte*)mat.Data;
|
byte[] r = new byte[width * height];
|
byte[] g = new byte[width * height];
|
byte[] b = new byte[width * height];
|
|
// 从Halcon拷贝数据
|
Marshal.Copy(ptrR.IP, r, 0, r.Length);
|
Marshal.Copy(ptrG.IP, g, 0, g.Length);
|
Marshal.Copy(ptrB.IP, b, 0, b.Length);
|
|
// 填充Mat(Halcon的RGB → OpenCV的BGR)
|
for (int i = 0; i < height; i++)
|
{
|
for (int j = 0; j < width; j++)
|
{
|
int idx = i * width + j;
|
matPtr[i * mat.Step() + j * 3] = b[idx]; // B
|
matPtr[i * mat.Step() + j * 3 + 1] = g[idx]; // G
|
matPtr[i * mat.Step() + j * 3 + 2] = r[idx]; // R
|
}
|
}
|
}
|
return mat;
|
}
|
|
public static Mat ConvertGrayImage(HObject grayImage)
|
{
|
// 获取单通道图像指针
|
HOperatorSet.GetImagePointer1(grayImage, out HTuple ptrGray,
|
out HTuple type, out HTuple width, out HTuple height);
|
|
// 创建OpenCV灰度Mat
|
Mat mat = new Mat(height.I, width.I, MatType.CV_8UC1);
|
|
//获取图像数据总字节数
|
int totalBytes = width.I * height.I;
|
// 使用非托管内存复制
|
unsafe
|
{
|
Buffer.MemoryCopy(
|
(void*)ptrGray.IP, // 源指针 (Halcon)
|
(void*)mat.Data, // 目标指针 (OpenCV)
|
totalBytes, // 目标缓冲区大小
|
totalBytes // 要复制的字节数
|
);
|
}
|
// 拷贝数据
|
//Marshal.Copy(ptrGray.IP, mat.Data, 0, width.I * height.I);
|
|
return mat;
|
}
|
|
public static void Bitmap2Mat(Bitmap bmp, out Mat image)
|
{
|
try
|
{
|
if (bmp == null)
|
{
|
image = null;
|
return;
|
}
|
|
image = Extensions.BitmapConverter.ToMat(bmp);
|
return;
|
}
|
catch
|
{
|
image = null;
|
return;
|
}
|
}
|
|
public static void Mat2Bitmap(Mat mat, out Bitmap image)
|
{
|
try
|
{
|
if (mat == null)
|
{
|
image = null;
|
return;
|
}
|
|
image = Extensions.BitmapConverter.ToBitmap(mat);
|
}
|
catch
|
{
|
image = null;
|
return;
|
}
|
}
|
|
public static void Bitmap2BinaryBitmap(Bitmap bitmap, out BinaryBitmap binarybitmap)
|
{
|
BinaryBitmap bbmp;
|
try
|
{
|
if (bitmap != null)
|
{
|
LuminanceSource source = new BitmapLuminanceSource(bitmap);
|
//var binarizer = new GlobalHistogramBinarizer(source);
|
var binarizer = new HybridBinarizer(source); // 或者用这个
|
bbmp = new BinaryBitmap(binarizer);
|
binarybitmap = bbmp;
|
}
|
else
|
{
|
binarybitmap = null;
|
}
|
}
|
catch
|
{
|
binarybitmap = null;
|
}
|
}
|
|
public static void BinaryBitmap2Bitmap(BinaryBitmap binarybitmap, out Bitmap bitmap)
|
{
|
try
|
{
|
if (binarybitmap != null)
|
{
|
BitMatrix bitmatrix = binarybitmap.BlackMatrix;
|
bitmap = new Bitmap(bitmatrix.Width, bitmatrix.Height);
|
for (int i = 0; i < bitmatrix.Width; i++)
|
{
|
for (int j = 0; j < bitmatrix.Height; j++)
|
bitmap.SetPixel(i, j, bitmatrix[i, j] ? Color.Black : Color.White);
|
}
|
}
|
else
|
{
|
bitmap = null;
|
}
|
}
|
catch
|
{
|
bitmap = null;
|
}
|
}
|
|
public static void DeepImage2PointsCloud(HObject image, out HTuple pointsCloud)
|
{
|
// Stack for temporary objects
|
HObject[] OTemp = new HObject[20];
|
|
// Local iconic variables
|
|
HObject ho_ImageZ, ho_ImageX, ho_ImageY, ho_Region;
|
HObject ho_ImageReduced, ho_Z, ho_ImageScaled;
|
|
// Local control variables
|
|
HTuple hv_xResolution = new HTuple(), hv_yResolution = new HTuple();
|
HTuple hv_zResolution = new HTuple(), hv_ScaleFactor = new HTuple();
|
HTuple hv_WindowHandle = new HTuple(), hv_Width = new HTuple();
|
HTuple hv_Height = new HTuple(), hv_Min = new HTuple();
|
HTuple hv_Max = new HTuple(), hv_Range = new HTuple();
|
HTuple hv_factor = new HTuple(), hv_ScaleZ = new HTuple();
|
HTuple hv_zScale = new HTuple();
|
HTuple hv_Instructions = new HTuple(), hv_PoseOut = new HTuple();
|
pointsCloud = new HTuple();
|
// Initialize local and output iconic variables
|
HOperatorSet.GenEmptyObj(out ho_ImageZ);
|
HOperatorSet.GenEmptyObj(out ho_ImageX);
|
HOperatorSet.GenEmptyObj(out ho_ImageY);
|
HOperatorSet.GenEmptyObj(out ho_Region);
|
HOperatorSet.GenEmptyObj(out ho_ImageReduced);
|
HOperatorSet.GenEmptyObj(out ho_Z);
|
HOperatorSet.GenEmptyObj(out ho_ImageScaled);
|
try
|
{
|
//读取深度图
|
ho_ImageZ.Dispose();
|
ho_ImageZ = image;
|
|
//确定xyz的显示分辨率,即确定缩放因子
|
hv_xResolution.Dispose();
|
hv_xResolution = 1;
|
hv_yResolution.Dispose();
|
hv_yResolution = 1;
|
hv_zResolution.Dispose();
|
hv_zResolution = 1;
|
//确定缩放因子
|
hv_ScaleFactor.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ScaleFactor = new HTuple();
|
hv_ScaleFactor = hv_ScaleFactor.TupleConcat(hv_xResolution, hv_yResolution, hv_zResolution);
|
}
|
//获取窗口句柄
|
if (HDevWindowStack.IsOpen())
|
{
|
hv_WindowHandle = HDevWindowStack.GetActive();
|
}
|
//获取图像大小
|
hv_Width.Dispose(); hv_Height.Dispose();
|
HOperatorSet.GetImageSize(ho_ImageZ, out hv_Width, out hv_Height);
|
|
|
//生成X曲面图像
|
ho_ImageX.Dispose();
|
HOperatorSet.GenImageSurfaceFirstOrder(out ho_ImageX, "real", 0, 1, 0, 0, 0,
|
hv_Width, hv_Height);
|
//生成Y曲面图像
|
ho_ImageY.Dispose();
|
HOperatorSet.GenImageSurfaceFirstOrder(out ho_ImageY, "real", 1, 0, 0, 0, 0,
|
hv_Width, hv_Height);
|
|
|
//对深度图进行处理滤波处理
|
|
//获取深度图最小值 Min 和最大值 Max,以及范围 Range
|
hv_Min.Dispose(); hv_Max.Dispose(); hv_Range.Dispose();
|
HOperatorSet.MinMaxGray(ho_ImageZ, ho_ImageZ, 0, out hv_Min, out hv_Max, out hv_Range);
|
|
//如果最小值小于0,则图像乘1,加-min,即保持最低值为0
|
if ((int)(new HTuple(hv_Min.TupleLess(0.0))) != 0)
|
{
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
HObject ExpTmpOutVar_0;
|
HOperatorSet.ScaleImage(ho_ImageZ, out ExpTmpOutVar_0, 1.0, -hv_Min);
|
ho_ImageZ.Dispose();
|
ho_ImageZ = ExpTmpOutVar_0;
|
}
|
}
|
//获取新深度图的最小值 Min 和最大值 Max,以及范围 Range
|
hv_Min.Dispose(); hv_Max.Dispose(); hv_Range.Dispose();
|
HOperatorSet.MinMaxGray(ho_ImageZ, ho_ImageZ, 0, out hv_Min, out hv_Max, out hv_Range);
|
// 检查Min和Max的值
|
Debug.WriteLine($"Min: {hv_Min.D}, Max: {hv_Max.D}");
|
//阈值提取(核心)
|
ho_Region.Dispose();
|
HOperatorSet.Threshold(ho_ImageZ, out ho_Region
|
, hv_Max.D < 1.0 ? 0 : 1, hv_Max);
|
//获取区域图像
|
ho_ImageReduced.Dispose();
|
HOperatorSet.ReduceDomain(ho_ImageZ, ho_Region, out ho_ImageReduced);
|
//转实数图
|
ho_Z.Dispose();
|
HOperatorSet.ConvertImageType(ho_ImageReduced, out ho_Z, "real");
|
//获取新深度图的最小值 Min 和最大值 Max,以及范围 Range
|
hv_Min.Dispose(); hv_Max.Dispose(); hv_Range.Dispose();
|
HOperatorSet.MinMaxGray(ho_Z, ho_Z, 0, out hv_Min, out hv_Max, out hv_Range);
|
//计算缩放因子 factor = xResolution / zResolution,然后计算 Z 方向上的缩放比例 ScaleZ = 1 / factor
|
hv_factor.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_factor = hv_xResolution / hv_zResolution;
|
}
|
hv_ScaleZ.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ScaleZ = 1 / hv_factor;
|
}
|
//输出
|
hv_zScale.Dispose();
|
hv_zScale = new HTuple(hv_ScaleZ);
|
//将 Z 按照缩放比例 ScaleZ 进行缩放,并存储在 ImageScaled 中
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
ho_ImageScaled.Dispose();
|
HOperatorSet.ScaleImage(ho_Z, out ho_ImageScaled, hv_ScaleZ, (-hv_ScaleZ) * hv_Min);
|
}
|
|
//把X,Y,Z图像拟合为3D点云模型
|
pointsCloud.Dispose();
|
HOperatorSet.XyzToObjectModel3d(ho_ImageX, ho_ImageY, ho_ImageScaled, out pointsCloud);
|
//HOperatorSet.WriteObjectModel3d(hv_ObjectModel3D, "om3", "test", new HTuple(),
|
// new HTuple());
|
if (hv_Instructions == null)
|
hv_Instructions = new HTuple();
|
hv_Instructions[0] = "";
|
|
//objectModel3D = hv_ObjectModel3D.Clone();
|
//// 持久化生成的3D模型
|
//HOperatorSet.WriteObjectModel3d(objectModel3D, "om3", "pcl.om3", new HTuple(), new HTuple());
|
//// 提示生成3D模型成功
|
//MessageBox.Show("生成3D模型OK");
|
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
ho_ImageZ.Dispose();
|
ho_ImageX.Dispose();
|
ho_ImageY.Dispose();
|
ho_Region.Dispose();
|
ho_ImageReduced.Dispose();
|
ho_Z.Dispose();
|
ho_ImageScaled.Dispose();
|
|
hv_xResolution.Dispose();
|
hv_yResolution.Dispose();
|
hv_zResolution.Dispose();
|
hv_ScaleFactor.Dispose();
|
hv_WindowHandle.Dispose();
|
hv_Width.Dispose();
|
hv_Height.Dispose();
|
hv_Min.Dispose();
|
hv_Max.Dispose();
|
hv_Range.Dispose();
|
hv_factor.Dispose();
|
hv_ScaleZ.Dispose();
|
hv_zScale.Dispose();
|
hv_Instructions.Dispose();
|
hv_PoseOut.Dispose();
|
|
throw HDevExpDefaultException;
|
}
|
finally
|
{
|
ho_ImageZ.Dispose();
|
ho_ImageX.Dispose();
|
ho_ImageY.Dispose();
|
ho_Region.Dispose();
|
ho_ImageReduced.Dispose();
|
ho_Z.Dispose();
|
ho_ImageScaled.Dispose();
|
|
hv_xResolution.Dispose();
|
hv_yResolution.Dispose();
|
hv_zResolution.Dispose();
|
hv_ScaleFactor.Dispose();
|
hv_WindowHandle.Dispose();
|
hv_Width.Dispose();
|
hv_Height.Dispose();
|
hv_Min.Dispose();
|
hv_Max.Dispose();
|
hv_Range.Dispose();
|
hv_factor.Dispose();
|
hv_ScaleZ.Dispose();
|
hv_zScale.Dispose();
|
hv_Instructions.Dispose();
|
hv_PoseOut.Dispose();
|
}
|
}
|
|
public static void DeepImage2PointsCloud(HObject image, out HTuple pointsCloud
|
, double XScale = 1, double YScale = 1, double ZScale = 1, int ZOffset = 0
|
, int InvalidValue = 0, int minColor = 0, int maxColor = 180, double grayPercent = 0.8)
|
{
|
// Stack for temporary objects
|
HObject[] OTemp = new HObject[20];
|
|
// Local iconic variables
|
HObject ho_ImageH;
|
HObject ho_ImageZ, ho_ImageX, ho_ImageY, ho_Region;
|
HObject ho_ImageReduced, ho_Z, ho_ImageScaled;
|
|
// Local control variables
|
|
HTuple hv_xResolution = new HTuple(), hv_yResolution = new HTuple();
|
HTuple hv_zResolution = new HTuple(), hv_ScaleFactor = new HTuple();
|
HTuple hv_WindowHandle = new HTuple(), hv_Width = new HTuple();
|
HTuple hv_Height = new HTuple(), hv_Min = new HTuple();
|
HTuple hv_Max = new HTuple(), hv_Range = new HTuple();
|
HTuple hv_factor = new HTuple(), hv_ScaleZ = new HTuple();
|
HTuple hv_zScale = new HTuple();
|
HTuple hv_Instructions = new HTuple(), hv_PoseOut = new HTuple();
|
pointsCloud = new HTuple();
|
// Initialize local and output iconic variables
|
HOperatorSet.GenEmptyObj(out ho_ImageH);
|
HOperatorSet.GenEmptyObj(out ho_ImageZ);
|
HOperatorSet.GenEmptyObj(out ho_ImageX);
|
HOperatorSet.GenEmptyObj(out ho_ImageY);
|
HOperatorSet.GenEmptyObj(out ho_Region);
|
HOperatorSet.GenEmptyObj(out ho_ImageReduced);
|
HOperatorSet.GenEmptyObj(out ho_Z);
|
HOperatorSet.GenEmptyObj(out ho_ImageScaled);
|
try
|
{
|
//获取原图像
|
ho_ImageH.Dispose();
|
HOperatorSet.CopyImage(image, out ho_ImageH);
|
|
hv_Width.Dispose(); hv_Height.Dispose();
|
HOperatorSet.GetImageSize(image, out hv_Width, out hv_Height);
|
|
//读取深度图
|
ho_ImageZ.Dispose();
|
HOperatorSet.GetDomain(ho_ImageH, out HObject ho_ImageDomain);
|
|
//获取深度图最小值 Min 和最大值 Max,以及范围 Range
|
hv_Min.Dispose(); hv_Max.Dispose(); hv_Range.Dispose();
|
HOperatorSet.MinMaxGray(ho_ImageDomain, ho_ImageH, 0, out hv_Min, out hv_Max, out hv_Range);
|
|
// 检查Min和Max的值
|
Debug.WriteLine($"Min: {hv_Min.D}, Max: {hv_Max.D}");
|
//如果最小值小于0,则图像乘1,加-min,即保持最低值为0
|
//if ((int)(new HTuple(hv_Min.TupleLess(0.0))) != 0)
|
//{
|
// using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
// {
|
// HObject ExpTmpOutVar_0;
|
// HOperatorSet.ScaleImage(ho_ImageZ, out ExpTmpOutVar_0, 1.0, -hv_Min);
|
// ho_ImageZ.Dispose();
|
// ho_ImageZ = ExpTmpOutVar_0;
|
// }
|
//}
|
|
//阈值提取(核心)
|
ho_Region.Dispose();
|
HOperatorSet.Threshold(ho_ImageH, out ho_Region
|
, hv_Min.D > 0 && InvalidValue > 0 ? InvalidValue : 0, hv_Max);
|
|
//转实数图
|
HOperatorSet.ConvertImageType(ho_ImageH, out ho_ImageH, "real");
|
|
//将 Z 按照缩放比例 ScaleZ 进行缩放,并存储在 ImageScaled 中
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
ho_ImageScaled.Dispose();
|
HOperatorSet.ScaleImage(ho_ImageH, out ho_ImageScaled, ZScale, ZScale * ZOffset);
|
}
|
|
//获取新深度图的最小值 Min 和最大值 Max,以及范围 Range
|
hv_Min.Dispose(); hv_Max.Dispose(); hv_Range.Dispose();
|
HOperatorSet.MinMaxGray(ho_Region, ho_ImageScaled, 0, out hv_Min, out hv_Max, out hv_Range);
|
|
//将高度图转为HSV格式的图像
|
double k = (maxColor - minColor) * 1.0 / (hv_Max.D - hv_Min.D);
|
double b = maxColor - k * hv_Min.D * 1.0;
|
HOperatorSet.ReduceDomain(ho_ImageScaled, ho_Region, out HObject ho_ImageZOut);
|
//
|
HOperatorSet.ScaleImage(ho_ImageZOut, out HObject ho_ImageZOutScaled, k, b);
|
HOperatorSet.ConvertImageType(ho_ImageZOutScaled, out HObject ho_ImageZByte, "byte");
|
HOperatorSet.GenImageProto(ho_ImageZByte, out HObject ho_ImageZProto, 255);
|
HOperatorSet.TransToRgb(ho_ImageZByte, ho_ImageZProto, ho_ImageZProto
|
, out HObject H, out HObject S, out HObject V, "hsv");
|
HOperatorSet.Compose3(H, S, V, out HObject HSV);
|
|
//生成X曲面图像
|
ho_ImageX.Dispose();
|
HOperatorSet.GenImageSurfaceFirstOrder(out ho_ImageX, "real", 0, XScale, 0, 0, 0,
|
hv_Width, hv_Height);
|
//生成Y曲面图像
|
ho_ImageY.Dispose();
|
HOperatorSet.GenImageSurfaceFirstOrder(out ho_ImageY, "real", YScale, 0, 0, 0, 0,
|
hv_Width, hv_Height);
|
|
//把X,Y,Z图像拟合为3D点云模型
|
pointsCloud.Dispose();
|
HOperatorSet.XyzToObjectModel3d(ho_ImageX, ho_ImageY, ho_ImageZOut, out pointsCloud);
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
ho_ImageZ.Dispose();
|
ho_ImageX.Dispose();
|
ho_ImageY.Dispose();
|
ho_Region.Dispose();
|
ho_ImageReduced.Dispose();
|
ho_Z.Dispose();
|
ho_ImageScaled.Dispose();
|
|
hv_xResolution.Dispose();
|
hv_yResolution.Dispose();
|
hv_zResolution.Dispose();
|
hv_ScaleFactor.Dispose();
|
hv_WindowHandle.Dispose();
|
hv_Width.Dispose();
|
hv_Height.Dispose();
|
hv_Min.Dispose();
|
hv_Max.Dispose();
|
hv_Range.Dispose();
|
hv_factor.Dispose();
|
hv_ScaleZ.Dispose();
|
hv_zScale.Dispose();
|
hv_Instructions.Dispose();
|
hv_PoseOut.Dispose();
|
|
throw HDevExpDefaultException;
|
}
|
finally
|
{
|
ho_ImageH.Dispose();
|
ho_ImageZ.Dispose();
|
ho_ImageX.Dispose();
|
ho_ImageY.Dispose();
|
ho_Region.Dispose();
|
ho_ImageReduced.Dispose();
|
ho_Z.Dispose();
|
ho_ImageScaled.Dispose();
|
|
hv_xResolution.Dispose();
|
hv_yResolution.Dispose();
|
hv_zResolution.Dispose();
|
hv_ScaleFactor.Dispose();
|
hv_WindowHandle.Dispose();
|
hv_Width.Dispose();
|
hv_Height.Dispose();
|
hv_Min.Dispose();
|
hv_Max.Dispose();
|
hv_Range.Dispose();
|
hv_factor.Dispose();
|
hv_ScaleZ.Dispose();
|
hv_zScale.Dispose();
|
hv_Instructions.Dispose();
|
hv_PoseOut.Dispose();
|
}
|
}
|
|
public static void PointsCloud2DeepImage(HTuple pointsCloud, out HObject image, double Resolution = 1.0)
|
{
|
HOperatorSet.GenEmptyObj(out image);
|
image = null;
|
try
|
{
|
HOperatorSet.GetObjectModel3dParams(pointsCloud, "point_coord_z", out HTuple hv_z);
|
HOperatorSet.GetObjectModel3dParams(pointsCloud, "point_coord_y", out HTuple hv_y);
|
HOperatorSet.GetObjectModel3dParams(pointsCloud, "point_coord_x", out HTuple hv_x);
|
|
HOperatorSet.TupleMin(hv_x, out HTuple hv_Min);
|
HTuple hv_xTemp = hv_x - hv_Min;
|
hv_x = hv_xTemp;
|
hv_xTemp = ((hv_x / Resolution)).TupleInt();
|
hv_x.Dispose();
|
hv_x = hv_xTemp;
|
|
HOperatorSet.TupleMin(hv_y, out hv_Min);
|
HTuple hv_yTemp = hv_y - hv_Min;
|
hv_y = hv_yTemp;
|
hv_yTemp = ((hv_y / Resolution)).TupleInt();
|
hv_y.Dispose();
|
hv_y = hv_yTemp;
|
|
HOperatorSet.TupleMin(hv_z, out hv_Min);
|
HTuple hv_zTemp = hv_z - hv_Min;
|
hv_z.Dispose();
|
hv_z = hv_zTemp;
|
|
HOperatorSet.TupleMax(hv_x, out HTuple hv_xMax);
|
HOperatorSet.TupleMax(hv_y, out HTuple hv_yMax);
|
HOperatorSet.GenImageConst(out image, "real", hv_xMax + 1, hv_yMax + 1);
|
HOperatorSet.SetGrayval(image, hv_y, hv_x, hv_z);
|
|
//HOperatorSet.GetImageSize(ho_Image, out HTuple hv_Width, out HTuple hv_Height);
|
//HOperatorSet.GenRectangle1(out HObject ho_Rectangle, 0, 0, hv_Height - 1, hv_Width - 1);
|
//HOperatorSet.GetRegionPoints(ho_Rectangle, out HTuple hv_Rows, out HTuple hv_Columns);
|
//HOperatorSet.GetGrayval(ho_Image, hv_Rows, hv_Columns, out HTuple hv_Z);
|
}
|
catch { image = null; }
|
}
|
|
/// <summary>
|
/// 计算两点的距离
|
/// </summary>
|
/// <param name="startPoint"></param>
|
/// <param name="endPoint"></param>
|
/// <returns></returns>
|
public static double GetDistanceP2P(HPoint startPoint, HPoint endPoint)
|
{
|
try
|
{
|
return Math.Sqrt(Math.Pow(startPoint.X - endPoint.X, 2) + Math.Pow(startPoint.Y - endPoint.Y, 2));
|
}
|
catch { return 9994; }
|
}
|
|
public static double GetDistanceP2P(Point startPoint, Point endPoint)
|
{
|
return GetDistanceP2P(new HPoint(startPoint), new HPoint(endPoint));
|
}
|
|
public static double DistanceP2P(double startX, double startY, double endX, double endY)
|
{
|
return GetDistanceP2P(new HPoint(startX, startY), new HPoint(endX, endY));
|
}
|
|
/// <summary>
|
/// 获取两点的中点
|
/// </summary>
|
/// <param name="startPoint"></param>
|
/// <param name="endPoint"></param>
|
/// <returns></returns>
|
public static HPoint GetMidPoint(HPoint startPoint, HPoint endPoint)
|
{
|
return new HPoint((startPoint.X + endPoint.X) / 2, (startPoint.Y + endPoint.Y) / 2);
|
}
|
|
public static Point GetMidPoint(Point startPoint, Point endPoint)
|
{
|
return new Point((startPoint.X + endPoint.X) / 2, (startPoint.Y + endPoint.Y) / 2);
|
}
|
|
public static System.Drawing.Point GetMidPoint(System.Drawing.Point startPoint, System.Drawing.Point endPoint)
|
{
|
return new System.Drawing.Point((startPoint.X + endPoint.X) / 2, (startPoint.Y + endPoint.Y) / 2);
|
}
|
|
/// <summary>
|
/// 判断点是否在线段上
|
/// </summary>
|
/// <param name="point"></param>
|
/// <param name="segment"></param>
|
/// <returns></returns>
|
public static bool IsPointOnSegment(HPoint pt, HSegment segment, double tolerance = 1e-3)
|
{
|
// 计算直线方程的系数
|
double A = segment.EndY - segment.StartX;
|
double B = segment.StartX - segment.EndX;
|
double C = segment.EndX * segment.StartY - segment.StartX * segment.EndY;
|
|
// 计算点到直线的距离
|
double distance = Math.Abs(A * pt.X + B * pt.Y + C) / Math.Sqrt(A * A + B * B);
|
|
// 允许一个很小的误差
|
if (distance < tolerance)
|
{
|
// 判断点是否在直线段范围内
|
if (Math.Min(segment.StartX, segment.EndX) <= pt.X && pt.X <= Math.Max(segment.StartX, segment.EndX)
|
&& Math.Min(segment.StartY, segment.EndY) <= pt.Y && pt.Y <= Math.Max(segment.StartY, segment.EndY))
|
{
|
return true;
|
}
|
}
|
return false;
|
}
|
|
public static bool IsPointOnSegment(double px, double py, double x1, double y1, double x2, double y2)
|
{
|
return IsPointOnSegment(new HPoint(px, py), new HSegment(x1, y1, x2, y2));
|
}
|
|
/// <summary>
|
/// 判断点是否在矩形边附近
|
/// </summary>
|
/// <param name="pt"></param>
|
/// <param name="rect"></param>
|
/// <param name="tolerance"></param>
|
/// <returns></returns>
|
static bool IsPointNearRectangleSilde(System.Drawing.Point pt, Rectangle rect, double tolerance = 100)
|
{
|
try
|
{
|
// 如果点的 X 坐标等于矩形的左边 (rect.Left) 或右边 (rect.Right),并且 Y 坐标在矩形的上下边界之间,那么点在矩形的垂直边界上。
|
// 如果点的 Y 坐标等于矩形的上边(rect.Top) 或下边(rect.Bottom),并且 X 坐标在矩形的左右边界之间,那么点在矩形的水平边界上。
|
return (Math.Abs(pt.X - rect.Left) <= tolerance || Math.Abs(pt.X - rect.Right) <= tolerance) && pt.Y >= rect.Top + tolerance && pt.Y <= rect.Bottom - tolerance
|
|| (Math.Abs(pt.Y - rect.Top) <= tolerance || Math.Abs(pt.Y - rect.Bottom) <= tolerance) && pt.X >= rect.Left - tolerance && pt.X <= rect.Right + tolerance;
|
|
}
|
catch { return false; }
|
}
|
|
public static bool IsPointNearRectangleSilde(HPoint pt, HRectangle2 rect, double tolerance = 100)
|
{
|
return IsPointNearRectangleSilde(new System.Drawing.Point((int)pt.X, (int)pt.Y), new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height), tolerance);
|
}
|
|
/// <summary>
|
/// 判断点是否在点附近
|
/// </summary>
|
/// <param name="pt1"></param>
|
/// <param name="pt2"></param>
|
/// <param name="tolerance"></param>
|
/// <returns></returns>
|
public static bool IsPointNearPoint(HPoint pt1, HPoint pt2, double tolerance = 100)
|
{
|
if (GetDistanceP2P(pt1, pt2) <= tolerance)
|
return true;
|
return false;
|
}
|
|
public static bool IsPointNearPoint(Point pt1, Point pt2, double tolerance = 100)
|
{
|
if (GetDistanceP2P(pt1, pt2) <= tolerance)
|
return true;
|
return false;
|
}
|
|
public static bool IsPointNearPoint(double x1, double y1, double x2, double y2, int tolerance = 100)
|
{
|
return IsPointNearPoint(new HPoint(x1, y1), new HPoint(x2, y2), tolerance);
|
}
|
|
/// <summary>
|
/// 判断点是否在矩形角上
|
/// </summary>
|
/// <param name="pt"></param>
|
/// <param name="rect"></param>
|
/// <param name="corner"></param>
|
/// <param name="tolerance"></param>
|
/// <returns></returns>
|
public static bool IsPointNearRectangleCorner(Point pt, Rectangle rect, out string corner, double tolerance = 10)
|
{
|
try
|
{
|
//按顺时针去匹配角位
|
Point LeftTopPoint = new Point(rect.Left, rect.Top);
|
if (IsPointNearPoint(LeftTopPoint, pt, tolerance))
|
{
|
corner = "LeftTop";
|
return true;
|
}
|
|
Point RightTopPoint = new Point(rect.Right, rect.Top);
|
if (IsPointNearPoint(RightTopPoint, pt, tolerance))
|
{
|
corner = "RightTop";
|
return true;
|
}
|
|
Point RightBtmPoint = new Point(rect.Right, rect.Bottom);
|
if (IsPointNearPoint(RightBtmPoint, pt, tolerance))
|
{
|
corner = "RightBtm";
|
return true;
|
}
|
|
Point LeftBtmPoint = new Point(rect.Left, rect.Bottom);
|
if (IsPointNearPoint(LeftBtmPoint, pt, tolerance))
|
{
|
corner = "LeftBtm";
|
return true;
|
}
|
|
corner = "";
|
return false;
|
}
|
catch { corner = ""; return false; }
|
}
|
|
public static bool IsPointNearRectangleCorner(HPoint pt, HRectangle2 rect, out string corner, double tolerance = 10)
|
{
|
try
|
{
|
//按顺时针去匹配角位
|
var rectCorners = rect.Corners;
|
HPoint LeftTopPoint = rectCorners[0];
|
if (IsPointNearPoint(LeftTopPoint, pt, tolerance))
|
{
|
corner = "LeftTop";
|
return true;
|
}
|
|
HPoint RightTopPoint = rectCorners[1];
|
if (IsPointNearPoint(RightTopPoint, pt, tolerance))
|
{
|
corner = "RightTop";
|
return true;
|
}
|
|
HPoint RightBtmPoint = rectCorners[2];
|
if (IsPointNearPoint(RightBtmPoint, pt, tolerance))
|
{
|
corner = "RightBtm";
|
return true;
|
}
|
|
HPoint LeftBtmPoint = rectCorners[3];
|
if (IsPointNearPoint(LeftBtmPoint, pt, tolerance))
|
{
|
corner = "LeftBtm";
|
return true;
|
}
|
|
corner = "";
|
return false;
|
}
|
catch { corner = ""; return false; }
|
}
|
|
/// <summary>
|
/// 计算两线的交点
|
/// </summary>
|
/// <param name="p1">线1起始点</param>
|
/// <param name="p2"></param>
|
/// <param name="p3">线2起始点</param>
|
/// <param name="p4"></param>
|
/// <returns></returns>
|
public static Point2d? GetLineIntersection(Point2d p1, Point2d p2, Point2d p3, Point2d p4, bool bOnSegment = false)
|
{
|
// 直线1的向量
|
double x1 = p1.X, y1 = p1.Y;
|
double x2 = p2.X, y2 = p2.Y;
|
|
// 直线2的向量
|
double x3 = p3.X, y3 = p3.Y;
|
double x4 = p4.X, y4 = p4.Y;
|
|
// 计算分母
|
double denominator = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
|
|
// 如果分母为0,说明两线平行或重合
|
if (denominator == 0)
|
return null;
|
|
// 计算ua和ub
|
double ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denominator;
|
double ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denominator;
|
|
//如果ua和ub在0和1之间,说明交点在两条线段上
|
if (bOnSegment && !(ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1))
|
return null; // 交点不在线段上
|
|
|
// 计算交点坐标
|
double x = x1 + ua * (x2 - x1);
|
double y = y1 + ua * (y2 - y1);
|
|
return new Point2d(x, y);
|
}
|
#endregion
|
|
#region Halcon
|
// Chapter: Graphics / Output
|
// Short Description: Display 3D object models
|
public static void visualize_object_model_3d(HTuple hv_WindowHandle, HTuple hv_ObjectModel3D,
|
HTuple hv_CamParam, HTuple hv_PoseIn, HTuple hv_GenParamName, HTuple hv_GenParamValue,
|
HTuple hv_Title, HTuple hv_Label, HTuple hv_Information, out HTuple hv_PoseOut)
|
{
|
// Local iconic variables
|
|
HObject ho_Image = null, ho_ImageDump = null;
|
|
// Local control variables
|
|
HTuple ExpTmpLocalVar_gDispObjOffset = new HTuple();
|
HTuple ExpTmpLocalVar_gLabelsDecor = new HTuple(), ExpTmpLocalVar_gInfoDecor = new HTuple();
|
HTuple ExpTmpLocalVar_gInfoPos = new HTuple(), ExpTmpLocalVar_gTitlePos = new HTuple();
|
HTuple ExpTmpLocalVar_gTitleDecor = new HTuple(), ExpTmpLocalVar_gTerminationButtonLabel = new HTuple();
|
HTuple ExpTmpLocalVar_gAlphaDeselected = new HTuple();
|
HTuple ExpTmpLocalVar_gIsSinglePose = new HTuple(), ExpTmpLocalVar_gUsesOpenGL = new HTuple();
|
HTuple hv_Scene3DTest = new HTuple(), hv_Scene3D = new HTuple();
|
HTuple hv_WindowHandleBuffer = new HTuple(), hv_TrackballSize = new HTuple();
|
HTuple hv_VirtualTrackball = new HTuple(), hv_MouseMapping = new HTuple();
|
HTuple hv_WaitForButtonRelease = new HTuple(), hv_MaxNumModels = new HTuple();
|
HTuple hv_WindowCenteredRotation = new HTuple(), hv_NumModels = new HTuple();
|
HTuple hv_SelectedObject = new HTuple(), hv_ClipRegion = new HTuple();
|
HTuple hv_CPLength = new HTuple(), hv_RowNotUsed = new HTuple();
|
HTuple hv_ColumnNotUsed = new HTuple(), hv_Width = new HTuple();
|
HTuple hv_Height = new HTuple(), hv_WPRow1 = new HTuple();
|
HTuple hv_WPColumn1 = new HTuple(), hv_WPRow2 = new HTuple();
|
HTuple hv_WPColumn2 = new HTuple(), hv_CamParamValue = new HTuple();
|
HTuple hv_CamWidth = new HTuple(), hv_CamHeight = new HTuple();
|
HTuple hv_Scale = new HTuple(), hv_Indices = new HTuple();
|
HTuple hv_DispBackground = new HTuple(), hv_Mask = new HTuple();
|
HTuple hv_Center = new HTuple(), hv_PoseEstimated = new HTuple();
|
HTuple hv_Poses = new HTuple(), hv_HomMat3Ds = new HTuple();
|
HTuple hv_Sequence = new HTuple(), hv_Font = new HTuple();
|
HTuple hv_Exception = new HTuple(), hv_OpenGLInfo = new HTuple();
|
HTuple hv_DummyObjectModel3D = new HTuple(), hv_CameraIndexTest = new HTuple();
|
HTuple hv_PoseTest = new HTuple(), hv_InstanceIndexTest = new HTuple();
|
HTuple hv_MinImageSize = new HTuple(), hv_TrackballRadiusPixel = new HTuple();
|
HTuple hv_Ascent = new HTuple(), hv_Descent = new HTuple();
|
HTuple hv_TextWidth = new HTuple(), hv_TextHeight = new HTuple();
|
HTuple hv_NumChannels = new HTuple(), hv_ColorImage = new HTuple();
|
HTuple hv_CameraIndex = new HTuple(), hv_AllInstances = new HTuple();
|
HTuple hv_SetLight = new HTuple(), hv_LightParam = new HTuple();
|
HTuple hv_LightPosition = new HTuple(), hv_LightKind = new HTuple();
|
HTuple hv_LightIndex = new HTuple(), hv_PersistenceParamName = new HTuple();
|
HTuple hv_PersistenceParamValue = new HTuple(), hv_AlphaOrig = new HTuple();
|
HTuple hv_I = new HTuple(), hv_ParamName = new HTuple();
|
HTuple hv_ParamValue = new HTuple(), hv_ParamNameTrunk = new HTuple();
|
HTuple hv_Instance = new HTuple(), hv_HomMat3D = new HTuple();
|
HTuple hv_Qx = new HTuple(), hv_Qy = new HTuple(), hv_Qz = new HTuple();
|
HTuple hv_TBCenter = new HTuple(), hv_TBSize = new HTuple();
|
HTuple hv_ButtonHold = new HTuple(), hv_VisualizeTB = new HTuple();
|
HTuple hv_MaxIndex = new HTuple(), hv_TrackballCenterRow = new HTuple();
|
HTuple hv_TrackballCenterCol = new HTuple(), hv_GraphEvent = new HTuple();
|
HTuple hv_Exit = new HTuple(), hv_GraphButtonRow = new HTuple();
|
HTuple hv_GraphButtonColumn = new HTuple(), hv_GraphButton = new HTuple();
|
HTuple hv_ButtonReleased = new HTuple(), hv_e = new HTuple();
|
HTuple hv_CamParam_COPY_INP_TMP = new HTuple(hv_CamParam);
|
HTuple hv_GenParamName_COPY_INP_TMP = new HTuple(hv_GenParamName);
|
HTuple hv_GenParamValue_COPY_INP_TMP = new HTuple(hv_GenParamValue);
|
HTuple hv_Label_COPY_INP_TMP = new HTuple(hv_Label);
|
HTuple hv_PoseIn_COPY_INP_TMP = new HTuple(hv_PoseIn);
|
|
// Initialize local and output iconic variables
|
HOperatorSet.GenEmptyObj(out ho_Image);
|
HOperatorSet.GenEmptyObj(out ho_ImageDump);
|
hv_PoseOut = new HTuple();
|
try
|
{
|
//The procedure visualize_object_model_3d can be used to display
|
//one or more 3d object models and to interactively modify
|
//the object poses by using the mouse.
|
//
|
//The pose can be modified by moving the mouse while
|
//pressing a mouse button. The default settings are:
|
//
|
// Rotate: Left mouse button
|
// Zoom: Shift + Left mouse button (or Center mouse button)
|
// Pan: Ctrl + Left mouse button
|
//
|
//Furthermore, it is possible to select and deselect objects,
|
//to decrease the mouse sensitivity, and to toggle the
|
//inspection mode (see the description of the generic parameter
|
//'inspection_mode' below):
|
//
|
// (De-)select object(s): Right mouse button
|
// Low mouse sensitivity: Alt + mouse button
|
// Toggle inspection mode: Ctrl + Alt + Left mouse button
|
//
|
//In GenParamName and GenParamValue all generic Parameters
|
//of disp_object_model_3d are supported.
|
//
|
//**********************************************************
|
//Define global variables
|
//**********************************************************
|
//
|
//global def tuple gDispObjOffset
|
//global def tuple gLabelsDecor
|
//global def tuple gInfoDecor
|
//global def tuple gInfoPos
|
//global def tuple gTitlePos
|
//global def tuple gTitleDecor
|
//global def tuple gTerminationButtonLabel
|
//global def tuple gAlphaDeselected
|
//global def tuple gIsSinglePose
|
//global def tuple gUsesOpenGL
|
//
|
//**********************************************************
|
//Initialize Handles to enable correct handling in error case
|
//**********************************************************
|
hv_Scene3DTest.Dispose();
|
hv_Scene3DTest = new HTuple();
|
hv_Scene3D.Dispose();
|
hv_Scene3D = new HTuple();
|
hv_WindowHandleBuffer.Dispose();
|
hv_WindowHandleBuffer = new HTuple();
|
|
//**********************************************************
|
//Some user defines that may be adapted if desired
|
//**********************************************************
|
//
|
//TrackballSize defines the diameter of the trackball in
|
//the image with respect to the smaller image dimension.
|
hv_TrackballSize.Dispose();
|
hv_TrackballSize = 0.8;
|
//
|
//VirtualTrackball defines the type of virtual trackball that
|
//shall be used ('shoemake' or 'bell').
|
hv_VirtualTrackball.Dispose();
|
hv_VirtualTrackball = "shoemake";
|
//VirtualTrackball := 'bell'
|
//
|
//Functionality of mouse buttons
|
// 1: Left mouse button
|
// 2: Middle mouse button
|
// 4: Right mouse button
|
// 5: Left+Right mouse button
|
// 8+x: Shift + mouse button
|
// 16+x: Ctrl + mouse button
|
// 48+x: Ctrl + Alt + mouse button
|
//in the order [Translate, Rotate, Scale, ScaleAlternative1, ScaleAlternative2, SelectObjects, ToggleSelectionMode]
|
hv_MouseMapping.Dispose();
|
hv_MouseMapping = new HTuple();
|
hv_MouseMapping[0] = 17;
|
hv_MouseMapping[1] = 1;
|
hv_MouseMapping[2] = 2;
|
hv_MouseMapping[3] = 5;
|
hv_MouseMapping[4] = 9;
|
hv_MouseMapping[5] = 4;
|
hv_MouseMapping[6] = 49;
|
//
|
//The labels of the objects appear next to their projected
|
//center. With gDispObjOffset a fixed offset is added
|
// R, C
|
ExpTmpLocalVar_gDispObjOffset = new HTuple();
|
ExpTmpLocalVar_gDispObjOffset[0] = -30;
|
ExpTmpLocalVar_gDispObjOffset[1] = 0;
|
HDevelopExport.ExpSetGlobalVar_gDispObjOffset(ExpTmpLocalVar_gDispObjOffset);
|
//
|
//Customize the decoration of the different text elements
|
// Color, Box
|
ExpTmpLocalVar_gInfoDecor = new HTuple();
|
ExpTmpLocalVar_gInfoDecor[0] = "white";
|
ExpTmpLocalVar_gInfoDecor[1] = "false";
|
HDevelopExport.ExpSetGlobalVar_gInfoDecor(ExpTmpLocalVar_gInfoDecor);
|
ExpTmpLocalVar_gLabelsDecor = new HTuple();
|
ExpTmpLocalVar_gLabelsDecor[0] = "white";
|
ExpTmpLocalVar_gLabelsDecor[1] = "false";
|
HDevelopExport.ExpSetGlobalVar_gLabelsDecor(ExpTmpLocalVar_gLabelsDecor);
|
ExpTmpLocalVar_gTitleDecor = new HTuple();
|
ExpTmpLocalVar_gTitleDecor[0] = "black";
|
ExpTmpLocalVar_gTitleDecor[1] = "true";
|
HDevelopExport.ExpSetGlobalVar_gTitleDecor(ExpTmpLocalVar_gTitleDecor);
|
//
|
//Customize the position of some text elements
|
// gInfoPos has one of the values
|
// {'UpperLeft', 'LowerLeft', 'UpperRight'}
|
ExpTmpLocalVar_gInfoPos = "LowerLeft";
|
HDevelopExport.ExpSetGlobalVar_gInfoPos(ExpTmpLocalVar_gInfoPos);
|
// gTitlePos has one of the values
|
// {'UpperLeft', 'UpperCenter', 'UpperRight'}
|
ExpTmpLocalVar_gTitlePos = "UpperLeft";
|
HDevelopExport.ExpSetGlobalVar_gTitlePos(ExpTmpLocalVar_gTitlePos);
|
//Alpha value (=1-transparency) that is used for visualizing
|
//the objects that are not selected
|
ExpTmpLocalVar_gAlphaDeselected = 0.3;
|
HDevelopExport.ExpSetGlobalVar_gAlphaDeselected(ExpTmpLocalVar_gAlphaDeselected);
|
//Customize the label of the continue button
|
ExpTmpLocalVar_gTerminationButtonLabel = " Continue ";
|
HDevelopExport.ExpSetGlobalVar_gTerminationButtonLabel(ExpTmpLocalVar_gTerminationButtonLabel);
|
//Define if the continue button responds to a single click event or
|
//if it responds only if the mouse button is released while being placed
|
//over the continue button.
|
//'true': Wait until the continue button has been released.
|
// This should be used to avoid unwanted continuations of
|
// subsequent calls of visualize_object_model_3d, which can
|
// otherwise occur if the mouse button remains pressed while the
|
// next visualization is active.
|
//'false': Continue the execution already if the continue button is
|
// pressed. This option allows a fast forwarding through
|
// subsequent calls of visualize_object_model_3d.
|
hv_WaitForButtonRelease.Dispose();
|
hv_WaitForButtonRelease = "true";
|
//Number of 3D Object models that can be selected and handled individually.
|
//If there are more models passed then this number, some calculations
|
//are performed differently and the individual selection and handling
|
//of models is not supported anymore. Note that the value of MaxNumModels
|
//can be overwritten with the generic parameter max_num_selectable_models.
|
hv_MaxNumModels.Dispose();
|
hv_MaxNumModels = 1000;
|
//Defines the default for the initial state of the rotation center:
|
//(1) The rotation center is fixed in the center of the image and lies
|
// on the surface of the object.
|
//(2) The rotation center lies in the center of the object.
|
hv_WindowCenteredRotation.Dispose();
|
hv_WindowCenteredRotation = 2;
|
//
|
//**********************************************************
|
//
|
//Initialize some values
|
hv_NumModels.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_NumModels = new HTuple(hv_ObjectModel3D.TupleLength()
|
);
|
}
|
hv_SelectedObject.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_SelectedObject = HTuple.TupleGenConst(
|
hv_NumModels, 1);
|
}
|
//
|
//Apply some system settings
|
// dev_get_preferences(...); only in hdevelop
|
// dev_set_preferences(...); only in hdevelop
|
// dev_get_preferences(...); only in hdevelop
|
// dev_set_preferences(...); only in hdevelop
|
hv_ClipRegion.Dispose();
|
HOperatorSet.GetSystem("clip_region", out hv_ClipRegion);
|
HOperatorSet.SetSystem("clip_region", "false");
|
HDevelopExport.dev_update_off();
|
//
|
//Check if GenParamName matches GenParamValue
|
if ((int)new HTuple(new HTuple(hv_GenParamName_COPY_INP_TMP.TupleLength()
|
).TupleNotEqual(new HTuple(hv_GenParamValue_COPY_INP_TMP.TupleLength()
|
))) != 0)
|
{
|
throw new HalconException("Number of generic parameters does not match number of generic parameter values");
|
}
|
//
|
try
|
{
|
//
|
//Refactor camera parameters to fit to window size
|
//
|
hv_CPLength.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_CPLength = new HTuple(hv_CamParam_COPY_INP_TMP.TupleLength()
|
);
|
}
|
hv_RowNotUsed.Dispose(); hv_ColumnNotUsed.Dispose(); hv_Width.Dispose(); hv_Height.Dispose();
|
HOperatorSet.GetWindowExtents(hv_WindowHandle, out hv_RowNotUsed, out hv_ColumnNotUsed,
|
out hv_Width, out hv_Height);
|
hv_WPRow1.Dispose(); hv_WPColumn1.Dispose(); hv_WPRow2.Dispose(); hv_WPColumn2.Dispose();
|
HOperatorSet.GetPart(hv_WindowHandle, out hv_WPRow1, out hv_WPColumn1, out hv_WPRow2,
|
out hv_WPColumn2);
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
HOperatorSet.SetPart(hv_WindowHandle, 0, 0, hv_Height - 1, hv_Width - 1);
|
}
|
if ((int)new HTuple(hv_CPLength.TupleEqual(0)) != 0)
|
{
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_CamParam_COPY_INP_TMP.Dispose();
|
HDevelopExport.gen_cam_par_area_scan_division(0.06, 0, 8.5e-6, 8.5e-6, hv_Width / 2, hv_Height / 2,
|
hv_Width, hv_Height, out hv_CamParam_COPY_INP_TMP);
|
}
|
}
|
else
|
{
|
hv_CamParamValue.Dispose();
|
HDevelopExport.get_cam_par_data(hv_CamParam_COPY_INP_TMP, new HTuple("sx").TupleConcat(
|
"sy").TupleConcat("cx").TupleConcat("cy").TupleConcat("image_width").TupleConcat(
|
"image_height"), out hv_CamParamValue);
|
hv_CamWidth.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_CamWidth = hv_CamParamValue.TupleSelect(
|
4).TupleReal();
|
}
|
hv_CamHeight.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_CamHeight = hv_CamParamValue.TupleSelect(
|
5).TupleReal();
|
}
|
hv_Scale.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Scale = (hv_Width / hv_CamWidth).TupleConcat(
|
hv_Height / hv_CamHeight).TupleMin();
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
HTuple ExpTmpOutVar_0;
|
set_cam_par_data(hv_CamParam_COPY_INP_TMP, "sx", hv_CamParamValue.TupleSelect(
|
0) / hv_Scale, out ExpTmpOutVar_0);
|
hv_CamParam_COPY_INP_TMP.Dispose();
|
hv_CamParam_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
HTuple ExpTmpOutVar_0;
|
set_cam_par_data(hv_CamParam_COPY_INP_TMP, "sy", hv_CamParamValue.TupleSelect(
|
1) / hv_Scale, out ExpTmpOutVar_0);
|
hv_CamParam_COPY_INP_TMP.Dispose();
|
hv_CamParam_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
HTuple ExpTmpOutVar_0;
|
set_cam_par_data(hv_CamParam_COPY_INP_TMP, "cx", hv_CamParamValue.TupleSelect(
|
2) * hv_Scale, out ExpTmpOutVar_0);
|
hv_CamParam_COPY_INP_TMP.Dispose();
|
hv_CamParam_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
HTuple ExpTmpOutVar_0;
|
set_cam_par_data(hv_CamParam_COPY_INP_TMP, "cy", hv_CamParamValue.TupleSelect(
|
3) * hv_Scale, out ExpTmpOutVar_0);
|
hv_CamParam_COPY_INP_TMP.Dispose();
|
hv_CamParam_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
HTuple ExpTmpOutVar_0;
|
set_cam_par_data(hv_CamParam_COPY_INP_TMP, "image_width", (hv_CamParamValue.TupleSelect(
|
4) * hv_Scale).TupleInt(), out ExpTmpOutVar_0);
|
hv_CamParam_COPY_INP_TMP.Dispose();
|
hv_CamParam_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
HTuple ExpTmpOutVar_0;
|
set_cam_par_data(hv_CamParam_COPY_INP_TMP, "image_height", (hv_CamParamValue.TupleSelect(
|
5) * hv_Scale).TupleInt(), out ExpTmpOutVar_0);
|
hv_CamParam_COPY_INP_TMP.Dispose();
|
hv_CamParam_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
}
|
//
|
//Check the generic parameters for max_num_selectable_models
|
//(Note that the default is set above to MaxNumModels := 1000)
|
hv_Indices.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Indices = hv_GenParamName_COPY_INP_TMP.TupleFind(
|
"max_num_selectable_models");
|
}
|
if ((int)new HTuple(hv_Indices.TupleNotEqual(-1)).TupleAnd(new HTuple(hv_Indices.TupleNotEqual(
|
new HTuple()))) != 0)
|
{
|
if ((int)hv_GenParamValue_COPY_INP_TMP.TupleSelect(hv_Indices.TupleSelect(
|
0)).TupleIsNumber() != 0)
|
{
|
if ((int)new HTuple(hv_GenParamValue_COPY_INP_TMP.TupleSelect(
|
hv_Indices.TupleSelect(0)).TupleNumber().TupleInt().TupleLess(
|
1)) != 0)
|
{
|
//Wrong parameter value: Only integer values greater than 0 are allowed
|
throw new HalconException("Wrong value for parameter 'max_num_selectable_models' (must be an integer value greater than 0)");
|
}
|
}
|
else
|
{
|
//Wrong parameter value: Only integer values greater than 0 are allowed
|
throw new HalconException("Wrong value for parameter 'max_num_selectable_models' (must be an integer value greater than 0)");
|
}
|
hv_MaxNumModels.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_MaxNumModels = hv_GenParamValue_COPY_INP_TMP.TupleSelect(
|
hv_Indices.TupleSelect(0)).TupleNumber().TupleInt();
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamName = hv_GenParamName_COPY_INP_TMP.TupleRemove(
|
hv_Indices);
|
hv_GenParamName_COPY_INP_TMP.Dispose();
|
hv_GenParamName_COPY_INP_TMP = ExpTmpLocalVar_GenParamName;
|
}
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamValue = hv_GenParamValue_COPY_INP_TMP.TupleRemove(
|
hv_Indices);
|
hv_GenParamValue_COPY_INP_TMP.Dispose();
|
hv_GenParamValue_COPY_INP_TMP = ExpTmpLocalVar_GenParamValue;
|
}
|
}
|
}
|
//
|
//Check the generic parameters for window_centered_rotation
|
//(Note that the default is set above to WindowCenteredRotation := 2)
|
hv_Indices.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Indices = hv_GenParamName_COPY_INP_TMP.TupleFind(
|
"inspection_mode");
|
}
|
if ((int)new HTuple(hv_Indices.TupleNotEqual(-1)).TupleAnd(new HTuple(hv_Indices.TupleNotEqual(
|
new HTuple()))) != 0)
|
{
|
if ((int)new HTuple(hv_GenParamValue_COPY_INP_TMP.TupleSelect(hv_Indices.TupleSelect(
|
0)).TupleEqual("surface")) != 0)
|
{
|
hv_WindowCenteredRotation.Dispose();
|
hv_WindowCenteredRotation = 1;
|
}
|
else if ((int)new HTuple(hv_GenParamValue_COPY_INP_TMP.TupleSelect(
|
hv_Indices.TupleSelect(0)).TupleEqual("standard")) != 0)
|
{
|
hv_WindowCenteredRotation.Dispose();
|
hv_WindowCenteredRotation = 2;
|
}
|
else
|
{
|
//Wrong parameter value, use default value
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamName = hv_GenParamName_COPY_INP_TMP.TupleRemove(
|
hv_Indices);
|
hv_GenParamName_COPY_INP_TMP.Dispose();
|
hv_GenParamName_COPY_INP_TMP = ExpTmpLocalVar_GenParamName;
|
}
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamValue = hv_GenParamValue_COPY_INP_TMP.TupleRemove(
|
hv_Indices);
|
hv_GenParamValue_COPY_INP_TMP.Dispose();
|
hv_GenParamValue_COPY_INP_TMP = ExpTmpLocalVar_GenParamValue;
|
}
|
}
|
}
|
//
|
//Check the generic parameters for disp_background
|
//(The former parameter name 'use_background' is still supported
|
// for compatibility reasons)
|
hv_DispBackground.Dispose();
|
hv_DispBackground = "false";
|
if ((int)new HTuple(new HTuple(hv_GenParamName_COPY_INP_TMP.TupleLength()
|
).TupleGreater(0)) != 0)
|
{
|
hv_Mask.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Mask = hv_GenParamName_COPY_INP_TMP.TupleEqualElem(
|
"disp_background").TupleOr(hv_GenParamName_COPY_INP_TMP.TupleEqualElem(
|
"use_background"));
|
}
|
hv_Indices.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Indices = hv_Mask.TupleFind(
|
1);
|
}
|
}
|
else
|
{
|
hv_Indices.Dispose();
|
hv_Indices = -1;
|
}
|
if ((int)new HTuple(hv_Indices.TupleNotEqual(-1)).TupleAnd(new HTuple(hv_Indices.TupleNotEqual(
|
new HTuple()))) != 0)
|
{
|
hv_DispBackground.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_DispBackground = hv_GenParamValue_COPY_INP_TMP.TupleSelect(
|
hv_Indices.TupleSelect(0));
|
}
|
if ((int)new HTuple(hv_DispBackground.TupleNotEqual("true")).TupleAnd(
|
new HTuple(hv_DispBackground.TupleNotEqual("false"))) != 0)
|
{
|
//Wrong parameter value: Only 'true' and 'false' are allowed
|
throw new HalconException("Wrong value for parameter 'disp_background' (must be either 'true' or 'false')");
|
}
|
//Note that the background is handled explicitly in this procedure
|
//and therefore, the parameter is removed from the list of
|
//parameters and disp_background is always set to true (see below)
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamName = hv_GenParamName_COPY_INP_TMP.TupleRemove(
|
hv_Indices);
|
hv_GenParamName_COPY_INP_TMP.Dispose();
|
hv_GenParamName_COPY_INP_TMP = ExpTmpLocalVar_GenParamName;
|
}
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamValue = hv_GenParamValue_COPY_INP_TMP.TupleRemove(
|
hv_Indices);
|
hv_GenParamValue_COPY_INP_TMP.Dispose();
|
hv_GenParamValue_COPY_INP_TMP = ExpTmpLocalVar_GenParamValue;
|
}
|
}
|
}
|
//
|
//Read and check the parameter Label for each object
|
if ((int)new HTuple(new HTuple(hv_Label_COPY_INP_TMP.TupleLength()).TupleEqual(
|
0)) != 0)
|
{
|
//no labels set -> leave as []
|
}
|
else if ((int)new HTuple(new HTuple(hv_Label_COPY_INP_TMP.TupleLength()
|
).TupleEqual(1)) != 0)
|
{
|
//a single label set for all models
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_Label = HTuple.TupleGenConst(
|
hv_NumModels, hv_Label_COPY_INP_TMP);
|
hv_Label_COPY_INP_TMP.Dispose();
|
hv_Label_COPY_INP_TMP = ExpTmpLocalVar_Label;
|
}
|
}
|
}
|
else
|
{
|
if ((int)new HTuple(new HTuple(hv_Label_COPY_INP_TMP.TupleLength()).TupleNotEqual(
|
hv_NumModels)) != 0)
|
{
|
//Number of elements in Label does not match
|
//the number of object models.
|
throw new HalconException(new HTuple(new HTuple("Number of elements in Label (") + new HTuple(hv_Label_COPY_INP_TMP.TupleLength()
|
)) + ") does not match the number of object models(" + hv_NumModels + ").");
|
}
|
}
|
//Convert labels into strings
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_Label = "" + hv_Label_COPY_INP_TMP;
|
hv_Label_COPY_INP_TMP.Dispose();
|
hv_Label_COPY_INP_TMP = ExpTmpLocalVar_Label;
|
}
|
}
|
//
|
//Read and check the parameter PoseIn for each object
|
hv_Center.Dispose();
|
HDevelopExport.get_object_models_center(hv_ObjectModel3D, out hv_Center);
|
if ((int)new HTuple(hv_Center.TupleEqual(new HTuple())) != 0)
|
{
|
hv_Center.Dispose();
|
hv_Center = new HTuple();
|
hv_Center[0] = 0;
|
hv_Center[1] = 0;
|
hv_Center[2] = 0;
|
}
|
if ((int)new HTuple(new HTuple(hv_PoseIn_COPY_INP_TMP.TupleLength()).TupleEqual(
|
0)) != 0)
|
{
|
//If no pose was specified by the caller, automatically calculate
|
//a pose that is appropriate for the visualization.
|
//Set the initial model reference pose. The orientation is parallel
|
//to the object coordinate system, the position is at the center
|
//of gravity of all models.
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_PoseIn_COPY_INP_TMP.Dispose();
|
HOperatorSet.CreatePose(-hv_Center.TupleSelect(0), -hv_Center.TupleSelect(
|
1), -hv_Center.TupleSelect(2), 0, 0, 0, "Rp+T", "gba", "point",
|
out hv_PoseIn_COPY_INP_TMP);
|
}
|
hv_PoseEstimated.Dispose();
|
HDevelopExport.determine_optimum_pose_distance(hv_ObjectModel3D, hv_CamParam_COPY_INP_TMP,
|
0.9, hv_PoseIn_COPY_INP_TMP, out hv_PoseEstimated);
|
hv_Poses.Dispose();
|
hv_Poses = new HTuple();
|
hv_HomMat3Ds.Dispose();
|
hv_HomMat3Ds = new HTuple();
|
hv_Sequence.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Sequence = HTuple.TupleGenSequence(
|
0, hv_NumModels * 7 - 1, 1);
|
}
|
hv_Poses.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Poses = hv_PoseEstimated.TupleSelect(
|
hv_Sequence % 7);
|
}
|
ExpTmpLocalVar_gIsSinglePose = 1;
|
HDevelopExport.ExpSetGlobalVar_gIsSinglePose(ExpTmpLocalVar_gIsSinglePose);
|
}
|
else if ((int)new HTuple(new HTuple(hv_PoseIn_COPY_INP_TMP.TupleLength()
|
).TupleEqual(7)) != 0)
|
{
|
hv_Poses.Dispose();
|
hv_Poses = new HTuple();
|
hv_HomMat3Ds.Dispose();
|
hv_HomMat3Ds = new HTuple();
|
hv_Sequence.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Sequence = HTuple.TupleGenSequence(
|
0, hv_NumModels * 7 - 1, 1);
|
}
|
hv_Poses.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Poses = hv_PoseIn_COPY_INP_TMP.TupleSelect(
|
hv_Sequence % 7);
|
}
|
ExpTmpLocalVar_gIsSinglePose = 1;
|
HDevelopExport.ExpSetGlobalVar_gIsSinglePose(ExpTmpLocalVar_gIsSinglePose);
|
}
|
else
|
{
|
if ((int)new HTuple(new HTuple(hv_PoseIn_COPY_INP_TMP.TupleLength()).TupleNotEqual(
|
new HTuple(hv_ObjectModel3D.TupleLength()) * 7)) != 0)
|
{
|
//Wrong number of values of input control parameter 'PoseIn'
|
throw new HalconException("Wrong number of values of input control parameter 'PoseIn'.");
|
}
|
else
|
{
|
hv_Poses.Dispose();
|
hv_Poses = new HTuple(hv_PoseIn_COPY_INP_TMP);
|
}
|
ExpTmpLocalVar_gIsSinglePose = 0;
|
HDevelopExport.ExpSetGlobalVar_gIsSinglePose(ExpTmpLocalVar_gIsSinglePose);
|
}
|
//
|
//Open (invisible) buffer window to avoid flickering
|
hv_WindowHandleBuffer.Dispose();
|
HOperatorSet.OpenWindow(0, 0, hv_Width, hv_Height, 0, "buffer", "", out hv_WindowHandleBuffer);
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
HOperatorSet.SetPart(hv_WindowHandleBuffer, 0, 0, hv_Height - 1, hv_Width - 1);
|
}
|
hv_Font.Dispose();
|
HOperatorSet.GetFont(hv_WindowHandle, out hv_Font);
|
try
|
{
|
HOperatorSet.SetFont(hv_WindowHandleBuffer, hv_Font);
|
}
|
// catch (Exception)
|
catch (HalconException HDevExpDefaultException2)
|
{
|
HDevExpDefaultException2.ToHTuple(out hv_Exception);
|
}
|
//
|
// Is OpenGL available and should it be used?
|
ExpTmpLocalVar_gUsesOpenGL = "true";
|
HDevelopExport.ExpSetGlobalVar_gUsesOpenGL(ExpTmpLocalVar_gUsesOpenGL);
|
hv_Indices.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Indices = hv_GenParamName_COPY_INP_TMP.TupleFind(
|
"opengl");
|
}
|
if ((int)new HTuple(hv_Indices.TupleNotEqual(-1)).TupleAnd(new HTuple(hv_Indices.TupleNotEqual(
|
new HTuple()))) != 0)
|
{
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
ExpTmpLocalVar_gUsesOpenGL = hv_GenParamValue_COPY_INP_TMP.TupleSelect(
|
hv_Indices.TupleSelect(0));
|
}
|
HDevelopExport.ExpSetGlobalVar_gUsesOpenGL(ExpTmpLocalVar_gUsesOpenGL);
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamName = hv_GenParamName_COPY_INP_TMP.TupleRemove(
|
hv_Indices);
|
hv_GenParamName_COPY_INP_TMP.Dispose();
|
hv_GenParamName_COPY_INP_TMP = ExpTmpLocalVar_GenParamName;
|
}
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamValue = hv_GenParamValue_COPY_INP_TMP.TupleRemove(
|
hv_Indices);
|
hv_GenParamValue_COPY_INP_TMP.Dispose();
|
hv_GenParamValue_COPY_INP_TMP = ExpTmpLocalVar_GenParamValue;
|
}
|
}
|
if ((int)new HTuple(HDevelopExport.ExpGetGlobalVar_gUsesOpenGL().TupleNotEqual("true")).TupleAnd(
|
new HTuple(HDevelopExport.ExpGetGlobalVar_gUsesOpenGL().TupleNotEqual("false"))) != 0)
|
{
|
//Wrong parameter value: Only 'true' and 'false' are allowed
|
throw new HalconException("Wrong value for parameter 'opengl' (must be either 'true' or 'false')");
|
}
|
}
|
if ((int)new HTuple(HDevelopExport.ExpGetGlobalVar_gUsesOpenGL().TupleEqual("true")) != 0)
|
{
|
hv_OpenGLInfo.Dispose();
|
HOperatorSet.GetSystem("opengl_info", out hv_OpenGLInfo);
|
if ((int)new HTuple(hv_OpenGLInfo.TupleEqual("No OpenGL support included.")) != 0)
|
{
|
ExpTmpLocalVar_gUsesOpenGL = "false";
|
HDevelopExport.ExpSetGlobalVar_gUsesOpenGL(ExpTmpLocalVar_gUsesOpenGL);
|
}
|
else
|
{
|
hv_DummyObjectModel3D.Dispose();
|
HOperatorSet.GenObjectModel3dFromPoints(0, 0, 0, out hv_DummyObjectModel3D);
|
hv_Scene3DTest.Dispose();
|
HOperatorSet.CreateScene3d(out hv_Scene3DTest);
|
hv_CameraIndexTest.Dispose();
|
HOperatorSet.AddScene3dCamera(hv_Scene3DTest, hv_CamParam_COPY_INP_TMP,
|
out hv_CameraIndexTest);
|
hv_PoseTest.Dispose();
|
HDevelopExport.determine_optimum_pose_distance(hv_DummyObjectModel3D, hv_CamParam_COPY_INP_TMP,
|
0.9, new HTuple(0).TupleConcat(0).TupleConcat(0).TupleConcat(
|
0).TupleConcat(0).TupleConcat(0).TupleConcat(0), out hv_PoseTest);
|
hv_InstanceIndexTest.Dispose();
|
HOperatorSet.AddScene3dInstance(hv_Scene3DTest, hv_DummyObjectModel3D,
|
hv_PoseTest, out hv_InstanceIndexTest);
|
try
|
{
|
HOperatorSet.DisplayScene3d(hv_WindowHandleBuffer, hv_Scene3DTest,
|
hv_InstanceIndexTest);
|
}
|
// catch (Exception)
|
catch (HalconException HDevExpDefaultException2)
|
{
|
HDevExpDefaultException2.ToHTuple(out hv_Exception);
|
ExpTmpLocalVar_gUsesOpenGL = "false";
|
HDevelopExport.ExpSetGlobalVar_gUsesOpenGL(ExpTmpLocalVar_gUsesOpenGL);
|
}
|
HOperatorSet.ClearScene3d(hv_Scene3DTest);
|
hv_Scene3DTest.Dispose();
|
hv_Scene3DTest = new HTuple();
|
HOperatorSet.ClearObjectModel3d(hv_DummyObjectModel3D);
|
}
|
}
|
//
|
//Compute the trackball
|
hv_MinImageSize.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_MinImageSize = hv_Width.TupleConcat(
|
hv_Height).TupleMin();
|
}
|
hv_TrackballRadiusPixel.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TrackballRadiusPixel = hv_TrackballSize * hv_MinImageSize / 2.0;
|
}
|
//
|
//Measure the text extents for the continue button in the
|
//graphics window
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Ascent.Dispose(); hv_Descent.Dispose(); hv_TextWidth.Dispose(); hv_TextHeight.Dispose();
|
HOperatorSet.GetStringExtents(hv_WindowHandleBuffer, HDevelopExport.ExpGetGlobalVar_gTerminationButtonLabel() + " ",
|
out hv_Ascent, out hv_Descent, out hv_TextWidth, out hv_TextHeight);
|
}
|
//
|
//Store background image
|
if ((int)new HTuple(hv_DispBackground.TupleEqual("false")) != 0)
|
{
|
HOperatorSet.ClearWindow(hv_WindowHandle);
|
}
|
ho_Image.Dispose();
|
HOperatorSet.DumpWindowImage(out ho_Image, hv_WindowHandle);
|
//Special treatment for color background images necessary
|
hv_NumChannels.Dispose();
|
HOperatorSet.CountChannels(ho_Image, out hv_NumChannels);
|
hv_ColorImage.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ColorImage = new HTuple(hv_NumChannels.TupleEqual(
|
3));
|
}
|
//
|
hv_Scene3D.Dispose();
|
HOperatorSet.CreateScene3d(out hv_Scene3D);
|
hv_CameraIndex.Dispose();
|
HOperatorSet.AddScene3dCamera(hv_Scene3D, hv_CamParam_COPY_INP_TMP, out hv_CameraIndex);
|
hv_AllInstances.Dispose();
|
HOperatorSet.AddScene3dInstance(hv_Scene3D, hv_ObjectModel3D, hv_Poses, out hv_AllInstances);
|
//Always set 'disp_background' to true, because it is handled explicitly
|
//in this procedure (see above)
|
HOperatorSet.SetScene3dParam(hv_Scene3D, "disp_background", "true");
|
//Check if we have to set light specific parameters
|
hv_SetLight.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_SetLight = new HTuple(hv_GenParamName_COPY_INP_TMP.TupleRegexpTest(
|
"light_"));
|
}
|
if ((int)hv_SetLight != 0)
|
{
|
//set position of light source
|
hv_Indices.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Indices = hv_GenParamName_COPY_INP_TMP.TupleFind(
|
"light_position");
|
}
|
if ((int)new HTuple(hv_Indices.TupleNotEqual(-1)).TupleAnd(new HTuple(hv_Indices.TupleNotEqual(
|
new HTuple()))) != 0)
|
{
|
//If multiple light positions are given, use the last one
|
hv_LightParam.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_LightParam = hv_GenParamValue_COPY_INP_TMP.TupleSelect(
|
hv_Indices.TupleSelect(new HTuple(hv_Indices.TupleLength()) - 1)).TupleSplit(
|
new HTuple(", ")).TupleNumber();
|
}
|
if ((int)new HTuple(new HTuple(hv_LightParam.TupleLength()).TupleNotEqual(
|
4)) != 0)
|
{
|
throw new HalconException("light_position must be given as a string that contains four space separated floating point numbers");
|
}
|
hv_LightPosition.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_LightPosition = hv_LightParam.TupleSelectRange(
|
0, 2);
|
}
|
hv_LightKind.Dispose();
|
hv_LightKind = "point_light";
|
if ((int)new HTuple(hv_LightParam.TupleSelect(3).TupleEqual(0)) != 0)
|
{
|
hv_LightKind.Dispose();
|
hv_LightKind = "directional_light";
|
}
|
//Currently, only one light source is supported
|
HOperatorSet.RemoveScene3dLight(hv_Scene3D, 0);
|
hv_LightIndex.Dispose();
|
HOperatorSet.AddScene3dLight(hv_Scene3D, hv_LightPosition, hv_LightKind,
|
out hv_LightIndex);
|
{
|
HTuple ExpTmpOutVar_0;
|
HOperatorSet.TupleRemove(hv_GenParamName_COPY_INP_TMP, hv_Indices, out ExpTmpOutVar_0);
|
hv_GenParamName_COPY_INP_TMP.Dispose();
|
hv_GenParamName_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
{
|
HTuple ExpTmpOutVar_0;
|
HOperatorSet.TupleRemove(hv_GenParamValue_COPY_INP_TMP, hv_Indices, out ExpTmpOutVar_0);
|
hv_GenParamValue_COPY_INP_TMP.Dispose();
|
hv_GenParamValue_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
}
|
//set ambient part of light source
|
hv_Indices.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Indices = hv_GenParamName_COPY_INP_TMP.TupleFind(
|
"light_ambient");
|
}
|
if ((int)new HTuple(hv_Indices.TupleNotEqual(-1)).TupleAnd(new HTuple(hv_Indices.TupleNotEqual(
|
new HTuple()))) != 0)
|
{
|
//If the ambient part is set multiple times, use the last setting
|
hv_LightParam.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_LightParam = hv_GenParamValue_COPY_INP_TMP.TupleSelect(
|
hv_Indices.TupleSelect(new HTuple(hv_Indices.TupleLength()) - 1)).TupleSplit(
|
new HTuple(", ")).TupleNumber();
|
}
|
if ((int)new HTuple(new HTuple(hv_LightParam.TupleLength()).TupleLess(
|
3)) != 0)
|
{
|
throw new HalconException("light_ambient must be given as a string that contains three space separated floating point numbers");
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
HOperatorSet.SetScene3dLightParam(hv_Scene3D, 0, "ambient", hv_LightParam.TupleSelectRange(
|
0, 2));
|
}
|
{
|
HTuple ExpTmpOutVar_0;
|
HOperatorSet.TupleRemove(hv_GenParamName_COPY_INP_TMP, hv_Indices, out ExpTmpOutVar_0);
|
hv_GenParamName_COPY_INP_TMP.Dispose();
|
hv_GenParamName_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
{
|
HTuple ExpTmpOutVar_0;
|
HOperatorSet.TupleRemove(hv_GenParamValue_COPY_INP_TMP, hv_Indices, out ExpTmpOutVar_0);
|
hv_GenParamValue_COPY_INP_TMP.Dispose();
|
hv_GenParamValue_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
}
|
//Set diffuse part of light source
|
hv_Indices.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Indices = hv_GenParamName_COPY_INP_TMP.TupleFind(
|
"light_diffuse");
|
}
|
if ((int)new HTuple(hv_Indices.TupleNotEqual(-1)).TupleAnd(new HTuple(hv_Indices.TupleNotEqual(
|
new HTuple()))) != 0)
|
{
|
//If the diffuse part is set multiple times, use the last setting
|
hv_LightParam.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_LightParam = hv_GenParamValue_COPY_INP_TMP.TupleSelect(
|
hv_Indices.TupleSelect(new HTuple(hv_Indices.TupleLength()) - 1)).TupleSplit(
|
new HTuple(", ")).TupleNumber();
|
}
|
if ((int)new HTuple(new HTuple(hv_LightParam.TupleLength()).TupleLess(
|
3)) != 0)
|
{
|
throw new HalconException("light_diffuse must be given as a string that contains three space separated floating point numbers");
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
HOperatorSet.SetScene3dLightParam(hv_Scene3D, 0, "diffuse", hv_LightParam.TupleSelectRange(
|
0, 2));
|
}
|
{
|
HTuple ExpTmpOutVar_0;
|
HOperatorSet.TupleRemove(hv_GenParamName_COPY_INP_TMP, hv_Indices, out ExpTmpOutVar_0);
|
hv_GenParamName_COPY_INP_TMP.Dispose();
|
hv_GenParamName_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
{
|
HTuple ExpTmpOutVar_0;
|
HOperatorSet.TupleRemove(hv_GenParamValue_COPY_INP_TMP, hv_Indices, out ExpTmpOutVar_0);
|
hv_GenParamValue_COPY_INP_TMP.Dispose();
|
hv_GenParamValue_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
}
|
}
|
//
|
//Handle persistence parameters separately because persistence will
|
//only be activated immediately before leaving the visualization
|
//procedure
|
hv_PersistenceParamName.Dispose();
|
hv_PersistenceParamName = new HTuple();
|
hv_PersistenceParamValue.Dispose();
|
hv_PersistenceParamValue = new HTuple();
|
//Set position of light source
|
hv_Indices.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Indices = hv_GenParamName_COPY_INP_TMP.TupleFind(
|
"object_index_persistence");
|
}
|
if ((int)new HTuple(hv_Indices.TupleNotEqual(-1)).TupleAnd(new HTuple(hv_Indices.TupleNotEqual(
|
new HTuple()))) != 0)
|
{
|
if ((int)new HTuple(hv_GenParamValue_COPY_INP_TMP.TupleSelect(hv_Indices.TupleSelect(
|
new HTuple(hv_Indices.TupleLength()) - 1)).TupleEqual("true")) != 0)
|
{
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_PersistenceParamName = hv_PersistenceParamName.TupleConcat(
|
"object_index_persistence");
|
hv_PersistenceParamName.Dispose();
|
hv_PersistenceParamName = ExpTmpLocalVar_PersistenceParamName;
|
}
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_PersistenceParamValue = hv_PersistenceParamValue.TupleConcat(
|
"true");
|
hv_PersistenceParamValue.Dispose();
|
hv_PersistenceParamValue = ExpTmpLocalVar_PersistenceParamValue;
|
}
|
}
|
}
|
else if ((int)new HTuple(hv_GenParamValue_COPY_INP_TMP.TupleSelect(
|
hv_Indices.TupleSelect(new HTuple(hv_Indices.TupleLength()) - 1)).TupleEqual(
|
"false")) != 0)
|
{
|
}
|
else
|
{
|
throw new HalconException("Wrong value for parameter 'object_index_persistence' (must be either 'true' or 'false')");
|
}
|
{
|
HTuple ExpTmpOutVar_0;
|
HOperatorSet.TupleRemove(hv_GenParamName_COPY_INP_TMP, hv_Indices, out ExpTmpOutVar_0);
|
hv_GenParamName_COPY_INP_TMP.Dispose();
|
hv_GenParamName_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
{
|
HTuple ExpTmpOutVar_0;
|
HOperatorSet.TupleRemove(hv_GenParamValue_COPY_INP_TMP, hv_Indices, out ExpTmpOutVar_0);
|
hv_GenParamValue_COPY_INP_TMP.Dispose();
|
hv_GenParamValue_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
}
|
hv_Indices.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Indices = hv_GenParamName_COPY_INP_TMP.TupleFind(
|
"depth_persistence");
|
}
|
if ((int)new HTuple(hv_Indices.TupleNotEqual(-1)).TupleAnd(new HTuple(hv_Indices.TupleNotEqual(
|
new HTuple()))) != 0)
|
{
|
if ((int)new HTuple(hv_GenParamValue_COPY_INP_TMP.TupleSelect(hv_Indices.TupleSelect(
|
new HTuple(hv_Indices.TupleLength()) - 1)).TupleEqual("true")) != 0)
|
{
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_PersistenceParamName = hv_PersistenceParamName.TupleConcat(
|
"depth_persistence");
|
hv_PersistenceParamName.Dispose();
|
hv_PersistenceParamName = ExpTmpLocalVar_PersistenceParamName;
|
}
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_PersistenceParamValue = hv_PersistenceParamValue.TupleConcat(
|
"true");
|
hv_PersistenceParamValue.Dispose();
|
hv_PersistenceParamValue = ExpTmpLocalVar_PersistenceParamValue;
|
}
|
}
|
}
|
else if ((int)new HTuple(hv_GenParamValue_COPY_INP_TMP.TupleSelect(
|
hv_Indices.TupleSelect(new HTuple(hv_Indices.TupleLength()) - 1)).TupleEqual(
|
"false")) != 0)
|
{
|
}
|
else
|
{
|
throw new HalconException("Wrong value for parameter 'depth_persistence' (must be either 'true' or 'false')");
|
}
|
{
|
HTuple ExpTmpOutVar_0;
|
HOperatorSet.TupleRemove(hv_GenParamName_COPY_INP_TMP, hv_Indices, out ExpTmpOutVar_0);
|
hv_GenParamName_COPY_INP_TMP.Dispose();
|
hv_GenParamName_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
{
|
HTuple ExpTmpOutVar_0;
|
HOperatorSet.TupleRemove(hv_GenParamValue_COPY_INP_TMP, hv_Indices, out ExpTmpOutVar_0);
|
hv_GenParamValue_COPY_INP_TMP.Dispose();
|
hv_GenParamValue_COPY_INP_TMP = ExpTmpOutVar_0;
|
}
|
}
|
//
|
//Parse the generic parameters
|
//- First, all parameters that are understood by set_scene_3d_instance_param
|
hv_AlphaOrig.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_AlphaOrig = HTuple.TupleGenConst(
|
hv_NumModels, 1);
|
}
|
for (hv_I = 0; (int)hv_I <= (int)(new HTuple(hv_GenParamName_COPY_INP_TMP.TupleLength()
|
) - 1); hv_I = (int)hv_I + 1)
|
{
|
hv_ParamName.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ParamName = hv_GenParamName_COPY_INP_TMP.TupleSelect(
|
hv_I);
|
}
|
hv_ParamValue.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ParamValue = hv_GenParamValue_COPY_INP_TMP.TupleSelect(
|
hv_I);
|
}
|
//Check if this parameter is understood by set_scene_3d_param
|
if ((int)new HTuple(hv_ParamName.TupleEqual("alpha")) != 0)
|
{
|
hv_AlphaOrig.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_AlphaOrig = HTuple.TupleGenConst(
|
hv_NumModels, hv_ParamValue);
|
}
|
}
|
try
|
{
|
HOperatorSet.SetScene3dParam(hv_Scene3D, hv_ParamName, hv_ParamValue);
|
continue;
|
}
|
// catch (Exception)
|
catch (HalconException HDevExpDefaultException2)
|
{
|
HDevExpDefaultException2.ToHTuple(out hv_Exception);
|
if ((int)new HTuple(hv_Exception.TupleSelect(0).TupleEqual(1203)).TupleOr(
|
new HTuple(hv_Exception.TupleSelect(0).TupleEqual(1303))) != 0)
|
{
|
if ((int)new HTuple(new HTuple(new HTuple(hv_ParamName.TupleEqual(
|
"color_attrib")).TupleOr(new HTuple(hv_ParamName.TupleEqual("red_channel_attrib")))).TupleOr(
|
new HTuple(hv_ParamName.TupleEqual("green_channel_attrib")))).TupleOr(
|
new HTuple(hv_ParamName.TupleEqual("blue_channel_attrib"))) != 0)
|
{
|
throw new HalconException("Wrong type or value for parameter " + hv_ParamName + ": " + hv_ParamValue + ". " + hv_ParamValue + " may not be attached to the points of the 3D object model. Compare the parameter AttachExtAttribTo of set_object_model_3d_attrib.");
|
}
|
else
|
{
|
throw new HalconException("Wrong type or value for parameter " + hv_ParamName + ": " + hv_ParamValue);
|
}
|
}
|
}
|
//Check if it is a parameter that is valid for only one instance
|
//and therefore can be set only with set_scene_3d_instance_param
|
hv_ParamNameTrunk.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ParamNameTrunk = hv_ParamName.TupleRegexpReplace(
|
"_\\d+$", "");
|
}
|
if ((int)new HTuple(hv_ParamName.TupleEqual(hv_ParamNameTrunk)) != 0)
|
{
|
hv_Instance.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Instance = HTuple.TupleGenSequence(
|
0, hv_NumModels - 1, 1);
|
}
|
}
|
else
|
{
|
hv_Instance.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Instance = hv_ParamName.TupleRegexpReplace(
|
"^" + hv_ParamNameTrunk + "_(\\d+)$", "$1").TupleNumber();
|
}
|
if ((int)new HTuple(hv_Instance.TupleLess(0)).TupleOr(new HTuple(hv_Instance.TupleGreater(
|
hv_NumModels - 1))) != 0)
|
{
|
throw new HalconException("Parameter " + hv_ParamName + " refers to a non existing 3D object model");
|
}
|
}
|
try
|
{
|
HOperatorSet.SetScene3dInstanceParam(hv_Scene3D, hv_Instance, hv_ParamNameTrunk,
|
hv_ParamValue);
|
}
|
// catch (Exception)
|
catch (HalconException HDevExpDefaultException2)
|
{
|
HDevExpDefaultException2.ToHTuple(out hv_Exception);
|
if ((int)new HTuple(hv_Exception.TupleSelect(0).TupleEqual(1204)).TupleOr(
|
new HTuple(hv_Exception.TupleSelect(0).TupleEqual(1304))) != 0)
|
{
|
if ((int)new HTuple(new HTuple(new HTuple(hv_ParamNameTrunk.TupleEqual(
|
"color_attrib")).TupleOr(new HTuple(hv_ParamNameTrunk.TupleEqual(
|
"red_channel_attrib")))).TupleOr(new HTuple(hv_ParamNameTrunk.TupleEqual(
|
"green_channel_attrib")))).TupleOr(new HTuple(hv_ParamNameTrunk.TupleEqual(
|
"blue_channel_attrib"))) != 0)
|
{
|
throw new HalconException("Wrong type or value for parameter " + hv_ParamName + ": " + hv_ParamValue + ". " + hv_ParamValue + " may not be attached to the points of the 3D object model. Compare the parameter AttachExtAttribTo of set_object_model_3d_attrib.");
|
}
|
else
|
{
|
throw new HalconException("Wrong type or value for parameter " + hv_ParamName + ": " + hv_ParamValue);
|
}
|
}
|
else if ((int)new HTuple(hv_Exception.TupleSelect(0).TupleEqual(
|
1203)).TupleOr(new HTuple(hv_Exception.TupleSelect(0).TupleEqual(
|
1303))) != 0)
|
{
|
throw new HalconException("Wrong parameter name " + hv_ParamName);
|
}
|
else
|
{
|
throw new HalconException(hv_Exception);
|
}
|
}
|
if ((int)new HTuple(hv_ParamNameTrunk.TupleEqual("alpha")) != 0)
|
{
|
if (hv_AlphaOrig == null)
|
hv_AlphaOrig = new HTuple();
|
hv_AlphaOrig[hv_Instance] = hv_ParamValue;
|
}
|
}
|
//
|
//Start the visualization loop
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_HomMat3D.Dispose();
|
HOperatorSet.PoseToHomMat3d(hv_Poses.TupleSelectRange(0, 6), out hv_HomMat3D);
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Qx.Dispose(); hv_Qy.Dispose(); hv_Qz.Dispose();
|
HOperatorSet.AffineTransPoint3d(hv_HomMat3D, hv_Center.TupleSelect(0), hv_Center.TupleSelect(
|
1), hv_Center.TupleSelect(2), out hv_Qx, out hv_Qy, out hv_Qz);
|
}
|
hv_TBCenter.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TBCenter = new HTuple();
|
hv_TBCenter = hv_TBCenter.TupleConcat(hv_Qx, hv_Qy, hv_Qz);
|
}
|
hv_TBSize.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TBSize = (0.5 + 0.5 * hv_SelectedObject.TupleSum()
|
/ hv_NumModels) * hv_TrackballRadiusPixel;
|
}
|
hv_ButtonHold.Dispose();
|
hv_ButtonHold = 0;
|
while (1 != 0)
|
{
|
// 设置在死循环不卡主线程
|
|
hv_VisualizeTB.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_VisualizeTB = new HTuple(hv_SelectedObject.TupleMax()
|
.TupleNotEqual(0));
|
}
|
hv_MaxIndex.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_MaxIndex = new HTuple(hv_ObjectModel3D.TupleLength()
|
).TupleConcat(hv_MaxNumModels).TupleMin() - 1;
|
}
|
//Set trackball fixed in the center of the window
|
hv_TrackballCenterRow.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TrackballCenterRow = hv_Height / 2;
|
}
|
hv_TrackballCenterCol.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TrackballCenterCol = hv_Width / 2;
|
}
|
if ((int)new HTuple(hv_WindowCenteredRotation.TupleEqual(1)) != 0)
|
{
|
try
|
{
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TBCenter.Dispose(); hv_TBSize.Dispose();
|
HDevelopExport.get_trackball_center_fixed(hv_SelectedObject.TupleSelectRange(0, hv_MaxIndex),
|
hv_TrackballCenterRow, hv_TrackballCenterCol, hv_TrackballRadiusPixel,
|
hv_Scene3D, hv_ObjectModel3D.TupleSelectRange(0, hv_MaxIndex), hv_Poses.TupleSelectRange(
|
0, (hv_MaxIndex + 1) * 7 - 1), hv_WindowHandleBuffer, hv_CamParam_COPY_INP_TMP,
|
hv_GenParamName_COPY_INP_TMP, hv_GenParamValue_COPY_INP_TMP, out hv_TBCenter,
|
out hv_TBSize);
|
}
|
}
|
// catch (Exception)
|
catch (HalconException HDevExpDefaultException2)
|
{
|
HDevExpDefaultException2.ToHTuple(out hv_Exception);
|
disp_message(hv_WindowHandle, "Surface inspection mode is not available.",
|
"image", 5, 20, "red", "true");
|
hv_WindowCenteredRotation.Dispose();
|
hv_WindowCenteredRotation = 2;
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TBCenter.Dispose(); hv_TBSize.Dispose();
|
HDevelopExport.get_trackball_center(hv_SelectedObject.TupleSelectRange(0, hv_MaxIndex),
|
hv_TrackballRadiusPixel, hv_ObjectModel3D.TupleSelectRange(0, hv_MaxIndex),
|
hv_Poses.TupleSelectRange(0, (hv_MaxIndex + 1) * 7 - 1), out hv_TBCenter,
|
out hv_TBSize);
|
}
|
HOperatorSet.WaitSeconds(1);
|
}
|
}
|
else
|
{
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TBCenter.Dispose(); hv_TBSize.Dispose();
|
HDevelopExport.get_trackball_center(hv_SelectedObject.TupleSelectRange(0, hv_MaxIndex),
|
hv_TrackballRadiusPixel, hv_ObjectModel3D.TupleSelectRange(0, hv_MaxIndex),
|
hv_Poses.TupleSelectRange(0, (hv_MaxIndex + 1) * 7 - 1), out hv_TBCenter,
|
out hv_TBSize);
|
}
|
}
|
HDevelopExport.dump_image_output(ho_Image, hv_WindowHandleBuffer, hv_Scene3D, hv_AlphaOrig,
|
hv_ObjectModel3D, hv_GenParamName_COPY_INP_TMP, hv_GenParamValue_COPY_INP_TMP,
|
hv_CamParam_COPY_INP_TMP, hv_Poses, hv_ColorImage, hv_Title, hv_Information,
|
hv_Label_COPY_INP_TMP, hv_VisualizeTB, "true", hv_TrackballCenterRow,
|
hv_TrackballCenterCol, hv_TBSize, hv_SelectedObject, hv_WindowCenteredRotation,
|
hv_TBCenter);
|
ho_ImageDump.Dispose();
|
HOperatorSet.DumpWindowImage(out ho_ImageDump, hv_WindowHandleBuffer);
|
HDevWindowStack.SetActive(hv_WindowHandle);
|
if (HDevWindowStack.IsOpen())
|
{
|
HOperatorSet.DispObj(ho_ImageDump, HDevWindowStack.GetActive());
|
}
|
//
|
//Check for mouse events
|
hv_GraphEvent.Dispose();
|
hv_GraphEvent = 0;
|
hv_Exit.Dispose();
|
hv_Exit = 0;
|
while (1 != 0)
|
{
|
// 设置在死循环不卡主线程
|
//
|
//Check graphic event
|
try
|
{
|
hv_GraphButtonRow.Dispose(); hv_GraphButtonColumn.Dispose(); hv_GraphButton.Dispose();
|
HOperatorSet.GetMpositionSubPix(hv_WindowHandle, out hv_GraphButtonRow,
|
out hv_GraphButtonColumn, out hv_GraphButton);
|
if ((int)new HTuple(hv_GraphButton.TupleNotEqual(0)) != 0)
|
{
|
if ((int)new HTuple(new HTuple(new HTuple(hv_GraphButtonRow.TupleGreater(
|
hv_Height - hv_TextHeight - 25)).TupleAnd(new HTuple(hv_GraphButtonRow.TupleLess(
|
hv_Height)))).TupleAnd(new HTuple(hv_GraphButtonColumn.TupleGreater(
|
hv_Width - hv_TextWidth - 15)))).TupleAnd(new HTuple(hv_GraphButtonColumn.TupleLess(
|
hv_Width))) != 0)
|
{
|
//Wait until the continue button has been released
|
if ((int)new HTuple(hv_WaitForButtonRelease.TupleEqual("true")) != 0)
|
{
|
while (1 != 0)
|
{
|
hv_GraphButtonRow.Dispose(); hv_GraphButtonColumn.Dispose(); hv_GraphButton.Dispose();
|
HOperatorSet.GetMpositionSubPix(hv_WindowHandle, out hv_GraphButtonRow,
|
out hv_GraphButtonColumn, out hv_GraphButton);
|
if ((int)new HTuple(hv_GraphButton.TupleEqual(0)).TupleOr(
|
new HTuple(hv_GraphButton.TupleEqual(new HTuple()))) != 0)
|
{
|
if ((int)new HTuple(new HTuple(new HTuple(hv_GraphButtonRow.TupleGreater(
|
hv_Height - hv_TextHeight - 25)).TupleAnd(new HTuple(hv_GraphButtonRow.TupleLess(
|
hv_Height)))).TupleAnd(new HTuple(hv_GraphButtonColumn.TupleGreater(
|
hv_Width - hv_TextWidth - 15)))).TupleAnd(new HTuple(hv_GraphButtonColumn.TupleLess(
|
hv_Width))) != 0)
|
{
|
hv_ButtonReleased.Dispose();
|
hv_ButtonReleased = 1;
|
}
|
else
|
{
|
hv_ButtonReleased.Dispose();
|
hv_ButtonReleased = 0;
|
}
|
//
|
break;
|
}
|
//Keep waiting until mouse button is released or moved out of the window
|
}
|
}
|
else
|
{
|
hv_ButtonReleased.Dispose();
|
hv_ButtonReleased = 1;
|
}
|
//Exit the visualization loop
|
if ((int)hv_ButtonReleased != 0)
|
{
|
hv_Exit.Dispose();
|
hv_Exit = 1;
|
break;
|
}
|
}
|
hv_GraphEvent.Dispose();
|
hv_GraphEvent = 1;
|
break;
|
}
|
else
|
{
|
hv_ButtonHold.Dispose();
|
hv_ButtonHold = 0;
|
}
|
}
|
// catch (Exception)
|
catch (HalconException HDevExpDefaultException2)
|
{
|
HDevExpDefaultException2.ToHTuple(out hv_Exception);
|
//Keep waiting
|
}
|
}
|
if ((int)hv_GraphEvent != 0)
|
{
|
{
|
HTuple ExpTmpOutVar_0; HTuple ExpTmpOutVar_1; HTuple ExpTmpOutVar_2; HTuple ExpTmpOutVar_3;
|
HDevelopExport.analyze_graph_event(ho_Image, hv_MouseMapping, hv_GraphButton, hv_GraphButtonRow,
|
hv_GraphButtonColumn, hv_WindowHandle, hv_WindowHandleBuffer, hv_VirtualTrackball,
|
hv_TrackballSize, hv_SelectedObject, hv_Scene3D, hv_AlphaOrig, hv_ObjectModel3D,
|
hv_CamParam_COPY_INP_TMP, hv_Label_COPY_INP_TMP, hv_Title, hv_Information,
|
hv_GenParamName_COPY_INP_TMP, hv_GenParamValue_COPY_INP_TMP, hv_Poses,
|
hv_ButtonHold, hv_TBCenter, hv_TBSize, hv_WindowCenteredRotation,
|
hv_MaxNumModels, out ExpTmpOutVar_0, out ExpTmpOutVar_1, out ExpTmpOutVar_2,
|
out ExpTmpOutVar_3);
|
hv_Poses.Dispose();
|
hv_Poses = ExpTmpOutVar_0;
|
hv_SelectedObject.Dispose();
|
hv_SelectedObject = ExpTmpOutVar_1;
|
hv_ButtonHold.Dispose();
|
hv_ButtonHold = ExpTmpOutVar_2;
|
hv_WindowCenteredRotation.Dispose();
|
hv_WindowCenteredRotation = ExpTmpOutVar_3;
|
}
|
}
|
if ((int)hv_Exit != 0)
|
{
|
break;
|
}
|
}
|
//
|
//Display final state with persistence, if requested
|
//Note that disp_object_model_3d must be used instead of the 3D scene
|
if ((int)new HTuple(new HTuple(hv_PersistenceParamName.TupleLength()).TupleGreater(
|
0)) != 0)
|
{
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
HOperatorSet.DispObjectModel3d(hv_WindowHandle, hv_ObjectModel3D, hv_CamParam_COPY_INP_TMP,
|
hv_Poses, new HTuple("disp_background").TupleConcat("alpha").TupleConcat(
|
hv_PersistenceParamName), new HTuple("true").TupleConcat(0.0).TupleConcat(
|
hv_PersistenceParamValue));
|
}
|
}
|
//
|
//Compute the output pose
|
if ((int)HDevelopExport.ExpGetGlobalVar_gIsSinglePose() != 0)
|
{
|
hv_PoseOut.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_PoseOut = hv_Poses.TupleSelectRange(
|
0, 6);
|
}
|
}
|
else
|
{
|
hv_PoseOut.Dispose();
|
hv_PoseOut = new HTuple(hv_Poses);
|
}
|
//
|
//Clean up.
|
HOperatorSet.SetSystem("clip_region", hv_ClipRegion);
|
// dev_set_preferences(...); only in hdevelop
|
// dev_set_preferences(...); only in hdevelop
|
HDevelopExport.dump_image_output(ho_Image, hv_WindowHandleBuffer, hv_Scene3D, hv_AlphaOrig,
|
hv_ObjectModel3D, hv_GenParamName_COPY_INP_TMP, hv_GenParamValue_COPY_INP_TMP,
|
hv_CamParam_COPY_INP_TMP, hv_Poses, hv_ColorImage, hv_Title, new HTuple(),
|
hv_Label_COPY_INP_TMP, 0, "false", hv_TrackballCenterRow, hv_TrackballCenterCol,
|
hv_TBSize, hv_SelectedObject, hv_WindowCenteredRotation, hv_TBCenter);
|
ho_ImageDump.Dispose();
|
HOperatorSet.DumpWindowImage(out ho_ImageDump, hv_WindowHandleBuffer);
|
HDevWindowStack.SetActive(hv_WindowHandle);
|
if (HDevWindowStack.IsOpen())
|
{
|
HOperatorSet.DispObj(ho_ImageDump, HDevWindowStack.GetActive());
|
}
|
HOperatorSet.CloseWindow(hv_WindowHandleBuffer);
|
HOperatorSet.SetPart(hv_WindowHandle, hv_WPRow1, hv_WPColumn1, hv_WPRow2,
|
hv_WPColumn2);
|
HOperatorSet.ClearScene3d(hv_Scene3D);
|
hv_Scene3D.Dispose();
|
hv_Scene3D = new HTuple();
|
}
|
// catch (Exception)
|
catch (HalconException HDevExpDefaultException1)
|
{
|
HDevExpDefaultException1.ToHTuple(out hv_Exception);
|
try
|
{
|
//Try to clean up as much as possible.
|
if ((int)new HTuple(new HTuple(0).TupleLess(new HTuple(hv_Scene3DTest.TupleLength()
|
))) != 0)
|
{
|
HOperatorSet.ClearScene3d(hv_Scene3DTest);
|
hv_Scene3DTest.Dispose();
|
hv_Scene3DTest = new HTuple();
|
}
|
if ((int)new HTuple(new HTuple(0).TupleLess(new HTuple(hv_Scene3D.TupleLength()
|
))) != 0)
|
{
|
HOperatorSet.ClearScene3d(hv_Scene3D);
|
hv_Scene3D.Dispose();
|
hv_Scene3D = new HTuple();
|
}
|
if ((int)new HTuple(new HTuple(0).TupleLess(new HTuple(hv_WindowHandleBuffer.TupleLength()
|
))) != 0)
|
{
|
HOperatorSet.CloseWindow(hv_WindowHandleBuffer);
|
hv_WindowHandleBuffer.Dispose();
|
hv_WindowHandleBuffer = new HTuple();
|
}
|
}
|
// catch (e)
|
catch (HalconException HDevExpDefaultException2)
|
{
|
HDevExpDefaultException2.ToHTuple(out hv_e);
|
//Suppress all further exceptions to return the original exception.
|
}
|
try
|
{
|
//Restore system settings.
|
HOperatorSet.SetSystem("clip_region", hv_ClipRegion);
|
// dev_set_preferences(...); only in hdevelop
|
// dev_set_preferences(...); only in hdevelop
|
}
|
// catch (e)
|
catch (HalconException HDevExpDefaultException2)
|
{
|
HDevExpDefaultException2.ToHTuple(out hv_e);
|
//Suppress all further exceptions to return the original exception.
|
}
|
//
|
throw new HalconException(hv_Exception);
|
}
|
ho_Image.Dispose();
|
ho_ImageDump.Dispose();
|
|
hv_CamParam_COPY_INP_TMP.Dispose();
|
hv_GenParamName_COPY_INP_TMP.Dispose();
|
hv_GenParamValue_COPY_INP_TMP.Dispose();
|
hv_Label_COPY_INP_TMP.Dispose();
|
hv_PoseIn_COPY_INP_TMP.Dispose();
|
hv_Scene3DTest.Dispose();
|
hv_Scene3D.Dispose();
|
hv_WindowHandleBuffer.Dispose();
|
hv_TrackballSize.Dispose();
|
hv_VirtualTrackball.Dispose();
|
hv_MouseMapping.Dispose();
|
hv_WaitForButtonRelease.Dispose();
|
hv_MaxNumModels.Dispose();
|
hv_WindowCenteredRotation.Dispose();
|
hv_NumModels.Dispose();
|
hv_SelectedObject.Dispose();
|
hv_ClipRegion.Dispose();
|
hv_CPLength.Dispose();
|
hv_RowNotUsed.Dispose();
|
hv_ColumnNotUsed.Dispose();
|
hv_Width.Dispose();
|
hv_Height.Dispose();
|
hv_WPRow1.Dispose();
|
hv_WPColumn1.Dispose();
|
hv_WPRow2.Dispose();
|
hv_WPColumn2.Dispose();
|
hv_CamParamValue.Dispose();
|
hv_CamWidth.Dispose();
|
hv_CamHeight.Dispose();
|
hv_Scale.Dispose();
|
hv_Indices.Dispose();
|
hv_DispBackground.Dispose();
|
hv_Mask.Dispose();
|
hv_Center.Dispose();
|
hv_PoseEstimated.Dispose();
|
hv_Poses.Dispose();
|
hv_HomMat3Ds.Dispose();
|
hv_Sequence.Dispose();
|
hv_Font.Dispose();
|
hv_Exception.Dispose();
|
hv_OpenGLInfo.Dispose();
|
hv_DummyObjectModel3D.Dispose();
|
hv_CameraIndexTest.Dispose();
|
hv_PoseTest.Dispose();
|
hv_InstanceIndexTest.Dispose();
|
hv_MinImageSize.Dispose();
|
hv_TrackballRadiusPixel.Dispose();
|
hv_Ascent.Dispose();
|
hv_Descent.Dispose();
|
hv_TextWidth.Dispose();
|
hv_TextHeight.Dispose();
|
hv_NumChannels.Dispose();
|
hv_ColorImage.Dispose();
|
hv_CameraIndex.Dispose();
|
hv_AllInstances.Dispose();
|
hv_SetLight.Dispose();
|
hv_LightParam.Dispose();
|
hv_LightPosition.Dispose();
|
hv_LightKind.Dispose();
|
hv_LightIndex.Dispose();
|
hv_PersistenceParamName.Dispose();
|
hv_PersistenceParamValue.Dispose();
|
hv_AlphaOrig.Dispose();
|
hv_I.Dispose();
|
hv_ParamName.Dispose();
|
hv_ParamValue.Dispose();
|
hv_ParamNameTrunk.Dispose();
|
hv_Instance.Dispose();
|
hv_HomMat3D.Dispose();
|
hv_Qx.Dispose();
|
hv_Qy.Dispose();
|
hv_Qz.Dispose();
|
hv_TBCenter.Dispose();
|
hv_TBSize.Dispose();
|
hv_ButtonHold.Dispose();
|
hv_VisualizeTB.Dispose();
|
hv_MaxIndex.Dispose();
|
hv_TrackballCenterRow.Dispose();
|
hv_TrackballCenterCol.Dispose();
|
hv_GraphEvent.Dispose();
|
hv_Exit.Dispose();
|
hv_GraphButtonRow.Dispose();
|
hv_GraphButtonColumn.Dispose();
|
hv_GraphButton.Dispose();
|
hv_ButtonReleased.Dispose();
|
hv_e.Dispose();
|
|
return;
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
ho_Image.Dispose();
|
ho_ImageDump.Dispose();
|
|
hv_CamParam_COPY_INP_TMP.Dispose();
|
hv_GenParamName_COPY_INP_TMP.Dispose();
|
hv_GenParamValue_COPY_INP_TMP.Dispose();
|
hv_Label_COPY_INP_TMP.Dispose();
|
hv_PoseIn_COPY_INP_TMP.Dispose();
|
hv_Scene3DTest.Dispose();
|
hv_Scene3D.Dispose();
|
hv_WindowHandleBuffer.Dispose();
|
hv_TrackballSize.Dispose();
|
hv_VirtualTrackball.Dispose();
|
hv_MouseMapping.Dispose();
|
hv_WaitForButtonRelease.Dispose();
|
hv_MaxNumModels.Dispose();
|
hv_WindowCenteredRotation.Dispose();
|
hv_NumModels.Dispose();
|
hv_SelectedObject.Dispose();
|
hv_ClipRegion.Dispose();
|
hv_CPLength.Dispose();
|
hv_RowNotUsed.Dispose();
|
hv_ColumnNotUsed.Dispose();
|
hv_Width.Dispose();
|
hv_Height.Dispose();
|
hv_WPRow1.Dispose();
|
hv_WPColumn1.Dispose();
|
hv_WPRow2.Dispose();
|
hv_WPColumn2.Dispose();
|
hv_CamParamValue.Dispose();
|
hv_CamWidth.Dispose();
|
hv_CamHeight.Dispose();
|
hv_Scale.Dispose();
|
hv_Indices.Dispose();
|
hv_DispBackground.Dispose();
|
hv_Mask.Dispose();
|
hv_Center.Dispose();
|
hv_PoseEstimated.Dispose();
|
hv_Poses.Dispose();
|
hv_HomMat3Ds.Dispose();
|
hv_Sequence.Dispose();
|
hv_Font.Dispose();
|
hv_Exception.Dispose();
|
hv_OpenGLInfo.Dispose();
|
hv_DummyObjectModel3D.Dispose();
|
hv_CameraIndexTest.Dispose();
|
hv_PoseTest.Dispose();
|
hv_InstanceIndexTest.Dispose();
|
hv_MinImageSize.Dispose();
|
hv_TrackballRadiusPixel.Dispose();
|
hv_Ascent.Dispose();
|
hv_Descent.Dispose();
|
hv_TextWidth.Dispose();
|
hv_TextHeight.Dispose();
|
hv_NumChannels.Dispose();
|
hv_ColorImage.Dispose();
|
hv_CameraIndex.Dispose();
|
hv_AllInstances.Dispose();
|
hv_SetLight.Dispose();
|
hv_LightParam.Dispose();
|
hv_LightPosition.Dispose();
|
hv_LightKind.Dispose();
|
hv_LightIndex.Dispose();
|
hv_PersistenceParamName.Dispose();
|
hv_PersistenceParamValue.Dispose();
|
hv_AlphaOrig.Dispose();
|
hv_I.Dispose();
|
hv_ParamName.Dispose();
|
hv_ParamValue.Dispose();
|
hv_ParamNameTrunk.Dispose();
|
hv_Instance.Dispose();
|
hv_HomMat3D.Dispose();
|
hv_Qx.Dispose();
|
hv_Qy.Dispose();
|
hv_Qz.Dispose();
|
hv_TBCenter.Dispose();
|
hv_TBSize.Dispose();
|
hv_ButtonHold.Dispose();
|
hv_VisualizeTB.Dispose();
|
hv_MaxIndex.Dispose();
|
hv_TrackballCenterRow.Dispose();
|
hv_TrackballCenterCol.Dispose();
|
hv_GraphEvent.Dispose();
|
hv_Exit.Dispose();
|
hv_GraphButtonRow.Dispose();
|
hv_GraphButtonColumn.Dispose();
|
hv_GraphButton.Dispose();
|
hv_ButtonReleased.Dispose();
|
hv_e.Dispose();
|
|
throw HDevExpDefaultException;
|
}
|
}
|
|
// Chapter: Calibration / Camera Parameters
|
// Short Description: Set the value of a specified camera parameter in the camera parameter tuple.
|
public static void set_cam_par_data(HTuple hv_CameraParamIn, HTuple hv_ParamName, HTuple hv_ParamValue,
|
out HTuple hv_CameraParamOut)
|
{
|
// Local iconic variables
|
|
// Local control variables
|
|
HTuple hv_CameraType = new HTuple(), hv_CameraParamNames = new HTuple();
|
HTuple hv_Index = new HTuple(), hv_ParamNameInd = new HTuple();
|
HTuple hv_I = new HTuple(), hv_IsTelecentric = new HTuple();
|
// Initialize local and output iconic variables
|
hv_CameraParamOut = new HTuple();
|
try
|
{
|
//set_cam_par_data sets the value of the parameter that
|
//is given in ParamName in the tuple of camera parameters
|
//given in CameraParamIn. The modified camera parameters
|
//are returned in CameraParamOut.
|
//
|
//Check for consistent length of input parameters
|
if ((int)new HTuple(new HTuple(hv_ParamName.TupleLength()).TupleNotEqual(
|
new HTuple(hv_ParamValue.TupleLength()))) != 0)
|
{
|
throw new HalconException("Different number of values in ParamName and ParamValue");
|
}
|
//First, get the parameter names that correspond to the
|
//elements in the input camera parameter tuple.
|
hv_CameraType.Dispose(); hv_CameraParamNames.Dispose();
|
HDevelopExport.get_cam_par_names(hv_CameraParamIn, out hv_CameraType, out hv_CameraParamNames);
|
//
|
//Find the index of the requested camera data and return
|
//the corresponding value.
|
hv_CameraParamOut.Dispose();
|
hv_CameraParamOut = new HTuple(hv_CameraParamIn);
|
for (hv_Index = 0; (int)hv_Index <= (int)(new HTuple(hv_ParamName.TupleLength()
|
) - 1); hv_Index = (int)hv_Index + 1)
|
{
|
hv_ParamNameInd.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ParamNameInd = hv_ParamName.TupleSelect(
|
hv_Index);
|
}
|
hv_I.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_I = hv_CameraParamNames.TupleFind(
|
hv_ParamNameInd);
|
}
|
if ((int)new HTuple(hv_I.TupleNotEqual(-1)) != 0)
|
{
|
if (hv_CameraParamOut == null)
|
hv_CameraParamOut = new HTuple();
|
hv_CameraParamOut[hv_I] = hv_ParamValue.TupleSelect(hv_Index);
|
}
|
else
|
{
|
throw new HalconException("Wrong ParamName " + hv_ParamNameInd);
|
}
|
//Check the consistency of focus and telecentricity
|
if ((int)new HTuple(hv_ParamNameInd.TupleEqual("focus")) != 0)
|
{
|
hv_IsTelecentric.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_IsTelecentric = new HTuple(hv_CameraType.TupleStrstr(
|
"telecentric").TupleNotEqual(-1)).TupleAnd(new HTuple(hv_CameraType.TupleStrstr(
|
"image_side_telecentric").TupleEqual(-1)));
|
}
|
if ((int)hv_IsTelecentric != 0)
|
{
|
throw new HalconException(new HTuple("Focus for telecentric lenses is always 0, and hence, cannot be changed."));
|
}
|
if ((int)new HTuple(hv_IsTelecentric.TupleNot()).TupleAnd(new HTuple(hv_ParamValue.TupleSelect(
|
hv_Index).TupleEqual(0.0))) != 0)
|
{
|
throw new HalconException("Focus for non-telecentric lenses must not be 0.");
|
}
|
}
|
}
|
|
hv_CameraType.Dispose();
|
hv_CameraParamNames.Dispose();
|
hv_Index.Dispose();
|
hv_ParamNameInd.Dispose();
|
hv_I.Dispose();
|
hv_IsTelecentric.Dispose();
|
|
return;
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
|
hv_CameraType.Dispose();
|
hv_CameraParamNames.Dispose();
|
hv_Index.Dispose();
|
hv_ParamNameInd.Dispose();
|
hv_I.Dispose();
|
hv_IsTelecentric.Dispose();
|
|
throw HDevExpDefaultException;
|
}
|
}
|
|
public static void gen_arrow_contour_xld(out HObject ho_Arrow, HTuple hv_Row1, HTuple hv_Column1,
|
HTuple hv_Row2, HTuple hv_Column2, HTuple hv_HeadLength, HTuple hv_HeadWidth)
|
{
|
// Stack for temporary objects
|
HObject[] OTemp = new HObject[20];
|
|
// Local iconic variables
|
|
HObject ho_TempArrow = null;
|
|
// Local control variables
|
|
HTuple hv_Length = new HTuple(), hv_ZeroLengthIndices = new HTuple();
|
HTuple hv_DR = new HTuple(), hv_DC = new HTuple(), hv_HalfHeadWidth = new HTuple();
|
HTuple hv_RowP1 = new HTuple(), hv_ColP1 = new HTuple();
|
HTuple hv_RowP2 = new HTuple(), hv_ColP2 = new HTuple();
|
HTuple hv_Index = new HTuple();
|
// Initialize local and output iconic variables
|
HOperatorSet.GenEmptyObj(out ho_Arrow);
|
HOperatorSet.GenEmptyObj(out ho_TempArrow);
|
try
|
{
|
//This procedure generates arrow shaped XLD contours,
|
//pointing from (Row1, Column1) to (Row2, Column2).
|
//If starting and end point are identical, a contour consisting
|
//of a single point is returned.
|
//
|
//input parameteres:
|
//Row1, Column1: Coordinates of the arrows' starting points
|
//Row2, Column2: Coordinates of the arrows' end points
|
//HeadLength, HeadWidth: Size of the arrow heads in pixels
|
//
|
//output parameter:
|
//Arrow: The resulting XLD contour
|
//
|
//The input tuples Row1, Column1, Row2, and Column2 have to be of
|
//the same length.
|
//HeadLength and HeadWidth either have to be of the same length as
|
//Row1, Column1, Row2, and Column2 or have to be a single element.
|
//If one of the above restrictions is violated, an error will occur.
|
//
|
//
|
//Init
|
ho_Arrow.Dispose();
|
HOperatorSet.GenEmptyObj(out ho_Arrow);
|
//
|
//Calculate the arrow length
|
hv_Length.Dispose();
|
HOperatorSet.DistancePp(hv_Row1, hv_Column1, hv_Row2, hv_Column2, out hv_Length);
|
//
|
//Mark arrows with identical start and end point
|
//(set Length to -1 to avoid division-by-zero exception)
|
hv_ZeroLengthIndices.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ZeroLengthIndices = hv_Length.TupleFind(
|
0);
|
}
|
if ((int)(new HTuple(hv_ZeroLengthIndices.TupleNotEqual(-1))) != 0)
|
{
|
if (hv_Length == null)
|
hv_Length = new HTuple();
|
hv_Length[hv_ZeroLengthIndices] = -1;
|
}
|
//
|
//Calculate auxiliary variables.
|
hv_DR.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_DR = (1.0 * (hv_Row2 - hv_Row1)) / hv_Length;
|
}
|
hv_DC.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_DC = (1.0 * (hv_Column2 - hv_Column1)) / hv_Length;
|
}
|
hv_HalfHeadWidth.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_HalfHeadWidth = hv_HeadWidth / 2.0;
|
}
|
//
|
//Calculate end points of the arrow head.
|
hv_RowP1.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_RowP1 = (hv_Row1 + ((hv_Length - hv_HeadLength) * hv_DR)) + (hv_HalfHeadWidth * hv_DC);
|
}
|
hv_ColP1.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ColP1 = (hv_Column1 + ((hv_Length - hv_HeadLength) * hv_DC)) - (hv_HalfHeadWidth * hv_DR);
|
}
|
hv_RowP2.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_RowP2 = (hv_Row1 + ((hv_Length - hv_HeadLength) * hv_DR)) - (hv_HalfHeadWidth * hv_DC);
|
}
|
hv_ColP2.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ColP2 = (hv_Column1 + ((hv_Length - hv_HeadLength) * hv_DC)) + (hv_HalfHeadWidth * hv_DR);
|
}
|
//
|
//Finally create output XLD contour for each input point pair
|
for (hv_Index = 0; (int)hv_Index <= (int)((new HTuple(hv_Length.TupleLength())) - 1); hv_Index = (int)hv_Index + 1)
|
{
|
if ((int)(new HTuple(((hv_Length.TupleSelect(hv_Index))).TupleEqual(-1))) != 0)
|
{
|
//Create_ single points for arrows with identical start and end point
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
ho_TempArrow.Dispose();
|
HOperatorSet.GenContourPolygonXld(out ho_TempArrow, hv_Row1.TupleSelect(
|
hv_Index), hv_Column1.TupleSelect(hv_Index));
|
}
|
}
|
else
|
{
|
//Create arrow contour
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
ho_TempArrow.Dispose();
|
HOperatorSet.GenContourPolygonXld(out ho_TempArrow, ((((((((((hv_Row1.TupleSelect(
|
hv_Index))).TupleConcat(hv_Row2.TupleSelect(hv_Index)))).TupleConcat(
|
hv_RowP1.TupleSelect(hv_Index)))).TupleConcat(hv_Row2.TupleSelect(hv_Index)))).TupleConcat(
|
hv_RowP2.TupleSelect(hv_Index)))).TupleConcat(hv_Row2.TupleSelect(hv_Index)),
|
((((((((((hv_Column1.TupleSelect(hv_Index))).TupleConcat(hv_Column2.TupleSelect(
|
hv_Index)))).TupleConcat(hv_ColP1.TupleSelect(hv_Index)))).TupleConcat(
|
hv_Column2.TupleSelect(hv_Index)))).TupleConcat(hv_ColP2.TupleSelect(
|
hv_Index)))).TupleConcat(hv_Column2.TupleSelect(hv_Index)));
|
}
|
}
|
{
|
HObject ExpTmpOutVar_0;
|
HOperatorSet.ConcatObj(ho_Arrow, ho_TempArrow, out ExpTmpOutVar_0);
|
ho_Arrow.Dispose();
|
ho_Arrow = ExpTmpOutVar_0;
|
}
|
}
|
ho_TempArrow.Dispose();
|
|
hv_Length.Dispose();
|
hv_ZeroLengthIndices.Dispose();
|
hv_DR.Dispose();
|
hv_DC.Dispose();
|
hv_HalfHeadWidth.Dispose();
|
hv_RowP1.Dispose();
|
hv_ColP1.Dispose();
|
hv_RowP2.Dispose();
|
hv_ColP2.Dispose();
|
hv_Index.Dispose();
|
|
return;
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
ho_TempArrow.Dispose();
|
|
hv_Length.Dispose();
|
hv_ZeroLengthIndices.Dispose();
|
hv_DR.Dispose();
|
hv_DC.Dispose();
|
hv_HalfHeadWidth.Dispose();
|
hv_RowP1.Dispose();
|
hv_ColP1.Dispose();
|
hv_RowP2.Dispose();
|
hv_ColP2.Dispose();
|
hv_Index.Dispose();
|
|
throw HDevExpDefaultException;
|
}
|
}
|
|
public static void get_rect2_vertex(HTuple hv_Row, HTuple hv_Column, HTuple hv_Phi, HTuple hv_Length1,
|
HTuple hv_Length2, out HTuple hv_TopLeft_Row, out HTuple hv_TopLeft_Col, out HTuple hv_TopRight_Row,
|
out HTuple hv_TopRight_Col, out HTuple hv_LowLeft_Row, out HTuple hv_LowLeft_Col,
|
out HTuple hv_LowRight_Row, out HTuple hv_LowRight_Col)
|
{
|
// Local iconic variables
|
|
// Local control variables
|
|
HTuple hv_Tmp = new HTuple(), hv_Sin = new HTuple();
|
HTuple hv_Cos = new HTuple(), hv_TopLeft_X = new HTuple();
|
HTuple hv_TopLeft_Y = new HTuple(), hv_TopRight_X = new HTuple();
|
HTuple hv_TopRight_Y = new HTuple(), hv_LowerRight_X = new HTuple();
|
HTuple hv_LowerRight_Y = new HTuple(), hv_LowerLeft_X = new HTuple();
|
HTuple hv_LowerLeft_Y = new HTuple();
|
HTuple hv_Length1_COPY_INP_TMP = new HTuple(hv_Length1);
|
HTuple hv_Length2_COPY_INP_TMP = new HTuple(hv_Length2);
|
HTuple hv_Phi_COPY_INP_TMP = new HTuple(hv_Phi);
|
|
// Initialize local and output iconic variables
|
hv_TopLeft_Row = new HTuple();
|
hv_TopLeft_Col = new HTuple();
|
hv_TopRight_Row = new HTuple();
|
hv_TopRight_Col = new HTuple();
|
hv_LowLeft_Row = new HTuple();
|
hv_LowLeft_Col = new HTuple();
|
hv_LowRight_Row = new HTuple();
|
hv_LowRight_Col = new HTuple();
|
try
|
{
|
if ((int)(new HTuple(((((hv_Phi_COPY_INP_TMP.TupleDeg())).TupleAbs())).TupleGreater(
|
45))) != 0)
|
{
|
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_Phi = (((hv_Phi_COPY_INP_TMP.TupleDeg()
|
) - (90 * (hv_Phi_COPY_INP_TMP / (hv_Phi_COPY_INP_TMP.TupleAbs()))))).TupleRad()
|
;
|
hv_Phi_COPY_INP_TMP.Dispose();
|
hv_Phi_COPY_INP_TMP = ExpTmpLocalVar_Phi;
|
}
|
}
|
|
hv_Tmp.Dispose();
|
hv_Tmp = new HTuple(hv_Length1_COPY_INP_TMP);
|
|
hv_Length1_COPY_INP_TMP.Dispose();
|
hv_Length1_COPY_INP_TMP = new HTuple(hv_Length2_COPY_INP_TMP);
|
|
hv_Length2_COPY_INP_TMP.Dispose();
|
hv_Length2_COPY_INP_TMP = new HTuple(hv_Tmp);
|
|
}
|
|
hv_Sin.Dispose();
|
HOperatorSet.TupleSin(hv_Phi_COPY_INP_TMP, out hv_Sin);
|
|
hv_Cos.Dispose();
|
HOperatorSet.TupleCos(hv_Phi_COPY_INP_TMP, out hv_Cos);
|
|
//左上角
|
|
hv_TopLeft_X.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TopLeft_X = ((-hv_Length1_COPY_INP_TMP) * hv_Cos) - (hv_Length2_COPY_INP_TMP * hv_Sin);
|
}
|
|
hv_TopLeft_Y.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TopLeft_Y = ((-hv_Length1_COPY_INP_TMP) * hv_Sin) + (hv_Length2_COPY_INP_TMP * hv_Cos);
|
}
|
|
hv_TopLeft_Row.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TopLeft_Row = hv_Row - hv_TopLeft_Y;
|
}
|
|
hv_TopLeft_Col.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TopLeft_Col = hv_Column + hv_TopLeft_X;
|
}
|
|
//右上角
|
|
hv_TopRight_X.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TopRight_X = (hv_Length1_COPY_INP_TMP * hv_Cos) - (hv_Length2_COPY_INP_TMP * hv_Sin);
|
}
|
|
hv_TopRight_Y.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TopRight_Y = (hv_Length1_COPY_INP_TMP * hv_Sin) + (hv_Length2_COPY_INP_TMP * hv_Cos);
|
}
|
|
hv_TopRight_Row.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TopRight_Row = hv_Row - hv_TopRight_Y;
|
}
|
|
hv_TopRight_Col.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_TopRight_Col = hv_Column + hv_TopRight_X;
|
}
|
|
//右下角
|
|
hv_LowerRight_X.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_LowerRight_X = (hv_Length1_COPY_INP_TMP * hv_Cos) + (hv_Length2_COPY_INP_TMP * hv_Sin);
|
}
|
|
hv_LowerRight_Y.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_LowerRight_Y = (hv_Length1_COPY_INP_TMP * hv_Sin) - (hv_Length2_COPY_INP_TMP * hv_Cos);
|
}
|
|
hv_LowRight_Row.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_LowRight_Row = hv_Row - hv_LowerRight_Y;
|
}
|
|
hv_LowRight_Col.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_LowRight_Col = hv_Column + hv_LowerRight_X;
|
}
|
|
//左下角
|
|
hv_LowerLeft_X.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_LowerLeft_X = ((-hv_Length1_COPY_INP_TMP) * hv_Cos) + (hv_Length2_COPY_INP_TMP * hv_Sin);
|
}
|
|
hv_LowerLeft_Y.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_LowerLeft_Y = ((-hv_Length1_COPY_INP_TMP) * hv_Sin) - (hv_Length2_COPY_INP_TMP * hv_Cos);
|
}
|
|
hv_LowLeft_Row.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_LowLeft_Row = hv_Row - hv_LowerLeft_Y;
|
}
|
|
hv_LowLeft_Col.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_LowLeft_Col = hv_Column + hv_LowerLeft_X;
|
}
|
|
|
hv_Length1_COPY_INP_TMP.Dispose();
|
hv_Length2_COPY_INP_TMP.Dispose();
|
hv_Phi_COPY_INP_TMP.Dispose();
|
hv_Tmp.Dispose();
|
hv_Sin.Dispose();
|
hv_Cos.Dispose();
|
hv_TopLeft_X.Dispose();
|
hv_TopLeft_Y.Dispose();
|
hv_TopRight_X.Dispose();
|
hv_TopRight_Y.Dispose();
|
hv_LowerRight_X.Dispose();
|
hv_LowerRight_Y.Dispose();
|
hv_LowerLeft_X.Dispose();
|
hv_LowerLeft_Y.Dispose();
|
|
return;
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
|
hv_Length1_COPY_INP_TMP.Dispose();
|
hv_Length2_COPY_INP_TMP.Dispose();
|
hv_Phi_COPY_INP_TMP.Dispose();
|
hv_Tmp.Dispose();
|
hv_Sin.Dispose();
|
hv_Cos.Dispose();
|
hv_TopLeft_X.Dispose();
|
hv_TopLeft_Y.Dispose();
|
hv_TopRight_X.Dispose();
|
hv_TopRight_Y.Dispose();
|
hv_LowerRight_X.Dispose();
|
hv_LowerRight_Y.Dispose();
|
hv_LowerLeft_X.Dispose();
|
hv_LowerLeft_Y.Dispose();
|
|
throw HDevExpDefaultException;
|
}
|
}
|
|
public static void pts_to_best_line(out HObject ho_LineXld, HTuple hv_Rows, HTuple hv_Columns,
|
HTuple hv_IgnoreNum, out HTuple hv_Row1, out HTuple hv_Column1, out HTuple hv_Row2,
|
out HTuple hv_Column2)
|
{
|
// Local iconic variables
|
|
HObject ho_Contour = null;
|
|
// Local control variables
|
|
HTuple hv_Length = new HTuple(), hv_Nr = new HTuple();
|
HTuple hv_Nc = new HTuple(), hv_Dist = new HTuple(), hv_Length1 = new HTuple();
|
// Initialize local and output iconic variables
|
HOperatorSet.GenEmptyObj(out ho_LineXld);
|
HOperatorSet.GenEmptyObj(out ho_Contour);
|
hv_Row1 = new HTuple();
|
hv_Column1 = new HTuple();
|
hv_Row2 = new HTuple();
|
hv_Column2 = new HTuple();
|
try
|
{
|
//初始化
|
hv_Row1.Dispose();
|
hv_Row1 = 0;
|
hv_Column1.Dispose();
|
hv_Column1 = 0;
|
hv_Row2.Dispose();
|
hv_Row2 = 0;
|
hv_Column2.Dispose();
|
hv_Column2 = 0;
|
//产生一个空的直线对象,用于保存拟合后的直线
|
ho_LineXld.Dispose();
|
HOperatorSet.GenEmptyObj(out ho_LineXld);
|
//计算边缘数量
|
hv_Length.Dispose();
|
HOperatorSet.TupleLength(hv_Columns, out hv_Length);
|
//当边缘数量不小于有效点数时进行拟合
|
if ((int)((new HTuple(hv_Length.TupleGreaterEqual(2))).TupleAnd(new HTuple(hv_IgnoreNum.TupleLess(
|
hv_Length - 2)))) != 0)
|
{
|
//halcon的拟合是基于xld的,需要把边缘连接成xld
|
ho_Contour.Dispose();
|
HOperatorSet.GenContourPolygonXld(out ho_Contour, hv_Rows, hv_Columns);
|
//拟合直线。使用的算法是'tukey',其他算法参考fit_line_contour_xld的描述
|
hv_Row1.Dispose(); hv_Column1.Dispose(); hv_Row2.Dispose(); hv_Column2.Dispose(); hv_Nr.Dispose(); hv_Nc.Dispose(); hv_Dist.Dispose();
|
HOperatorSet.FitLineContourXld(ho_Contour, "tukey", -1, hv_IgnoreNum, 5,
|
2, out hv_Row1, out hv_Column1, out hv_Row2, out hv_Column2, out hv_Nr,
|
out hv_Nc, out hv_Dist);
|
//判断拟合结果是否有效:如果拟合成功,数组中元素的数量大于0
|
hv_Length1.Dispose();
|
HOperatorSet.TupleLength(hv_Dist, out hv_Length1);
|
if ((int)(new HTuple(hv_Length1.TupleLess(1))) != 0)
|
{
|
ho_Contour.Dispose();
|
|
hv_Length.Dispose();
|
hv_Nr.Dispose();
|
hv_Nc.Dispose();
|
hv_Dist.Dispose();
|
hv_Length1.Dispose();
|
|
return;
|
}
|
//根据拟合结果,产生直线xld
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
ho_LineXld.Dispose();
|
HOperatorSet.GenContourPolygonXld(out ho_LineXld, hv_Row1.TupleConcat(hv_Row2),
|
hv_Column1.TupleConcat(hv_Column2));
|
}
|
}
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
ho_Contour.Dispose();
|
|
hv_Length.Dispose();
|
hv_Nr.Dispose();
|
hv_Nc.Dispose();
|
hv_Dist.Dispose();
|
hv_Length1.Dispose();
|
|
throw HDevExpDefaultException;
|
}
|
}
|
|
public static (double, double) CalculateTailValues(HTuple minValue, HTuple maxValue, HTuple mean, HTuple deviation, double tailPercentage = 0.3)
|
{
|
// 计算低尾灰度值
|
double lowTailValue = minValue.TupleReal() + (mean.TupleReal() - minValue.TupleReal()) * tailPercentage;
|
if (lowTailValue == 0)
|
lowTailValue = mean.TupleReal();
|
|
// 计算高尾灰度值
|
double highTailValue = maxValue.TupleReal() - (maxValue.TupleReal() - mean.TupleReal()) * tailPercentage;
|
if (highTailValue == 0)
|
highTailValue = mean.TupleReal();
|
|
return (highTailValue, lowTailValue);
|
}
|
|
/// <summary>
|
/// 图像增强算法-边缘增强
|
/// </summary>
|
/// <param name="ho_Image">待测图片</param>
|
/// <param name="hv_Wid">掩膜宽</param>
|
/// <param name="hv_High">掩膜高</param>
|
/// <param name="hv_Fac">增强因子</param>
|
/// <param name="hv_Row1">起始纵坐标</param>
|
/// <param name="hv_Column1">起始横坐标</param>
|
/// <param name="hv_Row2">结束纵坐标</param>
|
/// <param name="hv_Column2">结束横坐标</param>
|
public static void Emphsize(HObject ho_Image, out HObject ho_OutImage, HTuple hv_ImageEnhancementType, HTuple hv_Wid, HTuple hv_High, HTuple hv_Fac)
|
{
|
HOperatorSet.GenEmptyObj(out ho_OutImage);
|
try
|
{
|
HTuple hv_ImageEnhancementTypeOut = new HTuple();
|
hv_ImageEnhancementTypeOut.Dispose();
|
hv_ImageEnhancementTypeOut = new HTuple(hv_ImageEnhancementType);
|
|
hv_Wid.Dispose();
|
hv_High.Dispose();
|
ho_OutImage.Dispose();
|
|
//设置图像增强算法
|
if ((int)(new HTuple(hv_ImageEnhancementTypeOut.TupleEqual("emphasize"))) != 0)
|
{
|
hv_ImageEnhancementTypeOut.Dispose();
|
hv_ImageEnhancementTypeOut = "emphasize";
|
HOperatorSet.Emphasize(ho_Image, out ho_OutImage, hv_Wid, hv_High, hv_Fac);
|
}
|
else if ((int)(new HTuple(hv_ImageEnhancementTypeOut.TupleEqual("equHisto"))) != 0)
|
{
|
hv_ImageEnhancementTypeOut.Dispose();
|
hv_ImageEnhancementTypeOut = "equHisto";
|
|
}
|
else
|
{
|
hv_ImageEnhancementTypeOut.Dispose();
|
hv_ImageEnhancementTypeOut = "scaleMax";
|
}
|
|
|
|
HOperatorSet.EquHistoImage(ho_Image, out ho_OutImage);
|
|
|
return;
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
|
hv_Wid.Dispose();
|
hv_High.Dispose();
|
|
throw HDevExpDefaultException;
|
}
|
}
|
/// <summary>
|
/// 图像增强算法-比例增强
|
/// </summary>
|
/// <param name="ho_Image">待测图片</param>
|
/// <param name="hv_Wid">掩膜宽</param>
|
public static void ScaleImageMax(HObject ho_Image, out HObject ho_OutImage)
|
{
|
HOperatorSet.GenEmptyObj(out ho_OutImage);
|
try
|
{
|
ho_OutImage.Dispose();
|
HOperatorSet.ScaleImageMax(ho_Image, out ho_OutImage);
|
return;
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
throw HDevExpDefaultException;
|
}
|
}
|
/// <summary>
|
/// 图像增强算法-直方图均衡化
|
/// </summary>
|
/// <param name="ho_Image">待测图片</param>
|
/// <param name="hv_Wid">掩膜宽</param>
|
public static void EquHistoImage(HObject ho_Image, out HObject ho_OutImage)
|
{
|
HOperatorSet.GenEmptyObj(out ho_OutImage);
|
try
|
{
|
ho_OutImage.Dispose();
|
HOperatorSet.EquHistoImage(ho_Image, out ho_OutImage);
|
return;
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
throw HDevExpDefaultException;
|
}
|
}
|
|
/// <summary>
|
/// 卡尺算法
|
/// </summary>
|
/// <param name="ho_Image">待测图片</param>
|
/// <param name="ho_Regions">测量卡尺区域显示</param>
|
/// <param name="hv_Elements">卡尺个数</param>
|
/// <param name="hv_DetectHeight">卡尺长度</param>
|
/// <param name="hv_DetectWidth">卡尺宽度</param>
|
/// <param name="hv_Sigma">过滤一半像素(推荐值:2)</param>
|
/// <param name="hv_Threshold">对比度阈值(推荐值:5)</param>
|
/// <param name="hv_Transition">极性(negative/positive/ignore)</param>
|
/// <param name="hv_Select">边缘位置(first/last/best)</param>
|
/// <param name="hv_Row1">起始纵坐标</param>
|
/// <param name="hv_Column1">起始横坐标</param>
|
/// <param name="hv_Row2">结束纵坐标</param>
|
/// <param name="hv_Column2">结束横坐标</param>
|
/// <param name="hv_ResultRow">结果点集合纵坐标</param>
|
/// <param name="hv_ResultColumn">结果点集合横坐标</param>
|
public static void Rake(HObject ho_Image, out HObject ho_Regions, HTuple hv_Elements,
|
HTuple hv_DetectHeight, HTuple hv_DetectWidth, HTuple hv_Sigma, HTuple hv_Threshold,
|
HTuple hv_Transition, HTuple hv_Select, HTuple hv_Row1, HTuple hv_Column1, HTuple hv_Row2,
|
HTuple hv_Column2, out HTuple hv_ResultRow, out HTuple hv_ResultColumn)
|
{
|
// Stack for temporary objects
|
HObject[] OTemp = new HObject[20];
|
|
// Local iconic variables
|
|
HObject ho_RegionLines = null, ho_Rectangle = null;
|
HObject ho_Arrow1 = null;
|
HObject ExpTmpOutVar_0 = null;
|
|
// Local control variables
|
|
HTuple hv_SelectOut = new HTuple(), hv_TransitionOut = new HTuple();
|
HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
|
HTuple hv_ATan = new HTuple(), hv_i = new HTuple(), hv_RowC = new HTuple();
|
HTuple hv_ColC = new HTuple(), hv_Distance = new HTuple();
|
HTuple hv_RowL2 = new HTuple(), hv_RowL1 = new HTuple();
|
HTuple hv_ColL2 = new HTuple(), hv_ColL1 = new HTuple();
|
HTuple hv_MeasureHandle = new HTuple(), hv_RowEdge = new HTuple();
|
HTuple hv_ColEdge = new HTuple(), hv_Amplitude = new HTuple();
|
HTuple hv_tRow = new HTuple(), hv_tCol = new HTuple();
|
HTuple hv_t = new HTuple(), hv_Number = new HTuple(), hv_j = new HTuple();
|
HTuple hv_DetectWidth_COPY_INP_TMP = new HTuple(hv_DetectWidth);
|
|
// Initialize local and output iconic variables
|
HOperatorSet.GenEmptyObj(out ho_Regions);
|
HOperatorSet.GenEmptyObj(out ho_RegionLines);
|
HOperatorSet.GenEmptyObj(out ho_Rectangle);
|
HOperatorSet.GenEmptyObj(out ho_Arrow1);
|
HOperatorSet.GenEmptyObj(out ExpTmpOutVar_0);
|
hv_ResultRow = new HTuple();
|
hv_ResultColumn = new HTuple();
|
try
|
{
|
hv_SelectOut.Dispose();
|
hv_SelectOut = new HTuple(hv_Select);
|
|
hv_TransitionOut.Dispose();
|
hv_TransitionOut = new HTuple(hv_Transition);
|
|
//获取图像尺寸
|
hv_Width.Dispose(); hv_Height.Dispose();
|
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
|
|
//产生一个空显示对象,用于显示
|
ho_Regions.Dispose();
|
HOperatorSet.GenEmptyObj(out ho_Regions);
|
|
//初始化边缘坐标数组
|
hv_ResultRow.Dispose();
|
hv_ResultRow = new HTuple();
|
|
hv_ResultColumn.Dispose();
|
hv_ResultColumn = new HTuple();
|
|
//产生直线xld
|
//using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
//{
|
// ho_RegionLines.Dispose();
|
// HOperatorSet.GenContourPolygonXld(out ho_RegionLines, hv_Row1.TupleConcat(hv_Row2),
|
// hv_Column1.TupleConcat(hv_Column2));
|
//}
|
|
//存储到显示对象
|
HOperatorSet.ConcatObj(ho_Regions, ho_RegionLines, out ExpTmpOutVar_0);
|
ho_Regions.Dispose();
|
ho_Regions = ExpTmpOutVar_0;
|
|
//计算直线与x轴的夹角,逆时针方向为正向
|
hv_ATan.Dispose();
|
HOperatorSet.AngleLx(hv_Row1, hv_Column1, hv_Row2, hv_Column2, out hv_ATan);
|
|
//边缘检测方向垂直由于检测直线:直线方向正向旋转90°为边缘检测方向
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_ATan = hv_ATan + ((new HTuple(90)).TupleRad()
|
);
|
hv_ATan.Dispose();
|
hv_ATan = ExpTmpLocalVar_ATan;
|
}
|
}
|
|
//根据检测直线按顺序产生测量区域矩形,并存储到显示对象
|
HTuple end_val36 = hv_Elements;
|
HTuple step_val36 = 1;
|
for (hv_i = 1; hv_i.Continue(end_val36, step_val36); hv_i = hv_i.TupleAdd(step_val36))
|
{
|
//如果只有一个测量矩形,作为卡尺工具,宽度为检测直线的长度
|
if ((int)(new HTuple(hv_Elements.TupleEqual(1))) != 0)
|
{
|
|
hv_RowC.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_RowC = (hv_Row1 + hv_Row2) * 0.5;
|
}
|
|
hv_ColC.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ColC = (hv_Column1 + hv_Column2) * 0.5;
|
}
|
|
//判断是否超出图像,超出不检测边缘
|
if ((int)((new HTuple((new HTuple((new HTuple(hv_RowC.TupleGreater(hv_Height - 1))).TupleOr(
|
new HTuple(hv_RowC.TupleLess(0))))).TupleOr(new HTuple(hv_ColC.TupleGreater(
|
hv_Width - 1))))).TupleOr(new HTuple(hv_ColC.TupleLess(0)))) != 0)
|
continue;
|
|
hv_Distance.Dispose();
|
HOperatorSet.DistancePp(hv_Row1, hv_Column1, hv_Row2, hv_Column2, out hv_Distance);
|
|
hv_DetectWidth_COPY_INP_TMP.Dispose();
|
hv_DetectWidth_COPY_INP_TMP = new HTuple(hv_Distance);
|
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
ho_Rectangle.Dispose();
|
HOperatorSet.GenRectangle2ContourXld(out ho_Rectangle, hv_RowC, hv_ColC,
|
hv_ATan, hv_DetectHeight / 2, hv_Distance / 2);
|
}
|
|
}
|
else
|
{
|
//如果有多个测量矩形,产生该测量矩形xld
|
hv_RowC.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_RowC = hv_Row1 + (((hv_Row2 - hv_Row1) * (hv_i - 1)) / (hv_Elements - 1));
|
}
|
|
hv_ColC.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ColC = hv_Column1 + (((hv_Column2 - hv_Column1) * (hv_i - 1)) / (hv_Elements - 1));
|
}
|
|
//判断是否超出图像,超出不检测边缘
|
if ((int)((new HTuple((new HTuple((new HTuple(hv_RowC.TupleGreater(hv_Height - 1))).TupleOr(
|
new HTuple(hv_RowC.TupleLess(0))))).TupleOr(new HTuple(hv_ColC.TupleGreater(
|
hv_Width - 1))))).TupleOr(new HTuple(hv_ColC.TupleLess(0)))) != 0)
|
continue;
|
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
ho_Rectangle.Dispose();
|
HOperatorSet.GenRectangle2ContourXld(out ho_Rectangle, hv_RowC, hv_ColC,
|
hv_ATan, hv_DetectHeight / 2, hv_DetectWidth_COPY_INP_TMP / 2);
|
}
|
|
}
|
|
//把测量矩形xld存储到显示对象
|
HOperatorSet.ConcatObj(ho_Regions, ho_Rectangle, out ExpTmpOutVar_0);
|
ho_Regions.Dispose();
|
ho_Regions = ExpTmpOutVar_0;
|
|
if ((int)(new HTuple(hv_i.TupleEqual(1))) != 0)
|
{
|
|
//在第一个测量矩形绘制一个箭头xld,用于指示边缘检测方向
|
hv_RowL2.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_RowL2 = hv_RowC + ((hv_DetectHeight / 2) * (((-hv_ATan)).TupleSin()
|
));
|
}
|
|
hv_RowL1.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_RowL1 = hv_RowC - ((hv_DetectHeight / 2) * (((-hv_ATan)).TupleSin()
|
));
|
}
|
|
hv_ColL2.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ColL2 = hv_ColC + ((hv_DetectHeight / 2) * (((-hv_ATan)).TupleCos()
|
));
|
}
|
|
hv_ColL1.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ColL1 = hv_ColC - ((hv_DetectHeight / 2) * (((-hv_ATan)).TupleCos()
|
));
|
}
|
|
//ho_Arrow1.Dispose();
|
//gen_arrow_contour_xld(out ho_Arrow1, hv_RowL1, hv_ColL1, hv_RowL2, hv_ColL2,
|
// 25, 25);
|
|
////把xld存储到显示对象
|
//HOperatorSet.ConcatObj(ho_Regions, ho_Arrow1, out ExpTmpOutVar_0);
|
//ho_Regions.Dispose();
|
//ho_Regions = ExpTmpOutVar_0;
|
}
|
|
//产生测量对象句柄
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_MeasureHandle.Dispose();
|
HOperatorSet.GenMeasureRectangle2(hv_RowC, hv_ColC, hv_ATan, hv_DetectHeight / 2,
|
hv_DetectWidth_COPY_INP_TMP / 2, hv_Width, hv_Height, "nearest_neighbor",
|
out hv_MeasureHandle);
|
}
|
|
//设置极性
|
if ((int)(new HTuple(hv_TransitionOut.TupleEqual("negative"))) != 0)
|
{
|
hv_TransitionOut.Dispose();
|
hv_TransitionOut = "negative";
|
}
|
else if ((int)(new HTuple(hv_TransitionOut.TupleEqual("positive"))) != 0)
|
{
|
hv_TransitionOut.Dispose();
|
hv_TransitionOut = "positive";
|
}
|
else
|
{
|
hv_TransitionOut.Dispose();
|
hv_TransitionOut = "all";
|
}
|
|
//设置边缘位置,最强点是从所有边缘中选择幅度绝对值对大点,需要设置为'all'
|
if ((int)(new HTuple(hv_SelectOut.TupleEqual("first"))) != 0)
|
{
|
hv_SelectOut.Dispose();
|
hv_SelectOut = "first";
|
}
|
else if ((int)(new HTuple(hv_SelectOut.TupleEqual("last"))) != 0)
|
{
|
hv_SelectOut.Dispose();
|
hv_SelectOut = "last";
|
}
|
else
|
{
|
hv_SelectOut.Dispose();
|
hv_SelectOut = "all";
|
}
|
|
//检测边缘
|
hv_RowEdge.Dispose(); hv_ColEdge.Dispose(); hv_Amplitude.Dispose(); hv_Distance.Dispose();
|
HOperatorSet.MeasurePos(ho_Image, hv_MeasureHandle, hv_Sigma, hv_Threshold,
|
hv_TransitionOut, hv_SelectOut, out hv_RowEdge, out hv_ColEdge, out hv_Amplitude,
|
out hv_Distance);
|
|
//清除测量对象句柄
|
HOperatorSet.CloseMeasure(hv_MeasureHandle);
|
|
//临时变量初始化
|
|
//保存找到指定边缘的坐标
|
hv_tRow.Dispose();
|
hv_tRow = 0;
|
|
hv_tCol.Dispose();
|
hv_tCol = 0;
|
|
//保存边缘的幅度绝对值
|
hv_t.Dispose();
|
hv_t = 0;
|
|
//找到的边缘必须至少为1个
|
hv_Number.Dispose();
|
HOperatorSet.TupleLength(hv_RowEdge, out hv_Number);
|
|
if ((int)(new HTuple(hv_Number.TupleLess(1))) != 0)
|
continue;
|
|
|
//有多个边缘时,选择幅度绝对之后最大的边缘
|
HTuple end_val178 = hv_Number - 1;
|
HTuple step_val178 = 1;
|
for (hv_j = 0; hv_j.Continue(end_val178, step_val178); hv_j = hv_j.TupleAdd(step_val178))
|
{
|
|
if ((int)(new HTuple(((((hv_Amplitude.TupleSelect(hv_j))).TupleAbs())).TupleGreater(
|
hv_t))) != 0)
|
{
|
|
hv_tRow.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_tRow = hv_RowEdge.TupleSelect(
|
hv_j);
|
}
|
|
hv_tCol.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_tCol = hv_ColEdge.TupleSelect(
|
hv_j);
|
}
|
|
hv_t.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_t = hv_Amplitude.TupleAbs()
|
;
|
}
|
|
}
|
|
}
|
|
//把找到的边缘保存在输出数组
|
|
if ((int)(new HTuple(hv_t.TupleGreater(0))) != 0)
|
{
|
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_ResultRow = hv_ResultRow.TupleConcat(
|
hv_tRow);
|
hv_ResultRow.Dispose();
|
hv_ResultRow = ExpTmpLocalVar_ResultRow;
|
}
|
}
|
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_ResultColumn = hv_ResultColumn.TupleConcat(
|
hv_tCol);
|
hv_ResultColumn.Dispose();
|
hv_ResultColumn = ExpTmpLocalVar_ResultColumn;
|
}
|
}
|
|
}
|
|
}
|
|
ho_RegionLines.Dispose();
|
ho_Rectangle.Dispose();
|
ho_Arrow1.Dispose();
|
|
hv_DetectWidth_COPY_INP_TMP.Dispose();
|
hv_SelectOut.Dispose();
|
hv_TransitionOut.Dispose();
|
hv_Width.Dispose();
|
hv_Height.Dispose();
|
hv_ATan.Dispose();
|
hv_i.Dispose();
|
hv_RowC.Dispose();
|
hv_ColC.Dispose();
|
hv_Distance.Dispose();
|
hv_RowL2.Dispose();
|
hv_RowL1.Dispose();
|
hv_ColL2.Dispose();
|
hv_ColL1.Dispose();
|
hv_MeasureHandle.Dispose();
|
hv_RowEdge.Dispose();
|
hv_ColEdge.Dispose();
|
hv_Amplitude.Dispose();
|
hv_tRow.Dispose();
|
hv_tCol.Dispose();
|
hv_t.Dispose();
|
hv_Number.Dispose();
|
hv_j.Dispose();
|
|
return;
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
ho_RegionLines.Dispose();
|
ho_Rectangle.Dispose();
|
ho_Arrow1.Dispose();
|
|
hv_DetectWidth_COPY_INP_TMP.Dispose();
|
hv_SelectOut.Dispose();
|
hv_TransitionOut.Dispose();
|
hv_Width.Dispose();
|
hv_Height.Dispose();
|
hv_ATan.Dispose();
|
hv_i.Dispose();
|
hv_RowC.Dispose();
|
hv_ColC.Dispose();
|
hv_Distance.Dispose();
|
hv_RowL2.Dispose();
|
hv_RowL1.Dispose();
|
hv_ColL2.Dispose();
|
hv_ColL1.Dispose();
|
hv_MeasureHandle.Dispose();
|
hv_RowEdge.Dispose();
|
hv_ColEdge.Dispose();
|
hv_Amplitude.Dispose();
|
hv_tRow.Dispose();
|
hv_tCol.Dispose();
|
hv_t.Dispose();
|
hv_Number.Dispose();
|
hv_j.Dispose();
|
|
throw HDevExpDefaultException;
|
}
|
}
|
|
public static void GetRakeRegions(HObject ho_Image, out HObject ho_Regions, HTuple hv_Elements,
|
HTuple hv_DetectHeight, HTuple hv_DetectWidth, HTuple hv_Sigma, HTuple hv_Threshold,
|
HTuple hv_Transition, HTuple hv_Select, HTuple hv_Row1, HTuple hv_Column1, HTuple hv_Row2,
|
HTuple hv_Column2, out HTuple hv_ResultRow, out HTuple hv_ResultColumn)
|
{
|
// Stack for temporary objects
|
HObject[] OTemp = new HObject[20];
|
|
// Local iconic variables
|
|
HObject ho_RegionLines = null, ho_Rectangle = null;
|
HObject ho_Arrow1 = null;
|
HObject ExpTmpOutVar_0 = null;
|
|
// Local control variables
|
|
HTuple hv_SelectOut = new HTuple(), hv_TransitionOut = new HTuple();
|
HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
|
HTuple hv_ATan = new HTuple(), hv_i = new HTuple(), hv_RowC = new HTuple();
|
HTuple hv_ColC = new HTuple(), hv_Distance = new HTuple();
|
HTuple hv_RowL2 = new HTuple(), hv_RowL1 = new HTuple();
|
HTuple hv_ColL2 = new HTuple(), hv_ColL1 = new HTuple();
|
HTuple hv_MeasureHandle = new HTuple(), hv_RowEdge = new HTuple();
|
HTuple hv_ColEdge = new HTuple(), hv_Amplitude = new HTuple();
|
HTuple hv_tRow = new HTuple(), hv_tCol = new HTuple();
|
HTuple hv_t = new HTuple(), hv_Number = new HTuple(), hv_j = new HTuple();
|
HTuple hv_DetectWidth_COPY_INP_TMP = new HTuple(hv_DetectWidth);
|
|
// Initialize local and output iconic variables
|
HOperatorSet.GenEmptyObj(out ho_Regions);
|
HOperatorSet.GenEmptyObj(out ho_RegionLines);
|
HOperatorSet.GenEmptyObj(out ho_Rectangle);
|
HOperatorSet.GenEmptyObj(out ho_Arrow1);
|
HOperatorSet.GenEmptyObj(out ExpTmpOutVar_0);
|
hv_ResultRow = new HTuple();
|
hv_ResultColumn = new HTuple();
|
try
|
{
|
hv_SelectOut.Dispose();
|
hv_SelectOut = new HTuple(hv_Select);
|
|
hv_TransitionOut.Dispose();
|
hv_TransitionOut = new HTuple(hv_Transition);
|
|
//获取图像尺寸
|
hv_Width.Dispose(); hv_Height.Dispose();
|
//HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
|
|
//产生一个空显示对象,用于显示
|
ho_Regions.Dispose();
|
HOperatorSet.GenEmptyObj(out ho_Regions);
|
|
//初始化边缘坐标数组
|
hv_ResultRow.Dispose();
|
hv_ResultRow = new HTuple();
|
|
hv_ResultColumn.Dispose();
|
hv_ResultColumn = new HTuple();
|
|
//产生直线xld
|
//using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
//{
|
// ho_RegionLines.Dispose();
|
// HOperatorSet.GenContourPolygonXld(out ho_RegionLines, hv_Row1.TupleConcat(hv_Row2),
|
// hv_Column1.TupleConcat(hv_Column2));
|
//}
|
|
//存储到显示对象
|
HOperatorSet.ConcatObj(ho_Regions, ho_RegionLines, out ExpTmpOutVar_0);
|
ho_Regions.Dispose();
|
ho_Regions = ExpTmpOutVar_0;
|
|
//计算直线与x轴的夹角,逆时针方向为正向
|
hv_ATan.Dispose();
|
HOperatorSet.AngleLx(hv_Row1, hv_Column1, hv_Row2, hv_Column2, out hv_ATan);
|
|
//边缘检测方向垂直由于检测直线:直线方向正向旋转90°为边缘检测方向
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_ATan = hv_ATan + ((new HTuple(90)).TupleRad()
|
);
|
hv_ATan.Dispose();
|
hv_ATan = ExpTmpLocalVar_ATan;
|
}
|
}
|
|
//根据检测直线按顺序产生测量区域矩形,并存储到显示对象
|
HTuple end_val36 = hv_Elements;
|
HTuple step_val36 = 1;
|
for (hv_i = 1; hv_i.Continue(end_val36, step_val36); hv_i = hv_i.TupleAdd(step_val36))
|
{
|
//如果只有一个测量矩形,作为卡尺工具,宽度为检测直线的长度
|
if ((int)(new HTuple(hv_Elements.TupleEqual(1))) != 0)
|
{
|
|
hv_RowC.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_RowC = (hv_Row1 + hv_Row2) * 0.5;
|
}
|
|
hv_ColC.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ColC = (hv_Column1 + hv_Column2) * 0.5;
|
}
|
|
////判断是否超出图像,超出不检测边缘
|
//if ((int)((new HTuple((new HTuple((new HTuple(hv_RowC.TupleGreater(hv_Height - 1))).TupleOr(
|
// new HTuple(hv_RowC.TupleLess(0))))).TupleOr(new HTuple(hv_ColC.TupleGreater(
|
// hv_Width - 1))))).TupleOr(new HTuple(hv_ColC.TupleLess(0)))) != 0)
|
// continue;
|
|
hv_Distance.Dispose();
|
HOperatorSet.DistancePp(hv_Row1, hv_Column1, hv_Row2, hv_Column2, out hv_Distance);
|
|
hv_DetectWidth_COPY_INP_TMP.Dispose();
|
hv_DetectWidth_COPY_INP_TMP = new HTuple(hv_Distance);
|
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
ho_Rectangle.Dispose();
|
HOperatorSet.GenRectangle2ContourXld(out ho_Rectangle, hv_RowC, hv_ColC,
|
hv_ATan, hv_DetectHeight / 2, hv_Distance / 2);
|
}
|
}
|
else
|
{
|
//如果有多个测量矩形,产生该测量矩形xld
|
hv_RowC.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_RowC = hv_Row1 + (((hv_Row2 - hv_Row1) * (hv_i - 1)) / (hv_Elements - 1));
|
}
|
|
hv_ColC.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_ColC = hv_Column1 + (((hv_Column2 - hv_Column1) * (hv_i - 1)) / (hv_Elements - 1));
|
}
|
|
////判断是否超出图像,超出不检测边缘
|
//if ((int)((new HTuple((new HTuple((new HTuple(hv_RowC.TupleGreater(hv_Height - 1))).TupleOr(
|
// new HTuple(hv_RowC.TupleLess(0))))).TupleOr(new HTuple(hv_ColC.TupleGreater(
|
// hv_Width - 1))))).TupleOr(new HTuple(hv_ColC.TupleLess(0)))) != 0)
|
// continue;
|
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
ho_Rectangle.Dispose();
|
HOperatorSet.GenRectangle2ContourXld(out ho_Rectangle, hv_RowC, hv_ColC,
|
hv_ATan, hv_DetectHeight / 2, hv_DetectWidth_COPY_INP_TMP / 2);
|
}
|
|
}
|
|
//把测量矩形xld存储到显示对象
|
HOperatorSet.ConcatObj(ho_Regions, ho_Rectangle, out ExpTmpOutVar_0);
|
ho_Regions.Dispose();
|
ho_Regions = ExpTmpOutVar_0;
|
|
//保存找到指定边缘的坐标
|
hv_tRow.Dispose();
|
hv_tRow = 0;
|
|
hv_tCol.Dispose();
|
hv_tCol = 0;
|
|
//保存边缘的幅度绝对值
|
hv_t.Dispose();
|
hv_t = 0;
|
}
|
|
ho_RegionLines.Dispose();
|
ho_Rectangle.Dispose();
|
ho_Arrow1.Dispose();
|
|
hv_DetectWidth_COPY_INP_TMP.Dispose();
|
hv_SelectOut.Dispose();
|
hv_TransitionOut.Dispose();
|
hv_Width.Dispose();
|
hv_Height.Dispose();
|
hv_ATan.Dispose();
|
hv_i.Dispose();
|
hv_RowC.Dispose();
|
hv_ColC.Dispose();
|
hv_Distance.Dispose();
|
hv_RowL2.Dispose();
|
hv_RowL1.Dispose();
|
hv_ColL2.Dispose();
|
hv_ColL1.Dispose();
|
hv_MeasureHandle.Dispose();
|
hv_RowEdge.Dispose();
|
hv_ColEdge.Dispose();
|
hv_Amplitude.Dispose();
|
hv_tRow.Dispose();
|
hv_tCol.Dispose();
|
hv_t.Dispose();
|
hv_Number.Dispose();
|
hv_j.Dispose();
|
|
return;
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
ho_RegionLines.Dispose();
|
ho_Rectangle.Dispose();
|
ho_Arrow1.Dispose();
|
|
hv_DetectWidth_COPY_INP_TMP.Dispose();
|
hv_SelectOut.Dispose();
|
hv_TransitionOut.Dispose();
|
hv_Width.Dispose();
|
hv_Height.Dispose();
|
hv_ATan.Dispose();
|
hv_i.Dispose();
|
hv_RowC.Dispose();
|
hv_ColC.Dispose();
|
hv_Distance.Dispose();
|
hv_RowL2.Dispose();
|
hv_RowL1.Dispose();
|
hv_ColL2.Dispose();
|
hv_ColL1.Dispose();
|
hv_MeasureHandle.Dispose();
|
hv_RowEdge.Dispose();
|
hv_ColEdge.Dispose();
|
hv_Amplitude.Dispose();
|
hv_tRow.Dispose();
|
hv_tCol.Dispose();
|
hv_t.Dispose();
|
hv_Number.Dispose();
|
hv_j.Dispose();
|
|
throw HDevExpDefaultException;
|
}
|
}
|
|
/// <summary>
|
/// 显示符号
|
/// </summary>
|
/// <param name="hv_WindowHandle"></param>
|
/// <param name="hv_String"></param>
|
/// <param name="hv_CoordSystem"></param>
|
/// <param name="hv_Row"></param>
|
/// <param name="hv_Column"></param>
|
/// <param name="hv_Color"></param>
|
/// <param name="hv_Box"></param>
|
static void disp_message(HTuple hv_WindowHandle, HTuple hv_String, HTuple hv_CoordSystem, HTuple hv_Row, HTuple hv_Column, HTuple hv_Color, HTuple hv_Box)
|
{
|
// Local iconic variables
|
|
// Local control variables
|
|
HTuple hv_GenParamName = new HTuple(), hv_GenParamValue = new HTuple();
|
HTuple hv_Color_COPY_INP_TMP = new HTuple(hv_Color);
|
HTuple hv_Column_COPY_INP_TMP = new HTuple(hv_Column);
|
HTuple hv_CoordSystem_COPY_INP_TMP = new HTuple(hv_CoordSystem);
|
HTuple hv_Row_COPY_INP_TMP = new HTuple(hv_Row);
|
|
try
|
{
|
if ((int)new HTuple(hv_Row_COPY_INP_TMP.TupleEqual(new HTuple())).TupleOr(
|
new HTuple(hv_Column_COPY_INP_TMP.TupleEqual(new HTuple()))) != 0)
|
{
|
|
hv_Color_COPY_INP_TMP.Dispose();
|
hv_Column_COPY_INP_TMP.Dispose();
|
hv_CoordSystem_COPY_INP_TMP.Dispose();
|
hv_Row_COPY_INP_TMP.Dispose();
|
hv_GenParamName.Dispose();
|
hv_GenParamValue.Dispose();
|
|
return;
|
}
|
if ((int)new HTuple(hv_Row_COPY_INP_TMP.TupleEqual(-1)) != 0)
|
{
|
hv_Row_COPY_INP_TMP.Dispose();
|
hv_Row_COPY_INP_TMP = 12;
|
}
|
if ((int)new HTuple(hv_Column_COPY_INP_TMP.TupleEqual(-1)) != 0)
|
{
|
hv_Column_COPY_INP_TMP.Dispose();
|
hv_Column_COPY_INP_TMP = 12;
|
}
|
//
|
//Convert the parameter Box to generic parameters.
|
hv_GenParamName.Dispose();
|
hv_GenParamName = new HTuple();
|
hv_GenParamValue.Dispose();
|
hv_GenParamValue = new HTuple();
|
if ((int)new HTuple(new HTuple(hv_Box.TupleLength()).TupleGreater(0)) != 0)
|
{
|
if ((int)new HTuple(hv_Box.TupleSelect(0).TupleEqual("false")) != 0)
|
{
|
//Display no box
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamName = hv_GenParamName.TupleConcat(
|
"box");
|
hv_GenParamName.Dispose();
|
hv_GenParamName = ExpTmpLocalVar_GenParamName;
|
}
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamValue = hv_GenParamValue.TupleConcat(
|
"false");
|
hv_GenParamValue.Dispose();
|
hv_GenParamValue = ExpTmpLocalVar_GenParamValue;
|
}
|
}
|
}
|
else if ((int)new HTuple(hv_Box.TupleSelect(0).TupleNotEqual(
|
"true")) != 0)
|
{
|
//Set a color other than the default.
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamName = hv_GenParamName.TupleConcat(
|
"box_color");
|
hv_GenParamName.Dispose();
|
hv_GenParamName = ExpTmpLocalVar_GenParamName;
|
}
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamValue = hv_GenParamValue.TupleConcat(
|
hv_Box.TupleSelect(0));
|
hv_GenParamValue.Dispose();
|
hv_GenParamValue = ExpTmpLocalVar_GenParamValue;
|
}
|
}
|
}
|
}
|
if ((int)new HTuple(new HTuple(hv_Box.TupleLength()).TupleGreater(1)) != 0)
|
{
|
if ((int)new HTuple(hv_Box.TupleSelect(1).TupleEqual("false")) != 0)
|
{
|
//Display no shadow.
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamName = hv_GenParamName.TupleConcat(
|
"shadow");
|
hv_GenParamName.Dispose();
|
hv_GenParamName = ExpTmpLocalVar_GenParamName;
|
}
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamValue = hv_GenParamValue.TupleConcat(
|
"false");
|
hv_GenParamValue.Dispose();
|
hv_GenParamValue = ExpTmpLocalVar_GenParamValue;
|
}
|
}
|
}
|
else if ((int)new HTuple(hv_Box.TupleSelect(1).TupleNotEqual(
|
"true")) != 0)
|
{
|
//Set a shadow color other than the default.
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamName = hv_GenParamName.TupleConcat(
|
"shadow_color");
|
hv_GenParamName.Dispose();
|
hv_GenParamName = ExpTmpLocalVar_GenParamName;
|
}
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_GenParamValue = hv_GenParamValue.TupleConcat(
|
hv_Box.TupleSelect(1));
|
hv_GenParamValue.Dispose();
|
hv_GenParamValue = ExpTmpLocalVar_GenParamValue;
|
}
|
}
|
}
|
}
|
//Restore default CoordSystem behavior.
|
if ((int)new HTuple(hv_CoordSystem_COPY_INP_TMP.TupleNotEqual("window")) != 0)
|
{
|
hv_CoordSystem_COPY_INP_TMP.Dispose();
|
hv_CoordSystem_COPY_INP_TMP = "image";
|
}
|
//
|
if ((int)new HTuple(hv_Color_COPY_INP_TMP.TupleEqual("")) != 0)
|
{
|
//disp_text does not accept an empty string for Color.
|
hv_Color_COPY_INP_TMP.Dispose();
|
hv_Color_COPY_INP_TMP = new HTuple();
|
}
|
//
|
//HOperatorSet.DispText(hv_WindowHandle, hv_String, hv_CoordSystem_COPY_INP_TMP,
|
// hv_Row_COPY_INP_TMP, hv_Column_COPY_INP_TMP, hv_Color_COPY_INP_TMP, hv_GenParamName,hv_GenParamValue);
|
HOperatorSet.SetTposition(hv_WindowHandle, hv_Row_COPY_INP_TMP, hv_Column_COPY_INP_TMP);
|
HOperatorSet.WriteString(hv_WindowHandle, hv_String);
|
hv_Color_COPY_INP_TMP.Dispose();
|
hv_Column_COPY_INP_TMP.Dispose();
|
hv_CoordSystem_COPY_INP_TMP.Dispose();
|
hv_Row_COPY_INP_TMP.Dispose();
|
hv_GenParamName.Dispose();
|
hv_GenParamValue.Dispose();
|
|
return;
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
|
hv_Color_COPY_INP_TMP.Dispose();
|
hv_Column_COPY_INP_TMP.Dispose();
|
hv_CoordSystem_COPY_INP_TMP.Dispose();
|
hv_Row_COPY_INP_TMP.Dispose();
|
hv_GenParamName.Dispose();
|
hv_GenParamValue.Dispose();
|
|
throw HDevExpDefaultException;
|
}
|
}
|
|
/// <summary>
|
/// 设置符号大小
|
/// </summary>
|
/// <param name="hv_WindowHandle"></param>
|
/// <param name="hv_Size"></param>
|
/// <param name="hv_Font"></param>
|
/// <param name="hv_Bold"></param>
|
/// <param name="hv_Slant"></param>
|
public static void set_display_font(HTuple hv_WindowHandle, HTuple hv_Size, string hv_Font = "mono", string hv_Bold = "true", string hv_Slant = "false")
|
{
|
// Local iconic variables
|
|
// Local control variables
|
|
HTuple hv_OS = new HTuple(), hv_Fonts = new HTuple();
|
HTuple hv_Style = new HTuple(), hv_Exception = new HTuple();
|
HTuple hv_AvailableFonts = new HTuple(), hv_Fdx = new HTuple();
|
HTuple hv_Indices = new HTuple();
|
HTuple hv_Font_COPY_INP_TMP = new HTuple(hv_Font);
|
HTuple hv_Size_COPY_INP_TMP = new HTuple(hv_Size);
|
|
// Initialize local and output iconic variables
|
try
|
{
|
//This procedure sets the text font of the current window with
|
//the specified attributes.
|
//
|
//Input parameters:
|
//WindowHandle: The graphics window for which the font will be set
|
//Size: The font size. If Size=-1, the default of 16 is used.
|
//Bold: If set to 'true', a bold font is used
|
//Slant: If set to 'true', a slanted font is used
|
//
|
hv_OS.Dispose();
|
HOperatorSet.GetSystem("operating_system", out hv_OS);
|
if ((int)((new HTuple(hv_Size_COPY_INP_TMP.TupleEqual(new HTuple()))).TupleOr(
|
new HTuple(hv_Size_COPY_INP_TMP.TupleEqual(-1)))) != 0)
|
{
|
hv_Size_COPY_INP_TMP.Dispose();
|
hv_Size_COPY_INP_TMP = 16;
|
}
|
if ((int)(new HTuple(((hv_OS.TupleSubstr(0, 2))).TupleEqual("Win"))) != 0)
|
{
|
//Restore previous behaviour
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_Size = ((1.13677 * hv_Size_COPY_INP_TMP)).TupleInt()
|
;
|
hv_Size_COPY_INP_TMP.Dispose();
|
hv_Size_COPY_INP_TMP = ExpTmpLocalVar_Size;
|
}
|
}
|
}
|
else
|
{
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_Size = hv_Size_COPY_INP_TMP.TupleInt()
|
;
|
hv_Size_COPY_INP_TMP.Dispose();
|
hv_Size_COPY_INP_TMP = ExpTmpLocalVar_Size;
|
}
|
}
|
}
|
if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("Courier"))) != 0)
|
{
|
hv_Fonts.Dispose();
|
hv_Fonts = new HTuple();
|
hv_Fonts[0] = "Courier";
|
hv_Fonts[1] = "Courier 10 Pitch";
|
hv_Fonts[2] = "Courier New";
|
hv_Fonts[3] = "CourierNew";
|
hv_Fonts[4] = "Liberation Mono";
|
}
|
else if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("mono"))) != 0)
|
{
|
hv_Fonts.Dispose();
|
hv_Fonts = new HTuple();
|
hv_Fonts[0] = "Consolas";
|
hv_Fonts[1] = "Menlo";
|
hv_Fonts[2] = "Courier";
|
hv_Fonts[3] = "Courier 10 Pitch";
|
hv_Fonts[4] = "FreeMono";
|
hv_Fonts[5] = "Liberation Mono";
|
}
|
else if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("sans"))) != 0)
|
{
|
hv_Fonts.Dispose();
|
hv_Fonts = new HTuple();
|
hv_Fonts[0] = "Luxi Sans";
|
hv_Fonts[1] = "DejaVu Sans";
|
hv_Fonts[2] = "FreeSans";
|
hv_Fonts[3] = "Arial";
|
hv_Fonts[4] = "Liberation Sans";
|
}
|
else if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("serif"))) != 0)
|
{
|
hv_Fonts.Dispose();
|
hv_Fonts = new HTuple();
|
hv_Fonts[0] = "Times New Roman";
|
hv_Fonts[1] = "Luxi Serif";
|
hv_Fonts[2] = "DejaVu Serif";
|
hv_Fonts[3] = "FreeSerif";
|
hv_Fonts[4] = "Utopia";
|
hv_Fonts[5] = "Liberation Serif";
|
}
|
else
|
{
|
hv_Fonts.Dispose();
|
hv_Fonts = new HTuple(hv_Font_COPY_INP_TMP);
|
}
|
hv_Style.Dispose();
|
hv_Style = "";
|
if ((int)(new HTuple(((HTuple)hv_Bold).TupleEqual("true"))) != 0)
|
{
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_Style = hv_Style + "Bold";
|
hv_Style.Dispose();
|
hv_Style = ExpTmpLocalVar_Style;
|
}
|
}
|
}
|
else if ((int)(new HTuple(((HTuple)hv_Bold).TupleNotEqual("false"))) != 0)
|
{
|
hv_Exception.Dispose();
|
hv_Exception = "Wrong value of control parameter Bold";
|
throw new HalconException(hv_Exception);
|
}
|
if ((int)(new HTuple(((HTuple)hv_Slant).TupleEqual("true"))) != 0)
|
{
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_Style = hv_Style + "Italic";
|
hv_Style.Dispose();
|
hv_Style = ExpTmpLocalVar_Style;
|
}
|
}
|
}
|
else if ((int)(new HTuple(((HTuple)hv_Slant).TupleNotEqual("false"))) != 0)
|
{
|
hv_Exception.Dispose();
|
hv_Exception = "Wrong value of control parameter Slant";
|
throw new HalconException(hv_Exception);
|
}
|
if ((int)(new HTuple(hv_Style.TupleEqual(""))) != 0)
|
{
|
hv_Style.Dispose();
|
hv_Style = "Normal";
|
}
|
hv_AvailableFonts.Dispose();
|
HOperatorSet.QueryFont(hv_WindowHandle, out hv_AvailableFonts);
|
hv_Font_COPY_INP_TMP.Dispose();
|
hv_Font_COPY_INP_TMP = "";
|
for (hv_Fdx = 0; (int)hv_Fdx <= (int)((new HTuple(hv_Fonts.TupleLength())) - 1); hv_Fdx = (int)hv_Fdx + 1)
|
{
|
hv_Indices.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Indices = hv_AvailableFonts.TupleFind(
|
hv_Fonts.TupleSelect(hv_Fdx));
|
}
|
if ((int)(new HTuple((new HTuple(hv_Indices.TupleLength())).TupleGreater(
|
0))) != 0)
|
{
|
if ((int)(new HTuple(((hv_Indices.TupleSelect(0))).TupleGreaterEqual(0))) != 0)
|
{
|
hv_Font_COPY_INP_TMP.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Font_COPY_INP_TMP = hv_Fonts.TupleSelect(
|
hv_Fdx);
|
}
|
break;
|
}
|
}
|
}
|
if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual(""))) != 0)
|
{
|
throw new HalconException("Wrong value of control parameter Font");
|
}
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
{
|
HTuple
|
ExpTmpLocalVar_Font = (((hv_Font_COPY_INP_TMP + "-") + hv_Style) + "-") + hv_Size_COPY_INP_TMP;
|
hv_Font_COPY_INP_TMP.Dispose();
|
hv_Font_COPY_INP_TMP = ExpTmpLocalVar_Font;
|
}
|
}
|
HOperatorSet.SetFont(hv_WindowHandle, hv_Font_COPY_INP_TMP);
|
|
hv_Font_COPY_INP_TMP.Dispose();
|
hv_Size_COPY_INP_TMP.Dispose();
|
hv_OS.Dispose();
|
hv_Fonts.Dispose();
|
hv_Style.Dispose();
|
hv_Exception.Dispose();
|
hv_AvailableFonts.Dispose();
|
hv_Fdx.Dispose();
|
hv_Indices.Dispose();
|
|
return;
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
|
hv_Font_COPY_INP_TMP.Dispose();
|
hv_Size_COPY_INP_TMP.Dispose();
|
hv_OS.Dispose();
|
hv_Fonts.Dispose();
|
hv_Style.Dispose();
|
hv_Exception.Dispose();
|
hv_AvailableFonts.Dispose();
|
hv_Fdx.Dispose();
|
hv_Indices.Dispose();
|
|
throw HDevExpDefaultException;
|
}
|
}
|
|
public static void DispImage(HObject image, HWindow window)
|
{
|
int imgWidth, imgHeight, winRow, winCol, winWidth, winHeight, partWidth, partHeight;
|
try
|
{
|
if (image != null && image.IsInitialized())
|
{
|
HOperatorSet.GetImageSize(image, out HTuple hv_imgWidth, out HTuple hv_imgHeight);
|
imgWidth = hv_imgWidth.I;
|
imgHeight = hv_imgHeight.I;
|
window.GetWindowExtents(out winRow, out winCol, out winWidth, out winHeight);
|
if (winWidth < winHeight)
|
{
|
partWidth = imgWidth;
|
partHeight = imgWidth * winHeight / winWidth;
|
}
|
else
|
{
|
partWidth = imgHeight * winWidth / winHeight;
|
partHeight = imgHeight;
|
}
|
window.SetPart(0, 0, partHeight - 1, partWidth - 1);
|
|
HOperatorSet.DispObj(image, window);
|
}
|
else
|
HOperatorSet.ClearWindow(window);
|
}
|
catch { }
|
}
|
|
public static void DispObj(HObject hObject, HWindow window)
|
{
|
try
|
{
|
if (hObject != null && hObject.IsInitialized())
|
HOperatorSet.DispObj(hObject, window);
|
}
|
catch { }
|
}
|
|
public static void DispMsg(string msg, HWindow window, string color, HTuple row, HTuple column)
|
{
|
try
|
{
|
SetColor(window, color);
|
|
disp_message(window, msg, "image", row, column, color, "true");
|
}
|
catch { }
|
}
|
|
public static void DispMsg(string msg, HWindow window, bool result = true, int x = 0, int y = 0)
|
{
|
try
|
{
|
if (result)
|
SetColor(window, "green");
|
else
|
SetColor(window, "red");
|
|
disp_message(window, msg, "image", y, x, result ? "green" : "red", "true");
|
}
|
catch { }
|
}
|
|
public static void ClearObj(HWindow window)
|
{
|
try
|
{
|
HOperatorSet.ClearWindow(window);
|
}
|
catch { }
|
}
|
|
static void ShowHoImage(HObject ho_image, HWindow hWindow, bool autoSize = true)
|
{
|
if (ho_image == null || !ho_image.IsInitialized())
|
{
|
HOperatorSet.ClearWindow(hWindow);
|
return;
|
}
|
|
try
|
{
|
HOperatorSet.ClearWindow(hWindow);
|
|
if (autoSize)
|
{
|
HOperatorSet.GetImageSize(ho_image, out HTuple imgWidth, out HTuple imgHeight);
|
if (imgWidth.Length > 0)
|
{
|
hWindow.GetWindowExtents(out int winRow, out int winCol, out int winWidth, out int winHeight);
|
int partWidth = imgHeight * winWidth / winHeight;
|
int partHeight = imgHeight;
|
if (winWidth < winHeight)
|
{
|
partWidth = imgWidth;
|
partHeight = imgWidth * winHeight / winWidth;
|
}
|
|
//计算比例
|
double scale = Math.Max(1.0 * imgWidth.I / winWidth, 1.0 * imgHeight.I / winHeight);
|
double w = winWidth * scale;
|
double h = winHeight * scale;
|
|
double row1 = -(h - imgHeight.D) / 2;
|
double col1 = -(w - imgWidth.D) / 2;
|
double row2 = imgHeight + (h - imgHeight.D) / 2;
|
double col2 = imgWidth + (w - imgWidth.D) / 2;
|
|
//居中等比例
|
hWindow.SetPart(row1, col1, row2, col2);
|
}
|
}
|
|
HOperatorSet.DispObj(ho_image, hWindow);
|
}
|
catch { }
|
}
|
|
public static void scale_gray_map(HObject ho_Image, out HObject ho_Image1, HTuple hv_Min, HTuple hv_Max)
|
{
|
HTuple hv_Mult = new HTuple(), hv_Add = new HTuple();
|
HOperatorSet.GenEmptyObj(out ho_Image1);
|
try
|
{
|
hv_Mult.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Mult = 255.0 / (hv_Max - hv_Min);
|
}
|
hv_Add.Dispose();
|
using (HDevDisposeHelper dh = new HDevDisposeHelper())
|
{
|
hv_Add = (-hv_Mult) * hv_Min;
|
}
|
ho_Image1.Dispose();
|
HOperatorSet.ScaleImage(ho_Image, out ho_Image1, hv_Mult, hv_Add);
|
hv_Mult.Dispose();
|
hv_Add.Dispose();
|
return;
|
}
|
catch (HalconException HDevExpDefaultException)
|
{
|
|
hv_Mult.Dispose();
|
hv_Add.Dispose();
|
|
throw HDevExpDefaultException;
|
}
|
}
|
|
public static void SetColor(HTuple hv_WindowHandle)
|
{
|
HOperatorSet.SetColor(hv_WindowHandle, GetRandomColor());
|
}
|
|
/// <summary>
|
/// 设置颜色("dark olive green")
|
/// </summary>
|
/// <param name="hv_WindowHandle"></param>
|
/// <param name="color"></param>
|
public static void SetColor(HTuple hv_WindowHandle, string color)
|
{
|
//*在set_color的算子中,列出Halcon支持的颜色代码,共21种。
|
//*Suggested values: 'black', 'white', 'red', 'green',
|
//*'blue', 'cyan', 'magenta', 'yellow', 'dim gray', 'gray',
|
//*'light gray', 'medium slate blue', 'coral', 'slate blue',
|
//*'spring green', 'orange red', 'orange', 'dark olive green',
|
//*'pink', 'forest green','cadet blue'
|
//* 可以用以下的代码来测试颜色
|
HOperatorSet.SetColor(hv_WindowHandle, color);
|
}
|
|
/// <summary>
|
/// 生成Halcon随机颜色
|
/// </summary>
|
/// <returns></returns>
|
public static string GetRandomColor()
|
{
|
// 获取当前时间的毫秒数作为种子
|
int seed = DateTime.Now.Millisecond;
|
|
// 使用种子创建 Random 实例
|
Random random = new Random(seed);
|
|
// 生成随机数
|
int randomNumber = random.Next(0, 18);
|
|
// 延时随机时间变更随机种子
|
Thread.Sleep(randomNumber);
|
|
string[] strsColors = new string[]
|
{
|
"red", "green","blue", "cyan", "magenta",
|
"yellow", "dim gray", "gray","light gray", "medium slate blue", "coral", "slate blue",
|
"spring green", "orange red", "orange", "dark olive green","pink", "forest green", "cadet blue"
|
};
|
if (randomNumber <= strsColors.Length)
|
return strsColors[randomNumber];
|
else
|
return strsColors[0];
|
}
|
#endregion
|
|
#region OpenCVSharp
|
// 根据Mat类型返回对应的无效值
|
public static Scalar GetInvalidValueForMat(Mat mat)
|
{
|
MatType type = mat.Type();
|
if (type == MatType.CV_8UC1 || type == MatType.CV_8UC3)
|
return new Scalar(0); // 对于8位无符号类型,0是安全的无效值
|
else if (type == MatType.CV_32FC1 || type == MatType.CV_32FC3)
|
return new Scalar(-1); // 对于浮点类型,-1或NaN可用
|
else if (type == MatType.CV_64FC1 || type == MatType.CV_64FC3)
|
return new Scalar(double.NaN); // 双精度浮点用NaN
|
else
|
return new Scalar(0); // 对于8位无符号类型,0是安全的无效值
|
}
|
|
public static void RGB2XYZ(double sR, double sG, double sB, out double X, out double Y, out double Z)
|
{
|
// 输入的颜色值 (sR, sG, sB) 应为 0 到 255 之间的值
|
|
// 计算归一化值
|
double var_R = sR / 255.0;
|
double var_G = sG / 255.0;
|
double var_B = sB / 255.0;
|
|
// 转换到线性空间
|
var_R = (var_R > 0.04045) ? Math.Pow((var_R + 0.055) / 1.055, 2.4) : var_R / 12.92;
|
var_G = (var_G > 0.04045) ? Math.Pow((var_G + 0.055) / 1.055, 2.4) : var_G / 12.92;
|
var_B = (var_B > 0.04045) ? Math.Pow((var_B + 0.055) / 1.055, 2.4) : var_B / 12.92;
|
|
// 转换为百分比
|
var_R *= 100;
|
var_G *= 100;
|
var_B *= 100;
|
|
// 计算 XYZ 值
|
double var_X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805;
|
double var_Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722;
|
double var_Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505;
|
|
// 计算归一化值
|
|
X = Math.Round(var_X / (var_X + var_Y + var_Z), 3);
|
Y = Math.Round(var_Y / (var_X + var_Y + var_Z), 3);
|
Z = Math.Round(var_Z / (var_X + var_Y + var_Z), 3);
|
}
|
|
public static void ExtractFrames(string videoPath, string outputDir)
|
{
|
// 检查视频文件是否存在
|
if (!File.Exists(videoPath))
|
{
|
throw new FileNotFoundException($"视频文件不存在: {videoPath}");
|
}
|
|
// 创建输出目录
|
if (!Directory.Exists(outputDir))
|
{
|
Directory.CreateDirectory(outputDir);
|
}
|
|
using (var capture = new VideoCapture(videoPath))
|
{
|
if (!capture.IsOpened())
|
{
|
throw new Exception("无法打开视频文件");
|
}
|
|
// 获取视频信息
|
int totalFrames = (int)capture.Get(VideoCaptureProperties.FrameCount);
|
double fps = capture.Get(VideoCaptureProperties.Fps);
|
int width = (int)capture.Get(VideoCaptureProperties.FrameWidth);
|
int height = (int)capture.Get(VideoCaptureProperties.FrameHeight);
|
|
Debug.WriteLine($"视频信息: {totalFrames}帧, {fps:F2}fps, 分辨率: {width}x{height}");
|
|
Mat frame = new Mat();
|
int frameCount = 0;
|
|
while (capture.Read(frame))
|
{
|
if (frame.Empty())
|
break;
|
|
// 生成输出文件名
|
string outputPath = Path.Combine(outputDir, $"frame_{frameCount:D6}.bmp");
|
|
// 保存帧为图片
|
Cv2.ImWrite(outputPath, frame);
|
|
frameCount++;
|
|
// 显示进度
|
if (frameCount % 100 == 0)
|
{
|
Debug.WriteLine($"已处理 {frameCount}/{totalFrames} 帧");
|
}
|
}
|
|
Debug.WriteLine($"提取完成! 共提取 {frameCount} 帧图片");
|
}
|
}
|
#endregion
|
}
|
|
public class ObjectRecord : IDisposable
|
{
|
//创建虚拟HWindow用于显示图片[需要释放]
|
protected HWindowControl hWindowControl = null;
|
|
public bool bCompleted = false;
|
|
public HObject Image
|
{
|
set
|
{
|
try
|
{
|
if (value == null)
|
return;
|
HOperatorSet.GetImageSize(value, out HTuple ho_ImageWidth, out HTuple ho_ImageHeight);
|
hWindowControl = new HWindowControl();
|
hWindowControl.Size = new System.Drawing.Size(ho_ImageWidth, ho_ImageHeight);
|
TAlgorithm.DispImage(value, hWindowControl.HalconWindow);
|
}
|
catch { }
|
}
|
}
|
|
public HObject RecordObject_OK;
|
public HObject RecordObject_NG;
|
|
public ObjectRecord(HObject Image = null)
|
{
|
if (RecordObject_OK != null)
|
RecordObject_OK.Dispose();
|
HOperatorSet.GenEmptyObj(out RecordObject_OK);
|
RecordObject_OK = null;
|
|
if (RecordObject_NG != null)
|
RecordObject_NG.Dispose();
|
HOperatorSet.GenEmptyObj(out RecordObject_NG);
|
RecordObject_NG = null;
|
|
this.Image = Image;
|
}
|
|
public void AddRecord(HObject RecordObject, bool result = true)
|
{
|
if (RecordObject == null || !RecordObject.IsInitialized())
|
return;
|
|
try
|
{
|
HOperatorSet.GenContourRegionXld(RecordObject, out RecordObject, "border_holes");
|
}
|
catch { }
|
|
if (result)
|
{
|
if (this.RecordObject_OK == null || !this.RecordObject_OK.IsInitialized())
|
this.RecordObject_OK = RecordObject;
|
else
|
HOperatorSet.ConcatObj(this.RecordObject_OK, RecordObject, out this.RecordObject_OK);
|
}
|
else
|
{
|
if (this.RecordObject_NG == null || !this.RecordObject_NG.IsInitialized())
|
this.RecordObject_NG = RecordObject;
|
else
|
HOperatorSet.ConcatObj(this.RecordObject_NG, RecordObject, out this.RecordObject_NG);
|
}
|
}
|
|
public void AddXld(HObject RecordObjectXld, bool result = true)
|
{
|
if (RecordObjectXld == null || !RecordObjectXld.IsInitialized())
|
return;
|
|
if (result)
|
{
|
if (this.RecordObject_OK == null || !this.RecordObject_OK.IsInitialized())
|
this.RecordObject_OK = RecordObjectXld;
|
else
|
HOperatorSet.ConcatObj(this.RecordObject_OK, RecordObjectXld, out this.RecordObject_OK);
|
}
|
else
|
{
|
if (this.RecordObject_NG == null || !this.RecordObject_NG.IsInitialized())
|
this.RecordObject_NG = RecordObjectXld;
|
else
|
HOperatorSet.ConcatObj(this.RecordObject_NG, RecordObjectXld, out this.RecordObject_NG);
|
}
|
}
|
|
public void GetRecord(out HObject RecordObject)
|
{
|
try
|
{
|
if (this.RecordObject_OK == null || !this.RecordObject_OK.IsInitialized())
|
{
|
RecordObject = this.RecordObject_NG;
|
return;
|
}
|
|
if (this.RecordObject_NG == null || !this.RecordObject_NG.IsInitialized())
|
{
|
RecordObject = this.RecordObject_NG;
|
return;
|
}
|
|
HOperatorSet.ConcatObj(this.RecordObject_OK, this.RecordObject_NG, out RecordObject);
|
return;
|
}
|
catch { RecordObject = null; }
|
}
|
|
public virtual void ChangeAll2False()
|
{
|
if (this.RecordObject_OK == null || !this.RecordObject_OK.IsInitialized())
|
return;
|
|
if (this.RecordObject_NG == null || !this.RecordObject_NG.IsInitialized())
|
this.RecordObject_NG = RecordObject_OK.CopyObj(1, -1);
|
else
|
HOperatorSet.ConcatObj(RecordObject_OK, RecordObject_NG, out RecordObject_NG);
|
|
if (RecordObject_OK != null && RecordObject_OK.IsInitialized())
|
RecordObject_OK.Dispose();
|
}
|
|
public virtual void ChangeAll2True()
|
{
|
if (this.RecordObject_NG == null || !this.RecordObject_NG.IsInitialized())
|
return;
|
|
if (this.RecordObject_OK == null || !this.RecordObject_OK.IsInitialized())
|
this.RecordObject_OK = RecordObject_NG.CopyObj(1, -1);
|
else
|
HOperatorSet.ConcatObj(RecordObject_OK, RecordObject_NG, out RecordObject_OK);
|
|
if (RecordObject_OK != null && RecordObject_OK.IsInitialized())
|
RecordObject_OK.Dispose();
|
}
|
|
public virtual HObject GetRecordImage()
|
{
|
bCompleted = false;
|
try
|
{
|
if (hWindowControl == null)
|
return null;
|
|
|
if (RecordObject_OK != null && RecordObject_OK.IsInitialized())
|
{
|
HOperatorSet.SetColor(hWindowControl.HalconWindow, "true");
|
HOperatorSet.DispObj(RecordObject_OK, hWindowControl.HalconWindow);
|
}
|
|
if (RecordObject_NG != null && RecordObject_NG.IsInitialized())
|
{
|
HOperatorSet.SetColor(hWindowControl.HalconWindow, "red");
|
HOperatorSet.DispObj(RecordObject_NG, hWindowControl.HalconWindow);
|
}
|
|
HOperatorSet.DumpWindowImage(out HObject hoRecordImage, hWindowControl.HalconWindow);
|
return hoRecordImage;
|
}
|
catch { return null; }
|
finally
|
{
|
if (RecordObject_OK != null && RecordObject_OK.IsInitialized())
|
RecordObject_OK.Dispose();
|
HOperatorSet.GenEmptyObj(out RecordObject_OK);
|
|
if (RecordObject_NG != null && RecordObject_NG.IsInitialized())
|
RecordObject_NG.Dispose();
|
HOperatorSet.GenEmptyObj(out RecordObject_NG);
|
bCompleted = true;
|
}
|
}
|
|
public virtual void Display(HWindow hWindow)
|
{
|
try
|
{
|
if (hWindow != null)
|
{
|
if (RecordObject_NG != null && RecordObject_NG.IsInitialized())
|
{
|
HOperatorSet.SetColor(hWindow, "red");
|
HOperatorSet.DispObj(RecordObject_NG, hWindow);
|
}
|
|
if (RecordObject_OK != null && RecordObject_OK.IsInitialized())
|
{
|
HOperatorSet.SetColor(hWindow, "green");
|
HOperatorSet.DispObj(RecordObject_OK, hWindow);
|
}
|
}
|
}
|
catch { }
|
}
|
|
public virtual void Dispose()
|
{
|
try
|
{
|
if (hWindowControl != null)
|
hWindowControl.Dispose();
|
|
if (RecordObject_OK != null && RecordObject_OK.IsInitialized())
|
{
|
RecordObject_OK.Dispose();
|
RecordObject_OK = null;
|
}
|
if (RecordObject_NG != null && RecordObject_NG.IsInitialized())
|
{
|
RecordObject_NG.Dispose();
|
RecordObject_NG = null;
|
}
|
}
|
catch { }
|
}
|
}
|
|
public class MsgRecord : ObjectRecord
|
{
|
public HTuple Msg = new HTuple();
|
public HTuple Row = new HTuple();
|
public HTuple Column = new HTuple();
|
public HTuple Result = new HTuple();
|
|
public MsgRecord(HObject RecordImage = null) : base(RecordImage) // 这里调用基类构造函数
|
{
|
Msg = new HTuple();
|
Row = new HTuple();
|
Column = new HTuple();
|
Result = new HTuple();
|
}
|
|
public void AddRecord(HTuple Msg, HTuple Row, HTuple Column, HObject RecordObject = null, bool Result = true)
|
{
|
|
if (Msg.Length <= 0 || Row.Length <= 0 || Column.Length <= 0)
|
return;
|
|
if (RecordObject != null && RecordObject.IsInitialized())
|
{
|
try
|
{
|
HOperatorSet.GenContourRegionXld(RecordObject, out RecordObject, "border_holes");
|
}
|
catch { }
|
|
if (Result)
|
{
|
if (this.RecordObject_OK == null || !this.RecordObject_OK.IsInitialized())
|
this.RecordObject_OK = RecordObject;
|
else
|
HOperatorSet.ConcatObj(this.RecordObject_OK, RecordObject, out this.RecordObject_OK);
|
}
|
else
|
{
|
if (this.RecordObject_NG == null || !this.RecordObject_NG.IsInitialized())
|
this.RecordObject_NG = RecordObject;
|
else
|
HOperatorSet.ConcatObj(this.RecordObject_NG, RecordObject, out this.RecordObject_NG);
|
}
|
}
|
|
HOperatorSet.TupleConcat(this.Msg, Msg, out this.Msg);
|
HOperatorSet.TupleConcat(this.Row, Row, out this.Row);
|
HOperatorSet.TupleConcat(this.Column, Column, out this.Column);
|
HOperatorSet.TupleConcat(this.Result, Result ? 1 : 0, out this.Result);
|
}
|
|
public void GetRecord(out HObject RecordObject, out HTuple Msg, out HTuple Row, out HTuple Column)
|
{
|
Msg = this.Msg;
|
Row = this.Row;
|
Column = this.Column;
|
try
|
{
|
if (this.RecordObject_OK == null || !this.RecordObject_OK.IsInitialized())
|
{
|
RecordObject = this.RecordObject_NG;
|
return;
|
}
|
|
if (this.RecordObject_NG == null || !this.RecordObject_NG.IsInitialized())
|
{
|
RecordObject = this.RecordObject_NG;
|
return;
|
}
|
|
HOperatorSet.ConcatObj(this.RecordObject_OK, this.RecordObject_NG, out RecordObject);
|
return;
|
}
|
catch { RecordObject = null; }
|
}
|
|
public override void ChangeAll2False()
|
{
|
for (int i = 0; i < Result.Length; i++)
|
Result[i] = 0;
|
|
if (this.RecordObject_NG == null || !this.RecordObject_NG.IsInitialized())
|
this.RecordObject_NG = RecordObject_OK.CopyObj(1, -1);
|
else if (!(this.RecordObject_OK == null || !this.RecordObject_OK.IsInitialized()))
|
HOperatorSet.ConcatObj(RecordObject_OK, RecordObject_NG, out RecordObject_NG);
|
|
if (RecordObject_OK != null && RecordObject_OK.IsInitialized())
|
RecordObject_OK.Dispose();
|
}
|
|
public override void ChangeAll2True()
|
{
|
for (int i = 0; i < Result.Length; i++)
|
Result[i] = 1;
|
|
if (this.RecordObject_OK == null || !this.RecordObject_OK.IsInitialized())
|
this.RecordObject_OK = RecordObject_NG.CopyObj(1, -1);
|
else if (!(this.RecordObject_NG == null || !this.RecordObject_NG.IsInitialized()))
|
HOperatorSet.ConcatObj(RecordObject_OK, RecordObject_NG, out RecordObject_OK);
|
|
if (RecordObject_NG != null && RecordObject_NG.IsInitialized())
|
RecordObject_NG.Dispose();
|
}
|
|
public override HObject GetRecordImage()
|
{
|
bCompleted = false;
|
try
|
{
|
if (hWindowControl == null)
|
return null;
|
|
if (RecordObject_OK != null && RecordObject_OK.IsInitialized())
|
{
|
HOperatorSet.SetColor(hWindowControl.HalconWindow, "true");
|
HOperatorSet.DispObj(RecordObject_OK, hWindowControl.HalconWindow);
|
}
|
|
if (RecordObject_NG != null && RecordObject_NG.IsInitialized())
|
{
|
HOperatorSet.SetColor(hWindowControl.HalconWindow, "red");
|
HOperatorSet.DispObj(RecordObject_NG, hWindowControl.HalconWindow);
|
}
|
|
for (int i = 0; i < Msg.Length; i++)
|
{
|
if (1 == Result[i])
|
HOperatorSet.SetColor(hWindowControl.HalconWindow, "green");
|
else
|
HOperatorSet.SetColor(hWindowControl.HalconWindow, "red");
|
|
TAlgorithm.DispMsg(Msg[i], hWindowControl.HalconWindow, 1 == Result[i] ? "green" : "red", Row[i], Column[i]);
|
}
|
|
HOperatorSet.DumpWindowImage(out HObject hoRecordImage, hWindowControl.HalconWindow);
|
bCompleted = true;
|
|
return hoRecordImage;
|
}
|
catch { return null; }
|
finally
|
{
|
if (RecordObject_OK != null && RecordObject_OK.IsInitialized())
|
RecordObject_OK.Dispose();
|
HOperatorSet.GenEmptyObj(out RecordObject_OK);
|
|
if (RecordObject_NG != null && RecordObject_NG.IsInitialized())
|
RecordObject_NG.Dispose();
|
HOperatorSet.GenEmptyObj(out RecordObject_NG);
|
|
Msg = new HTuple();
|
Row = new HTuple();
|
Column = new HTuple();
|
Result = new HTuple();
|
bCompleted = true;
|
}
|
}
|
|
public override void Display(HWindow hWindow)
|
{
|
try
|
{
|
base.Display(hWindow);
|
|
for (int i = 0; i < Msg.Length; i++)
|
{
|
if (hWindow != null)
|
{
|
if (1 == Result[i])
|
HOperatorSet.SetColor(hWindow, "green");
|
else
|
HOperatorSet.SetColor(hWindow, "red");
|
|
TAlgorithm.DispMsg(Msg[i], hWindow, 1 == Result[i] ? "green" : "red", Row[i], Column[i]);
|
}
|
}
|
}
|
catch { }
|
}
|
|
public override void Dispose()
|
{
|
try
|
{
|
if (hWindowControl != null)
|
hWindowControl.Dispose();
|
|
if (RecordObject_OK != null && RecordObject_OK.IsInitialized())
|
{
|
RecordObject_OK.Dispose();
|
RecordObject_OK = null;
|
}
|
if (RecordObject_NG != null && RecordObject_NG.IsInitialized())
|
{
|
RecordObject_NG.Dispose();
|
RecordObject_NG = null;
|
}
|
|
Msg = new HTuple();
|
Row = new HTuple();
|
Column = new HTuple();
|
Result = new HTuple();
|
}
|
catch { }
|
}
|
}
|
}
|