forked from amkovkov/GranuSightSoftware2
feat: add ResultsExporter
move results postprocessing to separate class fix few typos
This commit is contained in:
@@ -494,86 +494,34 @@ public partial class AnalysisViewModel : ViewModelBase
|
||||
InnerStdDevs.Clear();
|
||||
InnerHeterogeneities.Clear();
|
||||
|
||||
ParticlesCount = Values.Count();
|
||||
|
||||
if (Values.Count() == 0)
|
||||
{
|
||||
MeanProcessedArea = -1;
|
||||
ProcessedAreaP10 = -1;
|
||||
ProcessedAreaP50 = -1;
|
||||
ProcessedAreaP90 = -1;
|
||||
ProcessedAreaStdDev = -1;
|
||||
InterHeterogeneity = -1;
|
||||
ProcessedAreaDeltaP90P10 = -1;
|
||||
UnprocessedFraction = -1;
|
||||
MeanInnerHeterogeneity = -1;
|
||||
MeanInnerStdDev = -1;
|
||||
MeanHotspotArea = -1;
|
||||
MeanOpticalIntegral = -1;
|
||||
|
||||
ProcessedAreasHistogram.Clear();
|
||||
UnprocessedAreasHistogram.Clear();
|
||||
HotspotAreasHistogram.Clear();
|
||||
OpticalIntegralsHistogram.Clear();
|
||||
InnerStdDevsHistogram.Clear();
|
||||
InnerHeterogeneitiesHistogram.Clear();
|
||||
|
||||
ParticleIndex = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Для каждой гранулы
|
||||
var max = Values.Max(vs => vs.Max());
|
||||
foreach (var value in Values)
|
||||
{
|
||||
// Находим нормализованное значение
|
||||
var normalized = new double[value.Count()];
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
if (value[i] <= MixtureNormalRate * UNPROCESSED_THRESHOLD)
|
||||
normalized[i] = value[i] / (MixtureNormalRate * UNPROCESSED_THRESHOLD);
|
||||
else if (value[i] <= MixtureNormalRate * HOTSPOT_THRESHOLD)
|
||||
normalized[i] = 1 + (value[i] - (MixtureNormalRate * UNPROCESSED_THRESHOLD)) / ((MixtureNormalRate * HOTSPOT_THRESHOLD) - (MixtureNormalRate * UNPROCESSED_THRESHOLD));
|
||||
else
|
||||
normalized[i] = 2 + (value[i] - (MixtureNormalRate * HOTSPOT_THRESHOLD)) / (max - (MixtureNormalRate * HOTSPOT_THRESHOLD));
|
||||
|
||||
// Вычисляем значения
|
||||
var area = normalized.Count();
|
||||
var processedArea = normalized.Count(v => v > 1) * 100.0 / area;
|
||||
var unprocessedArea = normalized.Count(v => v <= 1) * 100.0 / area;
|
||||
var hotspotArea = normalized.Count(v => v > 2) * 100.0 / area;
|
||||
var opticalIntegral = normalized.Sum() * 100.0 / area;
|
||||
var innerStdDev = normalized.StdDev();
|
||||
var innerHeterogeneity = innerStdDev / (opticalIntegral + EPSILON);
|
||||
|
||||
// Добавляем значения в списки
|
||||
NormalizedValues.Add(normalized);
|
||||
ProcessedAreas.Add(processedArea);
|
||||
UnprocessedAreas.Add(unprocessedArea);
|
||||
HotspotAreas.Add(hotspotArea);
|
||||
OpticalIntegrals.Add(opticalIntegral);
|
||||
InnerStdDevs.Add(innerStdDev);
|
||||
InnerHeterogeneities.Add(innerHeterogeneity);
|
||||
}
|
||||
|
||||
// Вычисляем общие значения
|
||||
MeanProcessedArea = ProcessedAreas.Mean();
|
||||
ProcessedAreaP10 = ProcessedAreas.Percentile(10);
|
||||
ProcessedAreaP50 = ProcessedAreas.Percentile(50);
|
||||
ProcessedAreaP90 = ProcessedAreas.Percentile(90);
|
||||
ProcessedAreaStdDev = ProcessedAreas.StdDev();
|
||||
InterHeterogeneity = ProcessedAreaStdDev / MeanProcessedArea * 100;
|
||||
ProcessedAreaDeltaP90P10 = ProcessedAreaP90 - ProcessedAreaP10;
|
||||
UnprocessedFraction = (double)UnprocessedAreas.Count(v => v > UNPROCESSED_FRACTION_THRESHOLD) / UnprocessedAreas.Count() * 100;
|
||||
MeanInnerHeterogeneity = InnerHeterogeneities.Mean();
|
||||
MeanInnerStdDev = InnerStdDevs.Mean();
|
||||
MeanHotspotArea = HotspotAreas.Mean();
|
||||
MeanOpticalIntegral = OpticalIntegrals.Mean();
|
||||
(
|
||||
ParticlesCount,
|
||||
_,
|
||||
NormalizedValues,
|
||||
ProcessedAreas,
|
||||
UnprocessedAreas,
|
||||
HotspotAreas,
|
||||
OpticalIntegrals,
|
||||
InnerStdDevs,
|
||||
InnerHeterogeneities,
|
||||
MeanProcessedArea,
|
||||
ProcessedAreaP10,
|
||||
ProcessedAreaP50,
|
||||
ProcessedAreaP90,
|
||||
ProcessedAreaStdDev,
|
||||
InterHeterogeneity,
|
||||
ProcessedAreaDeltaP90P10,
|
||||
UnprocessedFraction,
|
||||
MeanInnerHeterogeneity,
|
||||
MeanInnerStdDev,
|
||||
MeanHotspotArea,
|
||||
MeanOpticalIntegral
|
||||
) = ResultsPostProcessor.PostProcess(Values, MixtureNormalRate);
|
||||
|
||||
// Обновляем гистограммы
|
||||
ProcessedAreasHistogram.Set(ProcessedAreas, 0, 100, "Количество гранул, шт", "Нормированная обработанная площадь, %");
|
||||
UnprocessedAreasHistogram.Set(UnprocessedAreas, 0, 100, "Количество гранул, шт", "Нормированная необработанная площадь, %");
|
||||
HotspotAreasHistogram.Set(HotspotAreas, 0, 100, "Количество гранул, шт", "Нормированная \"горячая\" площадь, %");
|
||||
HotspotAreasHistogram.Set(HotspotAreas, 0, 100, "Количество гранул, шт", "Нормированная горячая площадь, %");
|
||||
OpticalIntegralsHistogram.Set(OpticalIntegrals, 0, 3, "Количество гранул, шт", "Оптический интегральный показатель, %");
|
||||
InnerStdDevsHistogram.Set(InnerStdDevs, InnerStdDevs.Min(), InnerStdDevs.Max(), "Количество гранул, шт", "Внутригранульное среднеквадратичное отклонение");
|
||||
InnerHeterogeneitiesHistogram.Set(InnerHeterogeneities, InnerHeterogeneities.Min(), InnerHeterogeneities.Max(), "Количество гранул, шт", "Внутригранульная однородность");
|
||||
@@ -1904,17 +1852,17 @@ public partial class AnalysisViewModel : ViewModelBase
|
||||
|
||||
// Выичсляем максимальное значение
|
||||
OpenCvSharp.Cv2.MinMaxLoc(resultImage, out _, out double max);
|
||||
// Если иаксмиальное значниеz слишком мало, то устанавливаем его чуть больше hotspotsThreshold, чтобы не возникло деления на ноль и отридцательных значений
|
||||
// Если максимальное значние слишком мало, то устанавливаем его чуть больше hotspotsThreshold, чтобы не возникло деления на ноль и отрицательных значений
|
||||
if (max <= hotspotsThreshold)
|
||||
max = hotspotsThreshold + 0.001;
|
||||
|
||||
// Создаём цветное изображение результата
|
||||
var coloredResultImage = new OpenCvSharp.Mat(resultImage.Size(), OpenCvSharp.MatType.CV_8UC3, OpenCvSharp.Scalar.All(0));
|
||||
// Расшрашиваем диапазон 0...unprocessedThreshold -> чёрный...белый
|
||||
// Раскрашиваем диапазон 0...unprocessedThreshold -> чёрный...белый
|
||||
ApplyGradientToRange(resultImage, 0, unprocessedThreshold, OpenCvSharp.Scalar.Black, OpenCvSharp.Scalar.White, coloredResultImage);
|
||||
// Расшрашиваем диапазон unprocessedThreshold...hotspotsThreshold -> белый...зелёный
|
||||
// Раскрашиваем диапазон unprocessedThreshold...hotspotsThreshold -> белый...зелёный
|
||||
ApplyGradientToRange(resultImage, unprocessedThreshold, hotspotsThreshold, OpenCvSharp.Scalar.White, OpenCvSharp.Scalar.Green, coloredResultImage);
|
||||
// Расшрашиваем диапазон hotspotsThreshold...max -> зелёный...крастный
|
||||
// Раскрашиваем диапазон hotspotsThreshold...max -> зелёный...красный
|
||||
ApplyGradientToRange(resultImage, hotspotsThreshold, max, OpenCvSharp.Scalar.Green, OpenCvSharp.Scalar.Red, coloredResultImage);
|
||||
|
||||
// Устанавливаем в 0 всё что не попадает в маску
|
||||
|
||||
Reference in New Issue
Block a user