void SampleGradHistogram(double *pt, double radius, typename TImage::Pointer image, arma::ivec& samples) { typedef TImage ImageType; int radius_pix[3]; //radius in voxels, to be calculated radius_pix[0] = std::ceil(radius / image->GetSpacing()[0]); radius_pix[1] = std::ceil(radius / image->GetSpacing()[1]); radius_pix[2] = std::ceil(radius / image->GetSpacing()[2]); #ifdef DEBUG_MESSAGES_HOG std::cout << "Requested point: " << pt[0] << ", " << pt[1] << ", " << pt[2] << std::endl; std::cout << "Neighborhood size in mm: " << radius << std::endl; std::cout << "Neighborhood size in pix: " << radius_pix[0] << ", " << radius_pix[1] << ", " << radius_pix[2] << std::endl; #endif if (radius_pix[0] == 0 || radius_pix[1] == 0 || radius_pix[2] == 0) { std::cout << "One of the neighborhood dimensions is zero. Please correct the radius. Aborting." << std::endl; return; } //transform the point from physical s1pace typename ImageType::PointType point; point[0] = pt[0]; point[1] = pt[1]; point[2] = pt[2]; typename ImageType::IndexType pt_pix; image->TransformPhysicalPointToIndex(point, pt_pix); //define the region around the point of interest typename ImageType::IndexType rgn_idx = { {pt_pix[0] - radius_pix[0], pt_pix[1] - radius_pix[1], pt_pix[2] - radius_pix[2]}}; typename ImageType::SizeType rgn_size = { {2 * radius_pix[0] + 1, 2 * radius_pix[1] + 1, 2 * radius_pix[2] + 1}}; //crop the region so that it is inside rgn_idx[0] = std::max(rgn_idx[0], image->GetLargestPossibleRegion().GetIndex(0)); rgn_idx[1] = std::max(rgn_idx[1], image->GetLargestPossibleRegion().GetIndex(1)); rgn_idx[2] = std::max(rgn_idx[2], image->GetLargestPossibleRegion().GetIndex(2)); //set it first as a corner for comparison and then undo that operation rgn_size[0] = std::min(rgn_size[0]+rgn_idx[0], image->GetLargestPossibleRegion().GetSize(0))-rgn_idx[0]; rgn_size[1] = std::min(rgn_size[1]+rgn_idx[1], image->GetLargestPossibleRegion().GetSize(1))-rgn_idx[1]; rgn_size[2] = std::min(rgn_size[2]+rgn_idx[2], image->GetLargestPossibleRegion().GetSize(2))-rgn_idx[2]; typename ImageType::RegionType window(rgn_idx, rgn_size); #ifdef DEBUG_MESSAGES_HOG std::cout << "Region: " << window << std::endl; #endif samples.set_size(rgn_size[0]*rgn_size[1]*rgn_size[2]); samples.zeros(); // itk::ImageRegionConstIterator<typename GradientFilterType::OutputImageType> imageIterator(gradient_filter->GetOutput(), window); itk::ImageRegionConstIterator<ImageType> imageIterator(image, window); imageIterator.GoToBegin(); int i=0; while (!imageIterator.IsAtEnd()) { // Get the value of the current pixel typename ImageType::PixelType val = imageIterator.Get(); //std::cout << val << std::endl; samples[i++] = val; ++imageIterator; } }
void SampleStatistics(double *pt, double radius, typename TImage::Pointer image, arma::vec& features) { features.set_size(4); //just four features for now features.zeros(); typedef TImage ImageType; int radius_pix[3]; //radius in voxels, to be calculated radius_pix[0] = std::ceil(radius / image->GetSpacing()[0]); radius_pix[1] = std::ceil(radius / image->GetSpacing()[1]); radius_pix[2] = std::ceil(radius / image->GetSpacing()[2]); #ifdef DEBUG_MESSAGES_HOG std::cout << "Requested point: " << pt[0] << ", " << pt[1] << ", " << pt[2] << std::endl; std::cout << "Neighborhood size in mm: " << radius << std::endl; std::cout << "Neighborhood size in pix: " << radius_pix[0] << ", " << radius_pix[1] << ", " << radius_pix[2] << std::endl; #endif if (radius_pix[0] == 0 || radius_pix[1] == 0 || radius_pix[2] == 0) { std::cout << "One of the neighborhood dimensions is zero. Please correct the radius. Aborting." << std::endl; return; } //transform the point from physical s1pace typename ImageType::PointType point; point[0] = pt[0]; point[1] = pt[1]; point[2] = pt[2]; typename ImageType::IndexType pt_pix; image->TransformPhysicalPointToIndex(point, pt_pix); //define the region around the point of interest typename ImageType::IndexType rgn_idx = { {pt_pix[0] - radius_pix[0], pt_pix[1] - radius_pix[1], pt_pix[2] - radius_pix[2]}}; typename ImageType::SizeType rgn_size = { {2 * radius_pix[0] + 1, 2 * radius_pix[1] + 1, 2 * radius_pix[2] + 1}}; //crop the region so that it is inside rgn_idx[0] = std::max(rgn_idx[0], image->GetLargestPossibleRegion().GetIndex(0)); rgn_idx[1] = std::max(rgn_idx[1], image->GetLargestPossibleRegion().GetIndex(1)); rgn_idx[2] = std::max(rgn_idx[2], image->GetLargestPossibleRegion().GetIndex(2)); //set it first as a corner for comparison and then undo that operation rgn_size[0] = std::min(rgn_size[0]+rgn_idx[0], image->GetLargestPossibleRegion().GetSize(0))-rgn_idx[0]; rgn_size[1] = std::min(rgn_size[1]+rgn_idx[1], image->GetLargestPossibleRegion().GetSize(1))-rgn_idx[1]; rgn_size[2] = std::min(rgn_size[2]+rgn_idx[2], image->GetLargestPossibleRegion().GetSize(2))-rgn_idx[2]; typename ImageType::RegionType window(rgn_idx, rgn_size); #ifdef DEBUG_MESSAGES_HOG std::cout << "Region: " << window << std::endl; #endif itk::ImageRegionConstIterator<ImageType> imageIterator(image, window); imageIterator.GoToBegin(); const int nvoxels = rgn_size[0]*rgn_size[1]*rgn_size[2]; arma::vec voxels; voxels.set_size(nvoxels); voxels.zeros(); long int i=0; while (!imageIterator.IsAtEnd()) { // Get the value of the current pixel typename ImageType::PixelType val = imageIterator.Get(); //std::cout << val << std::endl; voxels[i++] = val; ++imageIterator; } //do the statistics const double mean = arma::mean(voxels); const double std = arma::stddev(voxels); double E3 = 0; //Accumulate expectation of (X-u)^3 double E4 = 0; //Accumulate expectation of (X-u)^4 for(int i=0; i<voxels.size(); i++) { const double diff = voxels[i] - mean; const double k = diff*diff*diff/nvoxels; E3 += k; //cubed E4 += diff*k; //4th power } features[0] = mean; features[1] = std; features[2] = E3/(std*std*std); //skewness features[3] = E3/(std*std*std*std); //kurtosis }