using VisionCommon;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace VisionCalibrator {
/// 한 점의 좌표 정보
public struct PointData {
/// X 좌표
public double X;
/// Y 좌표
public double Y;
}
/// 여러 점들의 좌표 정보
public struct PointsData {
/// 점들의 수
public int Count;
/// 점들의 좌표 정보
public IntPtr Points;
}
/// 회전을 위한 정보
public struct CircleData {
/// 회전 원점의 좌표
public PointData Center;
/// 회전 각도
public double Radius;
/// 반지름 길이
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 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 points) {
var pointsData = new PointsData();
pointsData.Count = points.Count;
pointsData.Points = Marshal.AllocHGlobal(Marshal.SizeOf() * 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() * i), false);
}
}
catch (Exception e) {
}
return pointsData;
}
private static PointsData ConvertPointsData(List points) {
var pointsData = new PointsData();
pointsData.Count = points.Count;
pointsData.Points = Marshal.AllocHGlobal(Marshal.SizeOf() * 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() * 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 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 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);
}
}
}