Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Extraction updates #1362

Merged
merged 6 commits into from
Oct 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "ZScoreNormalizer.h"
#include "FeatureExtraction.h"

std::string inputImageFile, outputDir;
std::string inputImageFile, outputDir, parameterFile;

bool debugMode;

Expand Down Expand Up @@ -155,10 +155,13 @@ int algorithmsRunner()
//auto featureExtractionPath = findRelativeApplicationPath("FeatureExtraction");

auto currentDataDir = getCaPTkDataDir();
auto latticeFeatureParamFilePath = currentDataDir + "/features/2_params_default_lattice.csv";
if (!cbica::isFile(latticeFeatureParamFilePath))
if (parameterFile.empty())
{
std::cerr << "The default lattice parameter file, '2_params_default_lattice.csv' was not found in the data directory, '" << currentDataDir << "'; please check.\n";
parameterFile = currentDataDir + "/features/2_params_default_lattice.csv";
}
if (!cbica::isFile(parameterFile))
{
std::cerr << "The specified lattice parameter file, '" << parameterFile << "' was not found; please check.\n";
exit(EXIT_FAILURE);
}

Expand All @@ -173,7 +176,7 @@ int algorithmsRunner()
features.SetMaskImage(outputRelevantMaskImage_flipped);
features.SetWriteFeatureMaps(true);
features.SetValidMask();
features.SetRequestedFeatures(latticeFeatureParamFilePath);
features.SetRequestedFeatures(parameterFile);
features.SetOutputFilename(cbica::normPath(outputDir + "/features/output.csv"));
features.SetVerticallyConcatenatedOutput(true);
features.Update();
Expand All @@ -198,6 +201,7 @@ int main(int argc, char** argv)
parser.addRequiredParameter("o", "outputDir", cbica::Parameter::DIRECTORY, "NIfTI", "Dir with write access", "All output files are written here");
parser.addOptionalParameter("d", "debugMode", cbica::Parameter::BOOLEAN, "0 or 1", "Enabled debug mode", "Default: 0");
parser.addOptionalParameter("r", "resize", cbica::Parameter::INTEGER, "0 - 100", "What resizing factor is to be applied", "Default: " + std::to_string(resizingFactor));
parser.addOptionalParameter("p", "paramFile", cbica::Parameter::FILE, ".csv", "A csv file with all features and its parameters filled", "Default: '../data/2_params_default.csv'");

parser.getParameterValue("i", inputImageFile);
parser.getParameterValue("o", outputDir);
Expand All @@ -217,6 +221,10 @@ int main(int argc, char** argv)
{
parser.getParameterValue("r", resizingFactor);
}
if (parser.isPresent("p"))
{
parser.getParameterValue("p", parameterFile);
}
//auto inputImageInfo = cbica::ImageInfo(inputImageFile);

