/* * Copyright (c) 2025 LG Electronics Inc. * SPDX-License-Identifier: LicenseRef-LGE-Proprietary */ using Aurora.Api.DataType; using System; using System.Drawing; namespace VisionCommon { /// /// 멀티 패턴용 개별 패턴 번호. 참고로 패턴 인덱스 0은 Master 패턴, 1부터 8은 Slave 패턴이다. /// public enum eRoiIdx { Roi0, Roi1, Roi2, Roi3, Roi4, Roi5, Roi6, Roi7, Roi8, Roi9 } public class ROI : ICloneable { public double CenterX { get; set; } = 0; public double CenterY { get; set; } = 0; public int Width { get; set; } = 0; public int Height { get; set; } = 0; public Angle Angle { get; set; } = new Angle(); public eRoiIdx RoiIdx { get; set; } = eRoiIdx.Roi0; // Default : 0 public eColor RoiColor { get; set; } = eColor.Cyan; // Default : Cyan public ImagePoint Center { get { return new ImagePoint(CenterX, CenterY); } private set { CenterX = value.X; CenterY = value.Y; } } #region Unrotated ROI Pos public ImagePoint LeftTop { get { return new ImagePoint(Left, Top); } } public ImagePoint RightBottom { get { return new ImagePoint(Right, Bottom); } } public int Left { get { return (int)(CenterX - (Width * 0.5)); } } public int Right { get { return (int)(CenterX + (Width * 0.5)); } } public int Top { get { return (int)(CenterY - (Height * 0.5)); } } public int Bottom { get { return (int)(CenterY + (Height * 0.5)); } } #endregion #region Rotated ROI Pos public ImagePoint RotatedLeftTop { get { return GetRotatedLeftTop(this); } } public ImagePoint RotatedRightBottom { get { return GetRotatedRightBottom(this); } } public ImagePoint RotatedLeftCenter { get { return GetRotatedLeftCenter(this); } } public ImagePoint RotatedRightCenter { get { return GetRotatedRightCenter(this); } } public static ImagePoint GetRotatedLeftTop(ROI roi) { return MathUtil.Rotate(roi.LeftTop, roi.Angle, roi.Center) as ImagePoint; } public static ImagePoint GetRotatedRightBottom(ROI roi) { return MathUtil.Rotate(roi.RightBottom, roi.Angle, roi.Center) as ImagePoint; } public static ImagePoint GetRotatedLeftCenter(ROI roi) { var leftCenter = new ImagePoint() { X = roi.Left, Y = roi.Top + (roi.Height / 2) }; return MathUtil.Rotate(leftCenter, roi.Angle, roi.Center) as ImagePoint; } public static ImagePoint GetRotatedRightCenter(ROI roi) { var rightCenter = new ImagePoint() { X = roi.Right, Y = roi.Bottom - (roi.Height / 2) }; return MathUtil.Rotate(rightCenter, roi.Angle, roi.Center) as ImagePoint; } #endregion public ROI() { } public ROI( ImagePoint center, int width, int height, eRoiIdx roiIdx = eRoiIdx.Roi0, eColor roiColor = eColor.Cyan) : this(center.X, center.Y, width, height, roiIdx, roiColor) { } public ROI( double centerX, double centerY, int width, int height, eRoiIdx roiIdx = eRoiIdx.Roi0, eColor roiColor = eColor.Cyan) : this(centerX, centerY, width, height, new Angle(), roiIdx, roiColor) { } public ROI( ImagePoint center, int width, int height, Angle angle, eRoiIdx roiIdx = eRoiIdx.Roi0, eColor roiColor = eColor.Cyan) : this(center.X, center.Y, width, height, angle, roiIdx, roiColor) { } public ROI( double centerX, double centerY, int width, int height, Angle angle, eRoiIdx roiIdx = eRoiIdx.Roi0, eColor roiColor = eColor.Cyan) { CenterX = centerX; CenterY = centerY; Width = width; Height = height; Angle = angle.Clone() as Angle; RoiIdx = roiIdx; RoiColor = roiColor; } public static bool IsNullOrEmpty(ROI roi) { if (roi == null) { return true; } return roi.Width == 0 || roi.Height == 0; } public object Clone() { return new ROI(CenterX, CenterY, Width, Height, Angle.Clone() as Angle, RoiIdx, RoiColor); } public override string ToString() { return $"Left : {Left:F2}, Right : {Right:F2}, Center : {Center}, " + $"Top : {Top:F2}, Bottom : {Bottom:F2}, " + $"Width : {Width:F2}, Height : {Height:F2}, Angle : {Angle}, " + $"RoiIdx : {RoiIdx}, RoiColor : {RoiColor.ToString()}"; } public static ROI Translate(ROI roi, ImagePoint translation) { return new ROI( (roi.Center + translation) as ImagePoint, roi.Width, roi.Height, roi.Angle.Clone() as Angle, roi.RoiIdx, roi.RoiColor); } public static bool IsOutsideImage(ROI roi, ImageSize imageSize) { if (roi.Left < 0) { return true; } if (roi.Top < 0) { return true; } if (imageSize.Width <= roi.Right) { return true; } if (imageSize.Height <= roi.Bottom) { return true; } return false; } public static ROI FitRoiToImage(ROI roi, ImageSize imageSize) { int left = roi.Left; int right = roi.Right; int top = roi.Top; int bottom = roi.Bottom; if (roi.Left < 0) { left = 0; } if (roi.Top < 0) { top = 0; } if (imageSize.Width <= roi.Right) { right = imageSize.Width - 1; } if (imageSize.Height <= roi.Bottom) { bottom = imageSize.Height - 1; } var roiCenter = new ImagePoint( (left + right) * 0.5, (top + bottom) * 0.5); return new ROI( roiCenter, right - left, bottom - top, roi.Angle); } public static Rectangle ToRectangle(ROI roi) { return new Rectangle( roi.Left, roi.Top, roi.Width, roi.Height); } public static ROI FromRectangle(Rectangle rectangle) { return new ROI( rectangle.Left + (rectangle.Width * 0.5), rectangle.Top + (rectangle.Height * 0.5), rectangle.Width, rectangle.Height, new Angle()); } } }