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 { /// /// 读写锁 /// public static readonly object lockObj = new object(); /// /// 裁切图片为hoDomainImage(保留原坐标系,其余填充为空) /// /// 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; } /// /// 算子逻辑 /// public virtual void TAlgorithmMain() { bCompleted = true; Debug.WriteLine("任务完成"); } /// /// 加载算法 /// /// 完整路径带.json /// 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(strJson); if (Params == null) return false; Params.FixDeserializedData(); return true; } catch { return false; } } /// /// 保存算法 /// /// 不带.json /// 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(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 value, T min, T max) where T : IComparable { 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; } } /// /// 计算两点的距离 /// /// /// /// 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)); } /// /// 获取两点的中点 /// /// /// /// 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); } /// /// 判断点是否在线段上 /// /// /// /// 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)); } /// /// 判断点是否在矩形边附近 /// /// /// /// /// 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); } /// /// 判断点是否在点附近 /// /// /// /// /// 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); } /// /// 判断点是否在矩形角上 /// /// /// /// /// /// 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; } } /// /// 计算两线的交点 /// /// 线1起始点 /// /// 线2起始点 /// /// 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); } /// /// 卡尺算法 /// /// 待测图片 /// 测量卡尺区域显示 /// 卡尺个数 /// 卡尺长度 /// 卡尺宽度 /// 过滤一半像素(推荐值:2) /// 对比度阈值(推荐值:5) /// 极性(negative/positive/ignore) /// 边缘位置(first/last/best) /// 起始纵坐标 /// 起始横坐标 /// 结束纵坐标 /// 结束横坐标 /// 结果点集合纵坐标 /// 结果点集合横坐标 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; } } /// /// 显示符号 /// /// /// /// /// /// /// /// 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; } } /// /// 设置符号大小 /// /// /// /// /// /// 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()); } /// /// 设置颜色("dark olive green") /// /// /// 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); } /// /// 生成Halcon随机颜色 /// /// 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 { } } } }