//switch (inputImageInfo.GetImageDimensions())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
FeatureName,ParamName,Type,Range,Default,Comments
Generic,Quantization_Extent,String,Image:ROI,ROI,Whether the quantization of Intensities is supposed to happen on a per-image basis or on a per-ROI basis
Generic,Quantization_Type,String,FixedBinNumber:FixedBinSize:Equal,FixedBinNumber,FixedBinNumber (FBN): the bins are uniformly distributed across the minimum and maximum extent in the ROI/Image as defined under 'Quantization_Extent'; FixedBinSize (FBS): bins are added in a fixed step between the minimum and maximum extent in the ROI/Image as defined under 'Quantization_Extent' the requested size is provided in 'Bins'; Equal: each bin holds an equal number of intensities
Generic,Resampling,mm,0:10,1.0,Resamples all images and masks to this value of voxel/pixel resolution before computations (0: no resampling): reduce this number of more accuracy
Generic,ResamplingInterpolator_Image,mm,Nearest:Linear:BSpline,Linear,Type of interpolator to use if resampling is happening; ignored if m_resamplingResolution = 0
Generic,ResamplingInterpolator_Mask,mm,Nearest:NearestLabel:Linear:BSpline,Nearest,Type of interpolator to use if resampling is happening; ignored if m_resamplingResolution = 0
Generic,SliceComputation,Int,(0:1),0,Controls whether non-Intensity features are calculated along the slice with the largest area along the 3 axes: valid for 3D images only
Generic,NaN-Handling,String,Keep:Remove,Keep,Specify how to handle features with NaN values 'Remove' removes the feature from output - keep in mind this might cause issues with output file in multi-subject (i.e. Training/Batch) mode
Intensity,,,,,
Volumetric,Dimension,string,[2D:3D],2D,For calculating 2D slice or full 3D volume features this doesn't do anything for 2D images
Histogram,Bins,Int,,129,The number of bins to calculate the Histogram on
Expand Down
22 changes: 18 additions & 4 deletions src/applications/FeatureExtraction/src/FeatureExtraction.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,7 @@ void FeatureExtraction< TImage >::SetFeatureParam(std::string featureFamily)
else
{
std::cerr << "Unsupported binning type selected; defaulting to FixedBinNumber.\n";
m_histogramBinningType = HistogramBinningType::FixedBinNumber;
}
}
else if (outer_key == ParamsString[Resampling])
Expand Down Expand Up @@ -2616,11 +2617,24 @@ void FeatureExtraction< TImage >::Update()
m_Radius = m_Radius_range[r];
auto m_Radius_string = std::to_string(m_Radius);

CalculateGaborWavelets(currentInputImage_patch, std::get<4>(temp->second), allROIs[j].latticeGridPoint);
bool sizeIsFine = true;
auto size = currentInputImage_patch->GetLargestPossibleRegion().GetSize();
for (size_t d = 0; d < TImageType::ImageDimension; d++)
{
if (size[d] < (m_Radius + 2)) // this is the size needs to be checked
{
sizeIsFine = false;
}
}

WriteFeatures(m_modality[i], allROIs[j].label, std::string(FeatureFamilyString[f]) + "_Radius-" + m_Radius_string, std::get<4>(temp->second),
"Radius=" + std::to_string(m_Radius) + ";FMax=" + std::to_string(m_gaborFMax) + ";Gamma=" + std::to_string(m_gaborGamma) +
";Directions=" + m_Radius_string + ";Level=" + std::to_string(m_gaborLevel), m_currentLatticeCenter, writeFeatureMapsAndLattice, allROIs[j].weight);
if (sizeIsFine)
{
CalculateGaborWavelets(currentInputImage_patch, std::get<4>(temp->second), allROIs[j].latticeGridPoint);

WriteFeatures(m_modality[i], allROIs[j].label, std::string(FeatureFamilyString[f]) + "_Radius-" + m_Radius_string, std::get<4>(temp->second),
"Radius=" + std::to_string(m_Radius) + ";FMax=" + std::to_string(m_gaborFMax) + ";Gamma=" + std::to_string(m_gaborGamma) +
";Directions=" + m_Radius_string + ";Level=" + std::to_string(m_gaborLevel), m_currentLatticeCenter, writeFeatureMapsAndLattice, allROIs[j].weight);
}
} // end radius-loop

if (m_debug)
Expand Down
3 changes: 3 additions & 0 deletions src/applications/PerfusionAlignment.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ std::pair< std::vector<typename ImageType::Pointer>, typename ImageType::Pointer
//get original curve
std::cout << "Calculating mean and std-dev from perfusion image.\n";
maskImage = CalculatePerfusionVolumeStd<ImageType, PerfusionImageType>(perfImagePointerNifti, t1ceImagePointer, 0, 9, stdDev); //values do not matter here
// put an error check here
// if numberOfNonZeroVoxelsInMask > 0.5 * totalNumberOfVoxels
// print_error << "Warning: the mask is larger than expected volume of brain, please perform quality-check after process completion.\n"
OriginalCurve = CalculatePerfusionVolumeMean<ImageType, PerfusionImageType>(perfImagePointerNifti, maskImage, 0, 9); //values do not matter here

std::cout << "Started resampling.\n";
Expand Down