页面逻辑添加

This commit is contained in:
2026-04-24 14:55:20 +08:00
parent dade596792
commit e59fed9b91
3 changed files with 383 additions and 58 deletions

View File

@@ -164,37 +164,80 @@ public static class ModbusHelper
//double total = left + right - binocular;
//下方视野面积
public static double CalcLowerEyeArea(
List<double[]> eyeGroups,
double threshold,
double standardLowerArea)
//下方视野角度
/// <summary>
/// GB2890-2022 计算 单眼下方视野角度
/// eyeData单眼72路平均数据数组
/// threshold:有效亮度阈值
/// </summary>
public static double CalcLowerAngle(double[] eyeData, double threshold = 10)
{
// 1. 每个通道求20组平均
// 总72点 每点5°
int totalPoint = 72;
double perAngle = 5;
// 国标最下方起始点位第54号开始为正下方
int startDownIndex = 54;
int validCount = 0;
// 从最下方向上 连续检测有效点
for (int i = 0; i < 36; i++)
{
int idx = (startDownIndex + i) % totalPoint;
if (eyeData[idx] >= threshold)
{
validCount++;
}
else
{
// 断开直接停止
break;
}
}
// 下方视野角度 = 有效点数 × 单步角度
return validCount * perAngle;
}
/// <summary>
/// 计算单眼72点通道平均值数组
/// </summary>
/// <param name="eyeGroups">多组采样数据集合</param>
/// <returns>72点通道平均值数组</returns>
private static double[] GetEyeAvgArray(List<double[]> eyeGroups)
{
if (eyeGroups == null || eyeGroups.Count == 0)
return new double[72]; // 无数据时返回全0数组
double[] avg = new double[72];
for (int i = 0; i < 72; i++)
{
double sum = 0;
foreach (var g in eyeGroups) sum += g[i];
foreach (var group in eyeGroups)
{
sum += group[i];
}
avg[i] = sum / eyeGroups.Count;
}
// 2. 只统计下半 36 个通道(下方视野)
int validCount = 0;
for (int i = 36; i < 72; i++) // 36~71 是下半区
{
if (avg[i] >= threshold)
validCount++;
}
// 3. 计算下方视野面积
return (validCount / 36.0) * standardLowerArea;
return avg;
}
//下方视野计算方法
////1. 先拿到左右眼 72点平均数组
//double[] leftAvg = GetLeftEyeAvgArray();
//double[] rightAvg = GetRightEyeAvgArray();
// 总下方视野面积调用
//double totalLower = leftLower + rightLower - binocularLower;
////2. 分别算下方角度
//double leftLowerAngle = CalcLowerAngle(leftAvg, 10);
//double rightLowerAngle = CalcLowerAngle(rightAvg, 10);
////3. 最终报告取值(国标取双眼较小值)
//double finalLowerAngle = Math.Min(leftLowerAngle, rightLowerAngle);
//bool lowerAngleOk = finalLowerAngle >= 35;
//空白视野面积计算
@@ -236,5 +279,128 @@ public static class ModbusHelper
//double totalSaveRate = VisionCalculator.CalculateVisionSaveRate(totalVisionArea, standardTotalArea);
}
// 空头模无面罩标定的标准面积GB2890-2022
//public static double StandardSingleEye = 5200;
//// 双眼总标准面积(左+右)
//public static double StandardTotalEye = 10400;
//// 双目重叠标准面积
////public static double StandardBinocular = 4200;
//// 下方视野标准角度
//public static double StandardLowerAngle = 75;
//===== 1. 你预先标定的 空模标准面积 =====
// 单眼标准、总标准(左+右)、双目重叠标准
public static double StandardLeftEye = 5180;
public static double StandardRightEye = 5180;
public static double StandardTotal = 10360;
public static double StandardBinocular = 4150;
//===== 2. 传入你采集的实测面积 =====
// leftArea左眼实测 rightArea右眼实测 binArea双目重叠实测
public static double CalcVisionRate(double leftArea, double rightArea)
{
// 总视野实测 = 左+右
double totalSi = leftArea + rightArea;
// 1. 总视野保存率
double ratioTotal = totalSi / StandardTotal;
double gammaTotal = GetVisionGamma(ratioTotal);
double totalRate = gammaTotal * ratioTotal * 100;
return (totalRate);
}
/// <summary>
/// GB2890-2022 自动获取 总视野/双目视野 校正系数γ
/// </summary>
/// <param name="ratio">实测面积/标准面积 比值(0~1)</param>
/// <returns>校正系数 γ</returns>
public static double GetVisionGamma(double ratio)
{
// X视野残存率 Si/S0
double[] xData = { 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 };
// 总视野 γ 对应值
double[] gammaTotal = { 1.22, 1.18, 1.14, 1.10, 1.06, 1.03, 1.02, 1.01, 1.00 };
double[] yData = gammaTotal;
// 边界限制
if (ratio <= xData[0]) return yData[0];
if (ratio >= xData.Last()) return 1.0;
// 线性插值
for (int i = 0; i < xData.Length - 1; i++)
{
if (ratio >= xData[i] && ratio <= xData[i + 1])
{
double t = (ratio - xData[i]) / (xData[i + 1] - xData[i]);
return yData[i] + t * (yData[i + 1] - yData[i]);
}
}
return 1.0;
}
internal static double CalculateEyeArea(List<dynamic> leftEyeDataList, int v1, int v2)
{
throw new NotImplementedException();
}
internal static double CalcBinocularArea(List<dynamic> leftEyeDataList, List<dynamic> rightEyeDataList, int v1, int v2)
{
throw new NotImplementedException();
}
internal static double[] GetEyeAvgArray(List<dynamic> leftEyeDataList)
{
throw new NotImplementedException();
}
// 你算出来的实际面积
//double left = 4250;
//double right = 4320;
//double bin = 2860;
//// 一键算出 国标保存率
//var result = CalcVisionRate(left, right, bin);
//double 总视野保存率 = result.totalRate;
//double 双目视野保存率 = result.binRate;
}
//// 1. 总视野保存率
//double gammaTotal = 查国标图D.4的总视野γ;
//double totalRate = gammaTotal * totalArea / GlobalData.StandardTotalEye * 100;
// // 2. 双目视野保存率
// double gammaBinoc = 查国标图D.4的双目视野γ;
//double binocRate = gammaBinoc * binocArea / GlobalData.StandardBinocular * 100;
//// 3. 下方视野(直接比角度,不用面积)
//bool lowerPass = lowerAngle >= 35;
// 四、关键澄清(你之前问的)
//下方视野:国标是角度(°),不是面积
//按左右眼视野曲线下方交点位置直接读出角度
//合格≥35°
//总视野 = 左眼 + 右眼(国标明确)
//双目视野 = 左右眼重叠部分(单独算面积)
//五、最简总结(国标一句话)
//总视野保存率 =γ ×(左 + 右实测面积))/ 标准总面积 ×100%
//双目视野保存率 =γ × 重叠实测面积)/ 标准重叠面积 ×100%
//下方视野:直接看角度 ≥35°
//}