-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathMonaiLabelUtils.cpp
145 lines (125 loc) · 4.9 KB
/
MonaiLabelUtils.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <ShapeWorksMONAI/MonaiLabelUtils.h>
#include <QDir>
#include <QFile>
#include <QString>
#include <QFileInfo>
#include <QSharedPointer>
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkBinaryThresholdImageFilter.h>
#include <itkCastImageFilter.h>
#include <itkImageRegionIterator.h>
#include <Data/Session.h>
using namespace shapeworks;
typedef float PixelType;
typedef itk::Image< PixelType, 3 > ImageType;
namespace monailabel {
bool MonaiLabelUtils::createDir(const QString& dirPath) {
QDir dir;
return dir.mkpath(dirPath);
}
bool MonaiLabelUtils::copySegmentation(const QString& sourcePath,
const QString& destinationPath) {
QFile destFile(destinationPath);
if (destFile.exists()) {
destFile.remove();
}
return QFile::copy(sourcePath, destinationPath);
}
bool MonaiLabelUtils::deleteTempFile(const QString& filePath) {
QFile file(filePath);
if (file.exists())
return file.remove();
else
return false;
}
//---------------------------------------------------------------------------
std::string MonaiLabelUtils::getFeatureName(QSharedPointer<Session> session) {
std::string feature_name = session->get_image_name();
auto image_names = session->get_project()->get_image_names();
if (image_names.size() > 0) {
feature_name = image_names[0];
}
return feature_name;
}
//---------------------------------------------------------------------------
ImageType::Pointer MonaiLabelUtils::loadNRRD(const std::string& filePath) {
using ReaderType = itk::ImageFileReader<ImageType>;
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(filePath);
reader->Update();
return reader->GetOutput();
}
//---------------------------------------------------------------------------
bool MonaiLabelUtils::isOrganPresent(ImageType::Pointer image) {
itk::ImageRegionIterator<ImageType> it(image, image->GetRequestedRegion());
while (!it.IsAtEnd()) {
if (it.Get() > 0) { // If any non-background pixel is found
return true;
}
++it;
}
return false;
}
//---------------------------------------------------------------------------
ImageType::Pointer MonaiLabelUtils::extractOrganSegmentation(ImageType::Pointer inputImage, int label) {
using ThresholdFilterType = itk::BinaryThresholdImageFilter<ImageType, ImageType>;
ThresholdFilterType::Pointer thresholdFilter = ThresholdFilterType::New();
thresholdFilter->SetInput(inputImage);
thresholdFilter->SetLowerThreshold(label);
thresholdFilter->SetUpperThreshold(label);
// thresholdFilter->SetInsideValue(label);
thresholdFilter->SetInsideValue(1); // dont save as label
thresholdFilter->SetOutsideValue(0); // Background set to 0
thresholdFilter->Update();
ImageType::Pointer organImage = thresholdFilter->GetOutput();
// Check if organ is present in segmentation
if (thresholdFilter->GetOutput()->GetBufferedRegion().GetNumberOfPixels() == 0) {
return nullptr; // Return null if the organ is not present
} // save all
// if (!isOrganPresent(organImage)) {
// return nullptr; // Return nullptr if no valid organ pixels exist
// }
// return thresholdFilter->GetOutput();
return organImage;
}
//---------------------------------------------------------------------------
void MonaiLabelUtils::saveNRRD(ImageType::Pointer image, const std::string& outputPath) {
using WriterType = itk::ImageFileWriter<ImageType>;
WriterType::Pointer writer = WriterType::New();
writer->SetFileName(outputPath);
writer->SetInput(image);
writer->UseCompressionOn();
writer->Update();
}
//---------------------------------------------------------------------------
void MonaiLabelUtils::processSegmentation(
const std::string& segmentationPath,
const std::map<int, std::string>& organLabels, const std::string& outputDir,
const std::string& sampleId,
std::vector<std::string>& organSegmentationPaths) {
organSegmentationPaths.resize(0);
ImageType::Pointer inputImage = loadNRRD(segmentationPath);
if (!inputImage) {
SW_ERROR("Failed to load segmentation file: {}", segmentationPath);
return;
}
QDir projDir(QString::fromStdString(outputDir));
// if (!projDir.exists()) {
// projDir.mkpath(".");
// }
// Extract and save each organ segmentation
for (const auto& [label, organName] : organLabels) {
ImageType::Pointer organImage = extractOrganSegmentation(inputImage, label);
if (!organImage) {
SW_LOG("Warning: {} (Label {}) not found in segmentation.", organName, label);
continue;
}
QString destPath = projDir.filePath(
QString::fromStdString(sampleId + "_" + organName + ".nrrd"));
saveNRRD(organImage, destPath.toStdString());
SW_LOG("✅ Saved segmented organ: {}", destPath.toStdString());
organSegmentationPaths.push_back(destPath.toStdString());
}
}
} // namespace monailabel