203 lines
7.1 KiB
C#
203 lines
7.1 KiB
C#
/*
|
|
* Copyright (c) 2025 LG Electronics Inc.
|
|
* SPDX-License-Identifier: LicenseRef-LGE-Proprietary
|
|
*/
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace VisionCommon {
|
|
// 하드웨어 카메라 플립 유무
|
|
public enum eFlipY : int {
|
|
True = -1,
|
|
False = 1
|
|
}
|
|
|
|
// 이미지 플립 방향
|
|
public enum eImageFlip {
|
|
None, // 반전X
|
|
LeftToRight, // 좌우반전
|
|
TopToBottom // 상하반전
|
|
}
|
|
|
|
// 이미지 회전 각도
|
|
public enum eImageRotation {
|
|
None = 0, // 회전X
|
|
CW_DEG_90 = 90, // 90도 회전
|
|
CW_DEG_180 = 180, // 180도 회전
|
|
CW_DEG_270 = 270, // 270도 회전
|
|
}
|
|
|
|
public enum eCoordSysType {
|
|
RotX_0,
|
|
RotX_90,
|
|
RotX_180,
|
|
RotX_270,
|
|
RotX_0_FilpY,
|
|
RotX_90_FilpY,
|
|
RotX_180_FilpY,
|
|
RotX_270_FilpY,
|
|
}
|
|
|
|
/// <summary>
|
|
/// Source -> Target 좌표계 변환을 위환 변환 값으로 작성한다.
|
|
/// </summary>
|
|
public class CoordSystem : ICloneable {
|
|
public Angle RotationX { get; set; }
|
|
public eFlipY FlipY { get; set; }
|
|
public eDirection DirectionT { get; set; }
|
|
public eDirection DirectionZ { get; set; }
|
|
|
|
public CoordSystem() : this(new Angle(), eFlipY.False, eDirection.Plus) {
|
|
}
|
|
|
|
public CoordSystem(
|
|
Angle rotationX,
|
|
eFlipY flipY,
|
|
eDirection directionT,
|
|
eDirection directionZ = eDirection.Plus) {
|
|
this.RotationX = rotationX;
|
|
this.FlipY = flipY;
|
|
this.DirectionT = directionT;
|
|
this.DirectionZ = directionZ;
|
|
}
|
|
|
|
public static Angle NormalizeAngleDirection(Angle angle, int flipY) {
|
|
// Image Coordinate (Vision Core) -> Calibrated Coordinate
|
|
return Angle.CreateWithRadian(angle.Radian * flipY);
|
|
}
|
|
|
|
public static Angle DenormalizeAngleDirection(Angle angle, int flipY) {
|
|
// Calibrated Coordinate -> Image Coordinate (Vision Core)
|
|
return Angle.CreateWithRadian(angle.Radian * flipY);
|
|
}
|
|
|
|
public static CoordSystem operator -(CoordSystem cs1, CoordSystem cs2) {
|
|
var angleDiff = Angle.DenormalizeAngle(cs1.RotationX - cs2.RotationX);
|
|
|
|
return new CoordSystem(
|
|
angleDiff,
|
|
(eFlipY)((int)cs1.FlipY * (int)cs2.FlipY),
|
|
(eDirection)((int)cs1.DirectionT * (int)cs2.DirectionT),
|
|
(eDirection)((int)cs1.DirectionZ * (int)cs2.DirectionZ));
|
|
}
|
|
|
|
public static DoublePoint ApplyDirection(DoublePoint point, SetupDirection setupDirection) {
|
|
return ApplyDirection(
|
|
point,
|
|
Angle.CreateWithDegree(setupDirection.RotationX),
|
|
setupDirection.FlipY);
|
|
}
|
|
|
|
public static DoublePoint ApplyDirection(DoublePoint point, CoordSystem csSource, CoordSystem csTarget) {
|
|
var csCorrection = csTarget - csSource;
|
|
|
|
return ApplyDirection(
|
|
point,
|
|
csCorrection.RotationX * (int)csSource.FlipY,
|
|
csCorrection.FlipY);
|
|
}
|
|
|
|
public static DoublePoint ApplyDirection(DoublePoint point, Angle rotationX, eFlipY flipY) {
|
|
return MathUtil.RotateFlip(
|
|
point,
|
|
rotationX * -1, // 좌표계 변환의 회전량은 부호가 반대이다.
|
|
flipY);
|
|
}
|
|
|
|
public static double ApplyDirectionT(double deltaT, CoordSystem coordSystem) {
|
|
return ApplyDirection(deltaT, coordSystem.DirectionT);
|
|
}
|
|
|
|
public static double ApplyDirectionZ(double deltaZ, CoordSystem coordSystem) {
|
|
return ApplyDirection(deltaZ, coordSystem.DirectionZ);
|
|
}
|
|
|
|
public static double ApplyDirection(double delta, eDirection direction) {
|
|
return delta * (int)direction;
|
|
}
|
|
|
|
public static eCoordSysType ToCoordSysType(CoordSystem coordSystem) {
|
|
return ToCoordSysType(coordSystem.RotationX, coordSystem.FlipY);
|
|
}
|
|
|
|
public static eCoordSysType ToCoordSysType(Angle rotationX, eFlipY flipY) {
|
|
var flipYType = (flipY == eFlipY.False) ? eCoordSysType.RotX_0 : eCoordSysType.RotX_0_FilpY;
|
|
var rotationXType = (int)(rotationX.Degree / 90);
|
|
|
|
return flipYType + rotationXType;
|
|
}
|
|
|
|
public static CoordSystem ToCoordSystem(eCoordSysType coordSysType, eDirection directionT, eDirection directionZ = eDirection.Plus) {
|
|
return new CoordSystem() {
|
|
RotationX = GetRotationX(coordSysType),
|
|
FlipY = GetFlipY(coordSysType),
|
|
DirectionT = directionT,
|
|
DirectionZ = directionZ
|
|
};
|
|
}
|
|
|
|
public static Angle GetRotationX(eCoordSysType coordSysType) {
|
|
return Angle.CreateWithDegree((int)coordSysType % 4 * 90);
|
|
}
|
|
|
|
public static eFlipY GetFlipY(eCoordSysType coordSysType) {
|
|
return (coordSysType < eCoordSysType.RotX_0_FilpY) ? eFlipY.False : eFlipY.True;
|
|
}
|
|
|
|
public object XFlip() {
|
|
return XFlip(new CoordSystem(RotationX.Clone() as Angle, FlipY, DirectionT, DirectionZ));
|
|
}
|
|
|
|
public static CoordSystem XFlip(CoordSystem coordSystem) {
|
|
return new CoordSystem() {
|
|
RotationX = Angle.CreateWithDegree(coordSystem.RotationX.Degree + 180),
|
|
FlipY = (eFlipY)((int)coordSystem.FlipY * -1),
|
|
DirectionT = coordSystem.DirectionT,
|
|
DirectionZ = coordSystem.DirectionZ
|
|
};
|
|
}
|
|
|
|
public object YFlip() {
|
|
return YFlip(new CoordSystem(RotationX.Clone() as Angle, FlipY, DirectionT, DirectionZ));
|
|
}
|
|
|
|
public static CoordSystem YFlip(CoordSystem coordSystem) {
|
|
return new CoordSystem() {
|
|
RotationX = coordSystem.RotationX.Clone() as Angle,
|
|
FlipY = (eFlipY)((int)coordSystem.FlipY * -1),
|
|
DirectionT = coordSystem.DirectionT,
|
|
DirectionZ = coordSystem.DirectionZ
|
|
};
|
|
}
|
|
|
|
public override bool Equals(object obj) {
|
|
CoordSystem cs = obj as CoordSystem;
|
|
|
|
if (cs == null || this.GetType() != cs.GetType()) {
|
|
return false;
|
|
}
|
|
|
|
return this.RotationX.Equals(cs.RotationX) &&
|
|
(this.FlipY == cs.FlipY) &&
|
|
(this.DirectionT == cs.DirectionT) &&
|
|
(this.DirectionZ == cs.DirectionZ);
|
|
}
|
|
|
|
public override int GetHashCode() {
|
|
return RotationX.GetHashCode() ^ FlipY.GetHashCode() ^
|
|
DirectionT.GetHashCode() ^ DirectionZ.GetHashCode();
|
|
}
|
|
|
|
public object Clone() {
|
|
return new CoordSystem(RotationX.Clone() as Angle, FlipY, DirectionT, DirectionZ);
|
|
}
|
|
|
|
public override string ToString() {
|
|
return $"RotX : {RotationX}, FlipY : {FlipY}, DirT : {DirectionT}, DirZ : {DirectionZ}";
|
|
}
|
|
}
|
|
}
|