233 lines
7.2 KiB
C#
233 lines
7.2 KiB
C#
/*
|
|
* Copyright (c) 2025 LG Electronics Inc.
|
|
* SPDX-License-Identifier: LicenseRef-LGE-Proprietary
|
|
*/
|
|
using Aurora.Api.DataType;
|
|
using System;
|
|
using System.Drawing;
|
|
|
|
namespace VisionCommon {
|
|
/// <summary>
|
|
/// 멀티 패턴용 개별 패턴 번호. 참고로 패턴 인덱스 0은 Master 패턴, 1부터 8은 Slave 패턴이다.
|
|
/// </summary>
|
|
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());
|
|
}
|
|
}
|
|
}
|