2026-06-05 13:44:39 +09:00

218 lines
8.3 KiB
C#

using VisionCommon;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace VisionCalibrator {
/// <summary>한 점의 좌표 정보</summary>
public struct PointData {
/// <summary>X 좌표</summary>
public double X;
/// <summary>Y 좌표</summary>
public double Y;
}
/// <summary>여러 점들의 좌표 정보</summary>
public struct PointsData {
/// <summary>점들의 수</summary>
public int Count;
/// <summary>점들의 좌표 정보</summary>
public IntPtr Points;
}
/// <summary>회전을 위한 정보</summary>
public struct CircleData {
/// <summary>회전 원점의 좌표</summary>
public PointData Center;
/// <summary>회전 각도</summary>
public double Radius;
/// <summary>반지름 길이</summary>
public double Rms;
}
internal static class NativeCalibrator {
private const string FILE_NAME_VISION_DLL = "VisionCore.dll";
[DllImport(FILE_NAME_VISION_DLL)]
extern internal static double GetAxisRadian(ref PointsData meaPoints);
[DllImport(FILE_NAME_VISION_DLL)]
extern internal static CircleData CircleFit(ref PointsData meaPoints, double rotationRadian);
[DllImport(FILE_NAME_VISION_DLL)]
extern internal static PointData TransformImageToStatic(PointData fovCenter, PointData fovCenterOffset, double setupDirection, double errorRotation, int imageWidth, int imageHeight, int flipY, double pixelSizeX, double pixelSizeY, PointData imagePoint);
[DllImport(FILE_NAME_VISION_DLL)]
extern internal static PointData TransformStaticToImage(PointData fovCenter, PointData fovCenterOffset, double setupDirection, double errorRotation, int imageWidth, int imageHeight, int flipY, double pixelSizeX, double pixelSizeY, PointData staticPoint);
[DllImport(FILE_NAME_VISION_DLL)]
extern internal static double GetPixelSize2(ref PointsData meaPoints, double moveLength, double AxisAngle, char target);
[DllImport(FILE_NAME_VISION_DLL)]
extern internal static PointData CalcCoordConvert(
double X, double Y,
double markSizeX, double markSizeY,
PointData llMotion, PointData hlMotion, PointData lhMotion, PointData hhMotion,
double sourceRotXRad, int sourceFlipY,
double targetRotXRad, int targetFlipY);
[DllImport(FILE_NAME_VISION_DLL)]
extern internal static PointData CalcCoordConvertInverse(
double X, double Y,
PointData s1, PointData s2, PointData s3, PointData s4,
PointData m1, PointData m2, PointData m3, PointData m4);
internal static StaticPoint StaticCalibrateThetaOrigin(
List<StaticPoint> meaPoints,
Angle rotation) {
var mPoints = ConvertPointsData(meaPoints);
CircleData result = CircleFit(ref mPoints, rotation.Radian);
return new StaticPoint(result.Center.X, result.Center.Y);
}
private static PointsData ConvertPointsData(List<StaticPoint> points) {
var pointsData = new PointsData();
pointsData.Count = points.Count;
pointsData.Points = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>() * pointsData.Count);
try {
for (int i = 0; i < pointsData.Count; i++) {
var pointData = new PointData() {
X = points[i].X,
Y = points[i].Y
};
// PointData Marshaling
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(pointData));
Marshal.StructureToPtr(pointData, ptr, false);
// Copy PointData to Array
Marshal.StructureToPtr(ptr, (IntPtr)((long)pointsData.Points + Marshal.SizeOf<IntPtr>() * i), false);
}
}
catch (Exception e) {
}
return pointsData;
}
private static PointsData ConvertPointsData(List<ImagePoint> points) {
var pointsData = new PointsData();
pointsData.Count = points.Count;
pointsData.Points = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>() * pointsData.Count);
try {
for (int i = 0; i < pointsData.Count; i++) {
var pointData = new PointData() {
X = points[i].X,
Y = points[i].Y
};
// PointData Marshaling
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(pointData));
Marshal.StructureToPtr(pointData, ptr, false);
// Copy PointData to Array
Marshal.StructureToPtr(ptr, (IntPtr)((long)pointsData.Points + Marshal.SizeOf<IntPtr>() * i), false);
}
}
catch (Exception e) {
}
return pointsData;
}
internal static StaticPoint ImageToStatic(
PointData fovCenter, PointData fovCenterOffset, double setupDirection, double errorRotation,
int imageWidth, int imageHeight, int flipY,
double pixelSizeX, double pixelSizeY, PointData imagePoint) {
var pointData = new PointData();
try {
pointData = TransformImageToStatic(
fovCenter, fovCenterOffset, setupDirection, errorRotation,
imageWidth, imageHeight, flipY,
pixelSizeX, pixelSizeY, imagePoint);
}
catch (Exception e) {
}
return new StaticPoint(pointData.X, pointData.Y);
}
internal static ImagePoint StaticToImage(
PointData fovCenter, PointData fovCenterOffset, double setupDirection, double errorRotation,
int imageWidth, int imageHeight, int flipY,
double pixelSizeX, double pixelSizeY, PointData staticPoint) {
var pointData = new PointData();
try {
pointData = TransformStaticToImage(
fovCenter, fovCenterOffset, setupDirection, errorRotation,
imageWidth, imageHeight, flipY,
pixelSizeX, pixelSizeY, staticPoint);
}
catch (Exception e) {
}
return new ImagePoint(pointData.X, pointData.Y);
}
internal static double CalibrateImagePixel(List<ImagePoint> meaPoints, double moveLength, double AxisAngle, char target) {
var mPoints = ConvertPointsData(meaPoints);
double pixelSize = GetPixelSize2(ref mPoints, moveLength, AxisAngle, target);
return pixelSize;
}
internal static Angle StaticCalibrateErrorRot(
List<ImagePoint> meaPoints) {
var mPoints = ConvertPointsData(meaPoints);
double axisRadian = GetAxisRadian(ref mPoints);
return Angle.CreateWithRadian(axisRadian);
}
internal static MotionPoint CoordConveter(
double X, double Y,
double MarkSizeX, double MarkSizeY,
PointData llMotion, PointData hlMotion, PointData lhMotion, PointData hhMotion,
double sourceRotXRad, int sourceFlipY,
double targetRotXRad, int targetFlipY) {
var pointData = new PointData();
try {
pointData = CalcCoordConvert(
X, Y,
MarkSizeX, MarkSizeY,
llMotion, hlMotion, lhMotion, hhMotion,
sourceRotXRad, sourceFlipY,
targetRotXRad, targetFlipY);
}
catch (Exception e) {
}
return new MotionPoint(pointData.X, pointData.Y);
}
internal static StaticPoint CoordConvertInverse(
double X, double Y,
PointData s1, PointData s2, PointData s3, PointData s4,
PointData m1, PointData m2, PointData m3, PointData m4) {
var pointData = new PointData();
try {
pointData = CalcCoordConvertInverse(
X, Y,
s1, s2, s3, s4,
m1, m2, m3, m4);
}
catch (Exception e) {
}
return new StaticPoint(pointData.X, pointData.Y);
}
}
}