2026-03-30 17:09:29 +09:00

199 lines
7.0 KiB
C#

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}";
}
}
}