190 lines
5.9 KiB
C#
190 lines
5.9 KiB
C#
using System.Collections.ObjectModel;
|
|
using System.IO;
|
|
using System.Text.RegularExpressions;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using DicomViewer.Models;
|
|
using FellowOakDicom.Imaging;
|
|
using OxyPlot;
|
|
using OxyPlot.Series;
|
|
|
|
namespace DicomViewer.ViewModels;
|
|
|
|
public readonly record struct PixelInfo
|
|
{
|
|
public string Name { get; init; }
|
|
public string Value { get; init; }
|
|
}
|
|
|
|
|
|
internal class MainWindowViewModel : ObservableObject
|
|
{
|
|
public DicomDataTuple? CurrentImage { get => _currentImage; private set => SetProperty(ref _currentImage, value); }
|
|
public int CurrentIndex
|
|
{
|
|
get => _currentIndex;
|
|
private set
|
|
{
|
|
SetProperty(ref _currentIndex, value);
|
|
UpdateCurrentImage();
|
|
}
|
|
}
|
|
public int MaxIndex { get => _maxIndex; private set => SetProperty(ref _maxIndex, value); }
|
|
public string CurrentImageName
|
|
{
|
|
get => _currentImageName;
|
|
set
|
|
{
|
|
SetProperty(ref _currentImageName, value);
|
|
UpdateCurrentImage();
|
|
}
|
|
}
|
|
public PlotModel CbfPlotModelModel { get => _cbfPlotModelModel; set => SetProperty(ref _cbfPlotModelModel, value); }
|
|
public ObservableCollection<string> ImageList { get; } = [];
|
|
public ObservableCollection<PixelInfo> PixelInfoList { get; } = [];
|
|
public string CursorPosition { get => _cursorPosition; set => SetProperty(ref _cursorPosition, value); }
|
|
|
|
private readonly Dictionary<string, List<DicomDataTuple>> _imageDictionary = new();
|
|
private int _currentIndex;
|
|
private int _maxIndex;
|
|
private int _pldCount;
|
|
private string _currentImageName = string.Empty;
|
|
private string _cursorPosition = string.Empty;
|
|
private PlotModel _cbfPlotModelModel = new();
|
|
private DicomDataTuple? _currentImage;
|
|
|
|
|
|
public void LoadData(string path)
|
|
{
|
|
CurrentImageName = "corr-cbf";
|
|
_imageDictionary.Clear();
|
|
ImageList.Clear();
|
|
_pldCount = 0;
|
|
|
|
try
|
|
{
|
|
//read from each sub folder
|
|
foreach (string directory in Directory.GetDirectories(Path.Combine(path, "asl")))
|
|
{
|
|
string key = Path.GetFileName(directory);
|
|
ImageList.Add(key);
|
|
List<DicomDataTuple> imageList = LoadFromDir(directory);
|
|
_imageDictionary.Add(key, imageList);
|
|
|
|
if (Regex.IsMatch(key, @"cbf\d+"))
|
|
_pldCount++;
|
|
}
|
|
|
|
//read java temp
|
|
string javaTempDir = Path.Combine(path, "java_temp", "reconstructed");
|
|
if (Directory.Exists(javaTempDir))
|
|
{
|
|
foreach (string file in Directory.GetFiles(javaTempDir, "*.dcm"))
|
|
{
|
|
string key = "j_" + Path.GetFileNameWithoutExtension(file);
|
|
ImageList.Add(key);
|
|
List<DicomDataTuple> imageList = LoadFromFile(file);
|
|
_imageDictionary.Add(key, imageList);
|
|
}
|
|
}
|
|
|
|
MaxIndex = _imageDictionary.First().Value.Count;
|
|
CurrentIndex = MaxIndex / 2;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
private static List<DicomDataTuple> LoadFromDir(string path)
|
|
{
|
|
string[] files = Directory.GetFiles(path);
|
|
Array.Sort(files);
|
|
List<DicomDataTuple> dataList = files.Select(file => new DicomDataTuple(file)).ToList();
|
|
return dataList;
|
|
}
|
|
|
|
private static List<DicomDataTuple> LoadFromFile(string path)
|
|
{
|
|
DicomImage image = new(path);
|
|
List<DicomDataTuple> dataList = Enumerable.Range(0, image.NumberOfFrames).Select(index => new DicomDataTuple(path, index)).ToList();
|
|
return dataList;
|
|
}
|
|
|
|
public void UpdateCbfPlot(int x, int y)
|
|
{
|
|
try
|
|
{
|
|
//draw plot
|
|
PlotModel model = new() { Title = "CBF Plot" };
|
|
LineSeries cbfLine = new() { Title = "CBF", LineJoin = LineJoin.Bevel, MarkerType = MarkerType.Circle };
|
|
for (int i = 1; i <= _pldCount; i++)
|
|
{
|
|
cbfLine.Points.Add(new DataPoint(i + 1, _imageDictionary[$"cbf{i}"][CurrentIndex - 1].GetPixel(x, y)));
|
|
}
|
|
model.Series.Add(cbfLine);
|
|
|
|
//Siemens 5
|
|
if (_imageDictionary.ContainsKey("j_PLD1"))
|
|
{
|
|
LineSeries pldLine = new() { Title = "PLD", LineJoin = LineJoin.Bevel, MarkerType = MarkerType.Square };
|
|
for (int i = 1; i <= _pldCount; i++)
|
|
{
|
|
pldLine.Points.Add(new DataPoint(i + 1, _imageDictionary[$"j_PLD{i}"][CurrentIndex - 1].GetPixel(x, y)));
|
|
}
|
|
model.Series.Add(pldLine);
|
|
}
|
|
|
|
CbfPlotModelModel = model;
|
|
|
|
//add all info
|
|
PixelInfoList.Clear();
|
|
foreach (KeyValuePair<string, List<DicomDataTuple>> pair in _imageDictionary)
|
|
{
|
|
string value = string.Empty;
|
|
try
|
|
{
|
|
value = pair.Value[CurrentIndex - 1].GetPixel(x, y).ToString("0.##");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e);
|
|
}
|
|
PixelInfoList.Add(new PixelInfo { Name = pair.Key, Value = value });
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e);
|
|
}
|
|
}
|
|
|
|
private void UpdateCurrentImage()
|
|
{
|
|
try
|
|
{
|
|
CurrentImage = _imageDictionary[CurrentImageName][CurrentIndex - 1];
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e);
|
|
}
|
|
}
|
|
|
|
public void NextImage()
|
|
{
|
|
if (CurrentIndex >= MaxIndex)
|
|
return;
|
|
|
|
CurrentIndex++;
|
|
}
|
|
|
|
public void PrevImage()
|
|
{
|
|
if (CurrentIndex <= 1)
|
|
return;
|
|
|
|
CurrentIndex--;
|
|
}
|
|
} |